Various new ideas for name analysis.
This commit is contained in:
		
							parent
							
								
									d32580a1d4
								
							
						
					
					
						commit
						af8f0b5dac
					
				| @ -1,5 +1,5 @@ | |||||||
| use convert_case::{Case, Casing}; |  | ||||||
| use crate::spec::tree_enum_spec::{EnumRuleChildKind, TreeEnumBuildSpec}; | use crate::spec::tree_enum_spec::{EnumRuleChildKind, TreeEnumBuildSpec}; | ||||||
|  | use convert_case::{Case, Casing}; | ||||||
| use proc_macro2::TokenStream; | use proc_macro2::TokenStream; | ||||||
| use quote::{format_ident, quote}; | use quote::{format_ident, quote}; | ||||||
| 
 | 
 | ||||||
| @ -10,20 +10,19 @@ pub fn make_enum_ast_node_impl(enum_spec: &TreeEnumBuildSpec) -> TokenStream { | |||||||
|         .map(|rule| { |         .map(|rule| { | ||||||
|             let rule_ident = format_ident!("{}", rule.rule()); |             let rule_ident = format_ident!("{}", rule.rule()); | ||||||
|             match rule.child() { |             match rule.child() { | ||||||
|                 Some(child) => { |                 Some(child) => match child.kind() { | ||||||
|                     match child.kind() { |                     EnumRuleChildKind::Node(node_child) => { | ||||||
|                         EnumRuleChildKind::Node(node_child) => { |                         let child_ident = | ||||||
|                             let child_ident = format_ident!("{}", node_child.node_kind().to_case(Case::Snake)); |                             format_ident!("{}", node_child.node_kind().to_case(Case::Snake)); | ||||||
|                             quote! { |                         quote! { | ||||||
|                                 #type_ident::#rule_ident(#child_ident) => vec![ |                             #type_ident::#rule_ident(#child_ident) => vec![ | ||||||
|                                     #child_ident |                                 #child_ident | ||||||
|                                 ] |                             ] | ||||||
|                             } |  | ||||||
|                         } |  | ||||||
|                         _ => quote! { |  | ||||||
|                             #type_ident::#rule_ident(_) => vec![] |  | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|  |                     _ => quote! { | ||||||
|  |                         #type_ident::#rule_ident(_) => vec![] | ||||||
|  |                     }, | ||||||
|                 }, |                 }, | ||||||
|                 None => { |                 None => { | ||||||
|                     quote! { |                     quote! { | ||||||
| @ -34,6 +33,34 @@ pub fn make_enum_ast_node_impl(enum_spec: &TreeEnumBuildSpec) -> TokenStream { | |||||||
|         }) |         }) | ||||||
|         .collect::<Vec<_>>(); |         .collect::<Vec<_>>(); | ||||||
| 
 | 
 | ||||||
|  |     let mut_match_arms = enum_spec | ||||||
|  |         .rules() | ||||||
|  |         .map(|rule| { | ||||||
|  |             let rule_ident = format_ident!("{}", rule.rule()); | ||||||
|  |             match rule.child() { | ||||||
|  |                 Some(child) => match child.kind() { | ||||||
|  |                     EnumRuleChildKind::Node(node_child) => { | ||||||
|  |                         let child_ident = | ||||||
|  |                             format_ident!("{}", node_child.node_kind().to_case(Case::Snake)); | ||||||
|  |                         quote! { | ||||||
|  |                             #type_ident::#rule_ident(#child_ident) => { | ||||||
|  |                                 f(#child_ident as &'a mut dyn AstNode<'a>) | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     _ => quote! { | ||||||
|  |                         #type_ident::#rule_ident(_) => {} | ||||||
|  |                     }, | ||||||
|  |                 }, | ||||||
|  |                 None => { | ||||||
|  |                     quote! { | ||||||
|  |                         #type_ident::#rule_ident => {} | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         }) | ||||||
|  |         .collect::<Vec<_>>(); | ||||||
|  | 
 | ||||||
|     quote! { |     quote! { | ||||||
|         impl<'a> AstNode<'a> for #type_ident { |         impl<'a> AstNode<'a> for #type_ident { | ||||||
|             fn children(&'a self) -> Vec<&'a dyn AstNode<'a>> { |             fn children(&'a self) -> Vec<&'a dyn AstNode<'a>> { | ||||||
| @ -42,9 +69,19 @@ pub fn make_enum_ast_node_impl(enum_spec: &TreeEnumBuildSpec) -> TokenStream { | |||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  |             fn for_each_child_mut(&'a mut self, mut f: &mut dyn FnMut(&'a mut dyn AstNode<'a>)) { | ||||||
|  |                 match self { | ||||||
|  |                     #(#mut_match_arms,)* | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             fn as_node_ref(&'a self) -> AstNodeRef<'a> { |             fn as_node_ref(&'a self) -> AstNodeRef<'a> { | ||||||
|                 AstNodeRef::#type_ident(&self) |                 AstNodeRef::#type_ident(&self) | ||||||
|             } |             } | ||||||
|  | 
 | ||||||
|  |             fn as_node_ref_mut(&'a mut self) -> AstNodeRefMut<'a> { | ||||||
|  |                 AstNodeRefMut::#type_ident(self) | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -10,9 +10,15 @@ pub fn make_leaf_enum_ast_node_impl(spec: &LeafEnumBuildSpec) -> TokenStream { | |||||||
|                 vec![] |                 vec![] | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  |             fn for_each_child_mut(&'a mut self, mut f: &mut dyn FnMut(&'a mut dyn AstNode<'a>)) {} | ||||||
|  | 
 | ||||||
|             fn as_node_ref(&'a self) -> AstNodeRef<'a> { |             fn as_node_ref(&'a self) -> AstNodeRef<'a> { | ||||||
|                 AstNodeRef::#type_ident(&self) |                 AstNodeRef::#type_ident(&self) | ||||||
|             } |             } | ||||||
|  | 
 | ||||||
|  |             fn as_node_ref_mut(&'a mut self) -> AstNodeRefMut<'a> { | ||||||
|  |                 AstNodeRefMut::#type_ident(self) | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -10,9 +10,15 @@ pub fn make_leaf_struct_ast_node_impl(spec: &LeafStructBuildSpec) -> TokenStream | |||||||
|                 vec![] |                 vec![] | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  |             fn for_each_child_mut(&'a mut self, mut f: &mut dyn FnMut(&'a mut dyn AstNode<'a>)) {} | ||||||
|  | 
 | ||||||
|             fn as_node_ref(&'a self) -> AstNodeRef<'a> { |             fn as_node_ref(&'a self) -> AstNodeRef<'a> { | ||||||
|                 AstNodeRef::#type_ident(&self) |                 AstNodeRef::#type_ident(&self) | ||||||
|             } |             } | ||||||
|  | 
 | ||||||
|  |             fn as_node_ref_mut(&'a mut self) -> AstNodeRefMut<'a> { | ||||||
|  |                 AstNodeRefMut::#type_ident(self) | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,104 +1,84 @@ | |||||||
| mod enum_ast_node; | mod enum_ast_node; | ||||||
| mod leaf_enum_ast_node; | mod leaf_enum_ast_node; | ||||||
| mod struct_ast_node; |  | ||||||
| mod leaf_struct_ast_node; | mod leaf_struct_ast_node; | ||||||
| mod polymorphic_type_ast_node; |  | ||||||
| mod polymorphic_enum_loop_ast_node; | mod polymorphic_enum_loop_ast_node; | ||||||
|  | mod polymorphic_type_ast_node; | ||||||
|  | mod struct_ast_node; | ||||||
| 
 | 
 | ||||||
| use crate::spec::BuildSpec; |  | ||||||
| use proc_macro2::TokenStream; |  | ||||||
| use quote::{format_ident, quote}; |  | ||||||
| use crate::ast_node::enum_ast_node::make_enum_ast_node_impl; | use crate::ast_node::enum_ast_node::make_enum_ast_node_impl; | ||||||
| use crate::ast_node::leaf_enum_ast_node::make_leaf_enum_ast_node_impl; | use crate::ast_node::leaf_enum_ast_node::make_leaf_enum_ast_node_impl; | ||||||
| use crate::ast_node::leaf_struct_ast_node::make_leaf_struct_ast_node_impl; | use crate::ast_node::leaf_struct_ast_node::make_leaf_struct_ast_node_impl; | ||||||
| use crate::ast_node::polymorphic_enum_loop_ast_node::make_polymorphic_enum_loop_ast_node_impl; | use crate::ast_node::polymorphic_enum_loop_ast_node::make_polymorphic_enum_loop_ast_node_impl; | ||||||
| use crate::ast_node::polymorphic_type_ast_node::make_polymorphic_type_ast_node_impl; | use crate::ast_node::polymorphic_type_ast_node::make_polymorphic_type_ast_node_impl; | ||||||
| use crate::ast_node::struct_ast_node::make_struct_ast_node_impl; | use crate::ast_node::struct_ast_node::make_struct_ast_node_impl; | ||||||
|  | use crate::spec::BuildSpec; | ||||||
|  | use proc_macro2::{Ident, TokenStream}; | ||||||
|  | use quote::{format_ident, quote}; | ||||||
| 
 | 
 | ||||||
| pub fn make_ast_node_impl(build_spec: &BuildSpec) -> Option<TokenStream> { | pub fn make_ast_node_impl(build_spec: &BuildSpec) -> Option<TokenStream> { | ||||||
|     match build_spec { |     match build_spec { | ||||||
|         BuildSpec::Enum(enum_spec) => { |         BuildSpec::Enum(enum_spec) => Some(make_enum_ast_node_impl(enum_spec)), | ||||||
|             Some(make_enum_ast_node_impl(enum_spec)) |         BuildSpec::LeafEnum(leaf_enum) => Some(make_leaf_enum_ast_node_impl(leaf_enum)), | ||||||
|         } |         BuildSpec::Struct(struct_spec) => Some(make_struct_ast_node_impl(struct_spec)), | ||||||
|         BuildSpec::LeafEnum(leaf_enum) => { |         BuildSpec::LeafStruct(leaf_struct) => Some(make_leaf_struct_ast_node_impl(leaf_struct)), | ||||||
|             Some(make_leaf_enum_ast_node_impl(leaf_enum)) |  | ||||||
|         } |  | ||||||
|         BuildSpec::Struct(struct_spec) => { |  | ||||||
|             Some(make_struct_ast_node_impl(struct_spec)) |  | ||||||
|         } |  | ||||||
|         BuildSpec::LeafStruct(leaf_struct) => { |  | ||||||
|             Some(make_leaf_struct_ast_node_impl(leaf_struct)) |  | ||||||
|         } |  | ||||||
|         BuildSpec::Production(_) => None, |         BuildSpec::Production(_) => None, | ||||||
|         BuildSpec::NodeProduction(_) => None, |         BuildSpec::NodeProduction(_) => None, | ||||||
|         BuildSpec::PolymorphicType(polymorphic_type) => { |         BuildSpec::PolymorphicType(polymorphic_type) => { | ||||||
|             Some(make_polymorphic_type_ast_node_impl(polymorphic_type)) |             Some(make_polymorphic_type_ast_node_impl(polymorphic_type)) | ||||||
|         } |         } | ||||||
|  |         BuildSpec::PolymorphicEnumLoop(polymorphic_enum_loop) => Some( | ||||||
|  |             make_polymorphic_enum_loop_ast_node_impl(polymorphic_enum_loop), | ||||||
|  |         ), | ||||||
|  |         BuildSpec::PolymorphicPassThrough(_) => None, | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn make_type_ident(build_spec: &BuildSpec) -> Option<Ident> { | ||||||
|  |     match build_spec { | ||||||
|  |         BuildSpec::Struct(struct_spec) => Some(format_ident!("{}", struct_spec.build())), | ||||||
|  |         BuildSpec::LeafStruct(leaf_struct) => Some(format_ident!("{}", leaf_struct.build())), | ||||||
|  |         BuildSpec::Enum(enum_spec) => Some(format_ident!("{}", enum_spec.build())), | ||||||
|  |         BuildSpec::LeafEnum(leaf_enum) => Some(format_ident!("{}", leaf_enum.build())), | ||||||
|  |         BuildSpec::PolymorphicType(polymorphic_type) => { | ||||||
|  |             Some(format_ident!("{}", polymorphic_type.name())) | ||||||
|  |         } | ||||||
|         BuildSpec::PolymorphicEnumLoop(polymorphic_enum_loop) => { |         BuildSpec::PolymorphicEnumLoop(polymorphic_enum_loop) => { | ||||||
|             Some(make_polymorphic_enum_loop_ast_node_impl(polymorphic_enum_loop)) |             Some(format_ident!("{}", polymorphic_enum_loop.name())) | ||||||
|         } |         } | ||||||
|         BuildSpec::PolymorphicPassThrough(_) => None, |         BuildSpec::PolymorphicPassThrough(_) => None, | ||||||
|  |         BuildSpec::Production(_) => None, | ||||||
|  |         BuildSpec::NodeProduction(_) => None, | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub fn make_ast_enum_member(build_spec: &BuildSpec) -> Option<TokenStream> { | pub fn make_ast_enum_member(build_spec: &BuildSpec) -> Option<TokenStream> { | ||||||
|     match build_spec { |     make_type_ident(build_spec).map(|type_ident| { | ||||||
|         BuildSpec::Struct(struct_spec) => { |         quote! { | ||||||
|             Some(format_ident!("{}", struct_spec.build())) |             #type_ident(&'a #type_ident) | ||||||
|         } |         } | ||||||
|         BuildSpec::LeafStruct(leaf_struct) => { |     }) | ||||||
|             Some(format_ident!("{}", leaf_struct.build())) | } | ||||||
|  | 
 | ||||||
|  | pub fn make_ast_enum_mut_member(build_spec: &BuildSpec) -> Option<TokenStream> { | ||||||
|  |     make_type_ident(build_spec).map(|type_ident| { | ||||||
|  |         quote! { | ||||||
|  |             #type_ident(&'a mut #type_ident) | ||||||
|         } |         } | ||||||
|         BuildSpec::Enum(enum_spec) => { |     }) | ||||||
|             Some(format_ident!("{}", enum_spec.build())) |  | ||||||
|         } |  | ||||||
|         BuildSpec::LeafEnum(leaf_enum) => { |  | ||||||
|             Some(format_ident!("{}", leaf_enum.build())) |  | ||||||
|         } |  | ||||||
|         BuildSpec::PolymorphicType(polymorphic_type) => { |  | ||||||
|             Some(format_ident!("{}", polymorphic_type.name())) |  | ||||||
|         }, |  | ||||||
|         BuildSpec::PolymorphicEnumLoop(polymorphic_enum_loop) => { |  | ||||||
|             Some(format_ident!("{}", polymorphic_enum_loop.name())) |  | ||||||
|         } |  | ||||||
|         BuildSpec::PolymorphicPassThrough(_) => None, |  | ||||||
|         BuildSpec::Production(_) => None, |  | ||||||
|         BuildSpec::NodeProduction(_) => None, |  | ||||||
|     } |  | ||||||
|         .map(|type_ident| { |  | ||||||
|             quote! { |  | ||||||
|                 #type_ident(&'a #type_ident) |  | ||||||
|             } |  | ||||||
|         }) |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub fn make_ast_node_ref_unwrapper(build_spec: &BuildSpec) -> Option<TokenStream> { | pub fn make_ast_node_ref_unwrapper(build_spec: &BuildSpec) -> Option<TokenStream> { | ||||||
|     match build_spec { |     make_type_ident(build_spec).map(|type_ident| { | ||||||
|         BuildSpec::Enum(enum_spec) => { |         quote! { | ||||||
|             Some(format_ident!("{}", enum_spec.build())) |             AstNodeRef::#type_ident(inner) => *inner | ||||||
|         } |         } | ||||||
|         BuildSpec::LeafEnum(leaf_enum) => { |     }) | ||||||
|             Some(format_ident!("{}", leaf_enum.build())) | } | ||||||
|         } | 
 | ||||||
|         BuildSpec::Struct(struct_spec) => { | pub fn make_ast_node_ref_mut_unwrapper(build_spec: &BuildSpec) -> Option<TokenStream> { | ||||||
|             Some(format_ident!("{}", struct_spec.build())) |     make_type_ident(build_spec).map(|type_ident| { | ||||||
|         } |         quote! { | ||||||
|         BuildSpec::LeafStruct(leaf_struct) => { |             AstNodeRefMut::#type_ident(inner) => *inner | ||||||
|             Some(format_ident!("{}", leaf_struct.build())) |         } | ||||||
|         } |     }) | ||||||
|         BuildSpec::Production(_) => None, |  | ||||||
|         BuildSpec::NodeProduction(_) => None, |  | ||||||
|         BuildSpec::PolymorphicType(polymorphic_type) => { |  | ||||||
|             Some(format_ident!("{}", polymorphic_type.name())) |  | ||||||
|         } |  | ||||||
|         BuildSpec::PolymorphicEnumLoop(polymorphic_enum_loop) => { |  | ||||||
|             Some(format_ident!("{}", polymorphic_enum_loop.name())) |  | ||||||
|         } |  | ||||||
|         BuildSpec::PolymorphicPassThrough(_) => None |  | ||||||
|     } |  | ||||||
|         .map(|type_ident| { |  | ||||||
|             quote! { |  | ||||||
|                 AstNodeRef::#type_ident(inner) => *inner |  | ||||||
|             } |  | ||||||
|         }) |  | ||||||
| } | } | ||||||
| @ -41,9 +41,17 @@ pub fn make_polymorphic_enum_loop_ast_node_impl( | |||||||
|                 children |                 children | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  |             fn for_each_child_mut(&'a mut self, mut f: &mut dyn FnMut(&'a mut dyn AstNode<'a>)) { | ||||||
|  |                 todo!() | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             fn as_node_ref(&'a self) -> AstNodeRef<'a> { |             fn as_node_ref(&'a self) -> AstNodeRef<'a> { | ||||||
|                 AstNodeRef::#type_ident(&self) |                 AstNodeRef::#type_ident(&self) | ||||||
|             } |             } | ||||||
|  | 
 | ||||||
|  |             fn as_node_ref_mut(&'a mut self) -> AstNodeRefMut<'a> { | ||||||
|  |                 AstNodeRefMut::#type_ident(self) | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -16,6 +16,19 @@ pub fn make_polymorphic_type_ast_node_impl(spec: &PolymorphicTypeBuildSpec) -> T | |||||||
|         }) |         }) | ||||||
|         .collect::<Vec<_>>(); |         .collect::<Vec<_>>(); | ||||||
| 
 | 
 | ||||||
|  |     let match_arms_mut = spec | ||||||
|  |         .variants() | ||||||
|  |         .map(|variant| { | ||||||
|  |             let variant_ident = format_ident!("{}", variant.name()); | ||||||
|  |             let child_ident = format_ident!("{}", variant.inner_kind().to_case(Case::Snake)); | ||||||
|  |             quote! { | ||||||
|  |                 #type_ident::#variant_ident(#child_ident) => { | ||||||
|  |                     f(#child_ident as &'a mut dyn AstNode) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         }) | ||||||
|  |         .collect::<Vec<_>>(); | ||||||
|  | 
 | ||||||
|     quote! { |     quote! { | ||||||
|         impl<'a> AstNode<'a> for #type_ident { |         impl<'a> AstNode<'a> for #type_ident { | ||||||
|             fn children(&'a self) -> Vec<&'a dyn AstNode<'a>> { |             fn children(&'a self) -> Vec<&'a dyn AstNode<'a>> { | ||||||
| @ -24,9 +37,19 @@ pub fn make_polymorphic_type_ast_node_impl(spec: &PolymorphicTypeBuildSpec) -> T | |||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  |             fn for_each_child_mut(&'a mut self, mut f: &mut dyn FnMut(&'a mut dyn AstNode<'a>)) { | ||||||
|  |                 match self { | ||||||
|  |                     #(#match_arms_mut,)* | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             fn as_node_ref(&'a self) -> AstNodeRef<'a> { |             fn as_node_ref(&'a self) -> AstNodeRef<'a> { | ||||||
|                 AstNodeRef::#type_ident(&self) |                 AstNodeRef::#type_ident(&self) | ||||||
|             } |             } | ||||||
|  | 
 | ||||||
|  |             fn as_node_ref_mut(&'a mut self) -> AstNodeRefMut<'a> { | ||||||
|  |                 AstNodeRefMut::#type_ident(self) | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -2,19 +2,27 @@ use crate::spec::struct_spec::{MemberChildBuild, StructChild, StructSpec, VecChi | |||||||
| use proc_macro2::TokenStream; | use proc_macro2::TokenStream; | ||||||
| use quote::{format_ident, quote}; | use quote::{format_ident, quote}; | ||||||
| 
 | 
 | ||||||
| pub fn make_struct_ast_node_impl(spec: &StructSpec) -> TokenStream { | fn make_child_adders(spec: &StructSpec, is_mut: bool) -> Vec<TokenStream> { | ||||||
|     let type_ident = format_ident!("{}", spec.build()); |     let as_clause = if is_mut { | ||||||
|     let child_adders = spec |         quote! { as &mut dyn AstNode } | ||||||
|         .children() |     } else { | ||||||
|  |         quote! { as &dyn AstNode } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     spec.children() | ||||||
|         .map(|child| match child { |         .map(|child| match child { | ||||||
|             StructChild::SkipChild(_) => None, |             StructChild::SkipChild(_) => None, | ||||||
|             StructChild::VecChild(vec_child) => match vec_child.build() { |             StructChild::VecChild(vec_child) => match vec_child.build() { | ||||||
|                 VecChildBuild::String(_) => None, |                 VecChildBuild::String(_) => None, | ||||||
|                 VecChildBuild::Node(_) => { |                 VecChildBuild::Node(_) => { | ||||||
|                     let child_ident = format_ident!("{}", vec_child.name()); |                     let child_ident = if is_mut { | ||||||
|  |                         format_ident!("{}_mut", vec_child.name()) | ||||||
|  |                     } else { | ||||||
|  |                         format_ident!("{}", vec_child.name()) | ||||||
|  |                     }; | ||||||
|                     let children_stream = quote! { |                     let children_stream = quote! { | ||||||
|                         for child in self.#child_ident() { |                         for child in self.#child_ident() { | ||||||
|                             children.push(child as &dyn AstNode); |                             children.push(child #as_clause); | ||||||
|                         } |                         } | ||||||
|                     }; |                     }; | ||||||
|                     Some(children_stream) |                     Some(children_stream) | ||||||
| @ -22,16 +30,21 @@ pub fn make_struct_ast_node_impl(spec: &StructSpec) -> TokenStream { | |||||||
|             }, |             }, | ||||||
|             StructChild::MemberChild(member_child) => match member_child.build() { |             StructChild::MemberChild(member_child) => match member_child.build() { | ||||||
|                 MemberChildBuild::Node(_) => { |                 MemberChildBuild::Node(_) => { | ||||||
|                     let child_ident = format_ident!("{}", member_child.name()); |                     let child_ident = if is_mut { | ||||||
|  |                         format_ident!("{}_mut", member_child.name()) | ||||||
|  |                     } else { | ||||||
|  |                         format_ident!("{}", member_child.name()) | ||||||
|  |                     }; | ||||||
|  | 
 | ||||||
|                     if member_child.optional() { |                     if member_child.optional() { | ||||||
|                         Some(quote! { |                         Some(quote! { | ||||||
|                             if let Some(#child_ident) = self.#child_ident() { |                             if let Some(#child_ident) = self.#child_ident() { | ||||||
|                                 children.push(#child_ident as &dyn AstNode); |                                 children.push(#child_ident #as_clause); | ||||||
|                             } |                             } | ||||||
|                         }) |                         }) | ||||||
|                     } else { |                     } else { | ||||||
|                         Some(quote! { |                         Some(quote! { | ||||||
|                             children.push(self.#child_ident() as &dyn AstNode) |                             children.push(self.#child_ident() #as_clause) | ||||||
|                         }) |                         }) | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
| @ -41,7 +54,13 @@ pub fn make_struct_ast_node_impl(spec: &StructSpec) -> TokenStream { | |||||||
|         }) |         }) | ||||||
|         .filter(Option::is_some) |         .filter(Option::is_some) | ||||||
|         .map(Option::unwrap) |         .map(Option::unwrap) | ||||||
|         .collect::<Vec<_>>(); |         .collect::<Vec<_>>() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub fn make_struct_ast_node_impl(spec: &StructSpec) -> TokenStream { | ||||||
|  |     let type_ident = format_ident!("{}", spec.build()); | ||||||
|  |     let child_adders = make_child_adders(spec, false); | ||||||
|  |     let child_adders_mut = make_child_adders(spec, true); | ||||||
| 
 | 
 | ||||||
|     quote! { |     quote! { | ||||||
|         impl<'a> AstNode<'a> for #type_ident { |         impl<'a> AstNode<'a> for #type_ident { | ||||||
| @ -51,9 +70,17 @@ pub fn make_struct_ast_node_impl(spec: &StructSpec) -> TokenStream { | |||||||
|                 children |                 children | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  |             fn for_each_child_mut(&'a mut self, mut f: &mut dyn FnMut(&'a mut dyn AstNode<'a>)) { | ||||||
|  |                 todo!() | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             fn as_node_ref(&'a self) -> AstNodeRef<'a> { |             fn as_node_ref(&'a self) -> AstNodeRef<'a> { | ||||||
|                 AstNodeRef::#type_ident(&self) |                 AstNodeRef::#type_ident(&self) | ||||||
|             } |             } | ||||||
|  | 
 | ||||||
|  |             fn as_node_ref_mut(&'a mut self) -> AstNodeRefMut<'a> { | ||||||
|  |                 AstNodeRefMut::#type_ident(self) | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -6,7 +6,10 @@ mod spec; | |||||||
| mod type_gen; | mod type_gen; | ||||||
| mod walk; | mod walk; | ||||||
| 
 | 
 | ||||||
| use crate::ast_node::{make_ast_enum_member, make_ast_node_impl, make_ast_node_ref_unwrapper}; | use crate::ast_node::{ | ||||||
|  |     make_ast_enum_member, make_ast_enum_mut_member, make_ast_node_impl, | ||||||
|  |     make_ast_node_ref_mut_unwrapper, make_ast_node_ref_unwrapper, | ||||||
|  | }; | ||||||
| use crate::build_fn::make_build_fn; | use crate::build_fn::make_build_fn; | ||||||
| use crate::deserialize::deserialize_yaml_spec; | use crate::deserialize::deserialize_yaml_spec; | ||||||
| use crate::pretty_print::make_pretty_print_impl; | use crate::pretty_print::make_pretty_print_impl; | ||||||
| @ -165,6 +168,13 @@ fn generate_ast_node_file(build_specs: &[BuildSpec]) -> AstGeneratedFile { | |||||||
|         .map(Option::unwrap) |         .map(Option::unwrap) | ||||||
|         .collect::<Vec<_>>(); |         .collect::<Vec<_>>(); | ||||||
| 
 | 
 | ||||||
|  |     let ast_enum_mut_members = build_specs | ||||||
|  |         .iter() | ||||||
|  |         .map(|build_spec| make_ast_enum_mut_member(build_spec)) | ||||||
|  |         .filter(Option::is_some) | ||||||
|  |         .map(Option::unwrap) | ||||||
|  |         .collect::<Vec<_>>(); | ||||||
|  | 
 | ||||||
|     let inner_unwrappers = build_specs |     let inner_unwrappers = build_specs | ||||||
|         .iter() |         .iter() | ||||||
|         .map(|build_spec| make_ast_node_ref_unwrapper(build_spec)) |         .map(|build_spec| make_ast_node_ref_unwrapper(build_spec)) | ||||||
| @ -172,6 +182,13 @@ fn generate_ast_node_file(build_specs: &[BuildSpec]) -> AstGeneratedFile { | |||||||
|         .map(Option::unwrap) |         .map(Option::unwrap) | ||||||
|         .collect::<Vec<_>>(); |         .collect::<Vec<_>>(); | ||||||
| 
 | 
 | ||||||
|  |     let inner_mut_unwrappers = build_specs | ||||||
|  |         .iter() | ||||||
|  |         .map(|build_spec| make_ast_node_ref_mut_unwrapper(build_spec)) | ||||||
|  |         .filter(Option::is_some) | ||||||
|  |         .map(Option::unwrap) | ||||||
|  |         .collect::<Vec<_>>(); | ||||||
|  | 
 | ||||||
|     let combined = quote! { |     let combined = quote! { | ||||||
|         use crate::ast::node::*; |         use crate::ast::node::*; | ||||||
| 
 | 
 | ||||||
| @ -187,10 +204,26 @@ fn generate_ast_node_file(build_specs: &[BuildSpec]) -> AstGeneratedFile { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         pub enum AstNodeRefMut<'a> { | ||||||
|  |             #(#ast_enum_mut_members,)* | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         impl<'a> AstNodeRefMut<'a> { | ||||||
|  |             pub fn inner(&mut self) -> &mut dyn AstNode<'a> { | ||||||
|  |                 match self { | ||||||
|  |                     #(#inner_mut_unwrappers,)* | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         pub trait AstNode<'a> { |         pub trait AstNode<'a> { | ||||||
|             fn children(&'a self) -> Vec<&'a dyn AstNode<'a>>; |             fn children(&'a self) -> Vec<&'a dyn AstNode<'a>>; | ||||||
| 
 | 
 | ||||||
|  |             fn for_each_child_mut(&'a mut self, f: &mut dyn FnMut(&'a mut dyn AstNode<'a>)); | ||||||
|  | 
 | ||||||
|             fn as_node_ref(&'a self) -> AstNodeRef<'a>; |             fn as_node_ref(&'a self) -> AstNodeRef<'a>; | ||||||
|  | 
 | ||||||
|  |             fn as_node_ref_mut(&'a mut self) -> AstNodeRefMut<'a>; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         #(#impls)* |         #(#impls)* | ||||||
|  | |||||||
							
								
								
									
										147
									
								
								src/name_analysis/first_pass.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								src/name_analysis/first_pass.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,147 @@ | |||||||
|  | use crate::ast::node::{CompilationUnit, UseStatement, UseStatementSuffix}; | ||||||
|  | use crate::diagnostic::DmDiagnostic; | ||||||
|  | use crate::name_analysis::fqn_context::FqnContext; | ||||||
|  | use crate::name_analysis::symbol::source_definition::SourceDefinition; | ||||||
|  | use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol}; | ||||||
|  | use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable}; | ||||||
|  | use crate::name_analysis::util::use_statement_base_fqn; | ||||||
|  | use codespan_reporting::diagnostic::{Diagnostic, Label}; | ||||||
|  | use std::range::Range; | ||||||
|  | 
 | ||||||
|  | fn handle_insert_error( | ||||||
|  |     err: SymbolInsertError, | ||||||
|  |     error_symbol_name: &str, | ||||||
|  |     error_file_id: usize, | ||||||
|  |     error_range: Range<usize>, | ||||||
|  |     symbol_types: &str, | ||||||
|  |     diagnostics: &mut Vec<DmDiagnostic>, | ||||||
|  | ) { | ||||||
|  |     match err { | ||||||
|  |         SymbolInsertError::SymbolAlreadyDefined(s) => { | ||||||
|  |             let mut diagnostic = Diagnostic::error() | ||||||
|  |                 .with_message(format!( | ||||||
|  |                     "{} symbol '{}' already defined in the current scope.", | ||||||
|  |                     symbol_types, error_symbol_name, | ||||||
|  |                 )) | ||||||
|  |                 .with_label( | ||||||
|  |                     Label::primary(error_file_id, error_range) | ||||||
|  |                         .with_message("Symbol duplicated here."), | ||||||
|  |                 ); | ||||||
|  | 
 | ||||||
|  |             if let Some(source_definition) = s.definition() { | ||||||
|  |                 diagnostic = diagnostic.with_label( | ||||||
|  |                     Label::secondary(source_definition.file_id(), source_definition.range()) | ||||||
|  |                         .with_message("Symbol defined here."), | ||||||
|  |                 ); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             diagnostics.push(diagnostic); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | macro_rules! insert_symbol { | ||||||
|  |     ($insert_method:ident, $symbol:expr, $symbol_table:ident, $name:expr, $node:ident, $symbol_kinds:literal, $diagnostics:ident) => { | ||||||
|  |         if let Err(insert_error) = $symbol_table.$insert_method($symbol) { | ||||||
|  |             handle_insert_error( | ||||||
|  |                 insert_error, | ||||||
|  |                 $name, | ||||||
|  |                 $node.file_id(), | ||||||
|  |                 $node.range(), | ||||||
|  |                 $symbol_kinds, | ||||||
|  |                 $diagnostics, | ||||||
|  |             ) | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | macro_rules! insert_concrete_use_symbol { | ||||||
|  |     ($symbol:expr, $symbol_table:ident, $symbol_name:expr, $source_node:ident, $symbol_kinds:literal, $diagnostics:ident) => { | ||||||
|  |         insert_symbol!( | ||||||
|  |             insert_concrete_use_symbol, | ||||||
|  |             $symbol, | ||||||
|  |             $symbol_table, | ||||||
|  |             $symbol_name, | ||||||
|  |             $source_node, | ||||||
|  |             $symbol_kinds, | ||||||
|  |             $diagnostics | ||||||
|  |         ) | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub fn np1_compilation_unit( | ||||||
|  |     file_name: &str, | ||||||
|  |     compilation_unit: &mut CompilationUnit, | ||||||
|  |     symbol_table: &mut SymbolTable, | ||||||
|  |     diagnostics: &mut Vec<DmDiagnostic>, | ||||||
|  | ) { | ||||||
|  |     let mut fqn_context = FqnContext::new(); | ||||||
|  |     symbol_table.push_scope(&format!("FileScope {}", file_name)); | ||||||
|  | 
 | ||||||
|  |     if let Some(namespace) = compilation_unit.namespace() { | ||||||
|  |         for identifier in namespace.fqn().identifiers() { | ||||||
|  |             fqn_context.push(identifier.name()); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     for use_statement in compilation_unit.use_statements_mut() { | ||||||
|  |         np1_use_statement(use_statement, symbol_table, diagnostics); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     symbol_table.pop_scope(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn np1_use_statement( | ||||||
|  |     use_statement: &mut UseStatement, | ||||||
|  |     symbol_table: &mut SymbolTable, | ||||||
|  |     diagnostics: &mut Vec<DmDiagnostic>, | ||||||
|  | ) { | ||||||
|  |     let base_fqn = use_statement_base_fqn(use_statement); | ||||||
|  | 
 | ||||||
|  |     match use_statement.suffix() { | ||||||
|  |         UseStatementSuffix::Identifier(identifier) => { | ||||||
|  |             insert_concrete_use_symbol!( | ||||||
|  |                 ConcreteUseSymbol::new( | ||||||
|  |                     &base_fqn, | ||||||
|  |                     identifier.name(), | ||||||
|  |                     Some(SourceDefinition::from_identifier(identifier)) | ||||||
|  |                 ), | ||||||
|  |                 symbol_table, | ||||||
|  |                 &base_fqn, | ||||||
|  |                 identifier, | ||||||
|  |                 "Use Statement", | ||||||
|  |                 diagnostics | ||||||
|  |             ) | ||||||
|  |         } | ||||||
|  |         UseStatementSuffix::Star => { | ||||||
|  |             insert_symbol!( | ||||||
|  |                 insert_star_use_symbol, | ||||||
|  |                 StarUseSymbol::new( | ||||||
|  |                     &base_fqn, | ||||||
|  |                     Some(SourceDefinition::from_use_statement(use_statement)) | ||||||
|  |                 ), | ||||||
|  |                 symbol_table, | ||||||
|  |                 &base_fqn, | ||||||
|  |                 use_statement, | ||||||
|  |                 "Use Statement", | ||||||
|  |                 diagnostics | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |         UseStatementSuffix::UseList(use_list) => { | ||||||
|  |             for identifier in use_list.identifiers() { | ||||||
|  |                 insert_concrete_use_symbol!( | ||||||
|  |                     ConcreteUseSymbol::new( | ||||||
|  |                         &base_fqn, | ||||||
|  |                         identifier.name(), | ||||||
|  |                         Some(SourceDefinition::from_identifier(identifier)) | ||||||
|  |                     ), | ||||||
|  |                     symbol_table, | ||||||
|  |                     &base_fqn, | ||||||
|  |                     identifier, | ||||||
|  |                     "Use Statement", | ||||||
|  |                     diagnostics | ||||||
|  |                 ); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -1,5 +1,5 @@ | |||||||
| /// The gather phase must exclusively gather all named items that can be used elsewhere.
 | /// The gather phase must exclusively gather all named items that can be used elsewhere.
 | ||||||
| use crate::ast::ast_node::{AstNode, AstNodeRef}; | use crate::ast::ast_node::{AstNode, AstNodeRef, AstNodeRefMut}; | ||||||
| use crate::ast::node::{ | use crate::ast::node::{ | ||||||
|     Class, Closure, ClosureParameter, CompilationUnit, ForStatement, Function, FunctionBody, |     Class, Closure, ClosureParameter, CompilationUnit, ForStatement, Function, FunctionBody, | ||||||
|     GenericParameters, Identifier, IfClause, Interface, InterfaceDefaultFunction, |     GenericParameters, Identifier, IfClause, Interface, InterfaceDefaultFunction, | ||||||
| @ -81,54 +81,55 @@ fn handle_lookup_error( | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn gather_node_children<'a>( | fn gather_node_children<'a>( | ||||||
|     node: &'a dyn AstNode<'a>, |     node: &'a mut dyn AstNode<'a>, | ||||||
|     symbol_table: &mut SymbolTable, |     symbol_table: &mut SymbolTable, | ||||||
|     fqn_context: &mut FqnContext, |     fqn_context: &mut FqnContext, | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |     diagnostics: &mut Vec<DmDiagnostic>, | ||||||
| ) { | ) { | ||||||
|     for child in node.children() { |     node.for_each_child_mut(&mut |child| { | ||||||
|         gather_node(child, symbol_table, fqn_context, diagnostics); |        gather_node(child, symbol_table, fqn_context, diagnostics); 
 | ||||||
|     } |     }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn gather_node<'a>( | fn gather_node<'a>( | ||||||
|     node: &'a dyn AstNode<'a>, |     node: &'a mut dyn AstNode<'a>, | ||||||
|     symbol_table: &mut SymbolTable, |     symbol_table: &mut SymbolTable, | ||||||
|     fqn_context: &mut FqnContext, |     fqn_context: &mut FqnContext, | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |     diagnostics: &mut Vec<DmDiagnostic>, | ||||||
| ) { | ) { | ||||||
|     match node.as_node_ref() { |     let node_ref = node.as_node_ref_mut(); | ||||||
|         AstNodeRef::GenericParameters(generic_parameters) => { |     match node_ref { | ||||||
|  |         AstNodeRefMut::GenericParameters(generic_parameters) => { | ||||||
|             gather_generic_parameters(generic_parameters, symbol_table, diagnostics); |             gather_generic_parameters(generic_parameters, symbol_table, diagnostics); | ||||||
|         } |         } | ||||||
|         AstNodeRef::Parameter(parameter) => { |         AstNodeRefMut::Parameter(parameter) => { | ||||||
|             gather_parameter(parameter, symbol_table, diagnostics); |             gather_parameter(parameter, symbol_table, diagnostics); | ||||||
|         } |         } | ||||||
|         AstNodeRef::Namespace(namespace) => { |         AstNodeRefMut::Namespace(namespace) => { | ||||||
|             gather_namespace(namespace, fqn_context); |             gather_namespace(namespace, fqn_context); | ||||||
|         } |         } | ||||||
|         AstNodeRef::UseStatement(use_statement) => { |         AstNodeRefMut::UseStatement(use_statement) => { | ||||||
|             gather_use_statement(use_statement, symbol_table, diagnostics); |             gather_use_statement(use_statement, symbol_table, diagnostics); | ||||||
|         } |         } | ||||||
|         AstNodeRef::Module(module) => { |         AstNodeRefMut::Module(module) => { | ||||||
|             gather_module(module, symbol_table, fqn_context, diagnostics); |             gather_module(module, symbol_table, fqn_context, diagnostics); | ||||||
|         } |         } | ||||||
|         AstNodeRef::Interface(interface) => { |         AstNodeRefMut::Interface(interface) => { | ||||||
|             gather_interface(interface, symbol_table, fqn_context, diagnostics); |             gather_interface(interface, symbol_table, fqn_context, diagnostics); | ||||||
|         } |         } | ||||||
|         AstNodeRef::Class(class) => { |         AstNodeRefMut::Class(class) => { | ||||||
|             gather_class(class, symbol_table, fqn_context, diagnostics); |             gather_class(class, symbol_table, fqn_context, diagnostics); | ||||||
|         } |         } | ||||||
|         AstNodeRef::Function(function) => { |         AstNodeRefMut::Function(function) => { | ||||||
|             gather_function(function, symbol_table, fqn_context, diagnostics); |             gather_function(function, symbol_table, fqn_context, diagnostics); | ||||||
|         } |         } | ||||||
|         AstNodeRef::OperatorFunction(operator_function) => { |         AstNodeRefMut::OperatorFunction(operator_function) => { | ||||||
|             gather_operator_function(operator_function, symbol_table, fqn_context, diagnostics); |             gather_operator_function(operator_function, symbol_table, fqn_context, diagnostics); | ||||||
|         } |         } | ||||||
|         AstNodeRef::PlatformFunction(platform_function) => { |         AstNodeRefMut::PlatformFunction(platform_function) => { | ||||||
|             gather_platform_function(platform_function, symbol_table, fqn_context, diagnostics); |             gather_platform_function(platform_function, symbol_table, fqn_context, diagnostics); | ||||||
|         } |         } | ||||||
|         AstNodeRef::PlatformOperatorFunction(platform_operator_function) => { |         AstNodeRefMut::PlatformOperatorFunction(platform_operator_function) => { | ||||||
|             gather_platform_operator_function( |             gather_platform_operator_function( | ||||||
|                 platform_operator_function, |                 platform_operator_function, | ||||||
|                 symbol_table, |                 symbol_table, | ||||||
| @ -136,10 +137,10 @@ fn gather_node<'a>( | |||||||
|                 diagnostics, |                 diagnostics, | ||||||
|             ); |             ); | ||||||
|         } |         } | ||||||
|         AstNodeRef::InterfaceFunction(interface_function) => { |         AstNodeRefMut::InterfaceFunction(interface_function) => { | ||||||
|             gather_interface_function(interface_function, symbol_table, fqn_context, diagnostics); |             gather_interface_function(interface_function, symbol_table, fqn_context, diagnostics); | ||||||
|         } |         } | ||||||
|         AstNodeRef::InterfaceDefaultFunction(interface_default_function) => { |         AstNodeRefMut::InterfaceDefaultFunction(interface_default_function) => { | ||||||
|             gather_interface_default_function( |             gather_interface_default_function( | ||||||
|                 interface_default_function, |                 interface_default_function, | ||||||
|                 symbol_table, |                 symbol_table, | ||||||
| @ -147,7 +148,7 @@ fn gather_node<'a>( | |||||||
|                 diagnostics, |                 diagnostics, | ||||||
|             ); |             ); | ||||||
|         } |         } | ||||||
|         AstNodeRef::InterfaceOperatorFunction(interface_operator_function) => { |         AstNodeRefMut::InterfaceOperatorFunction(interface_operator_function) => { | ||||||
|             gather_interface_operator_function( |             gather_interface_operator_function( | ||||||
|                 interface_operator_function, |                 interface_operator_function, | ||||||
|                 symbol_table, |                 symbol_table, | ||||||
| @ -155,7 +156,7 @@ fn gather_node<'a>( | |||||||
|                 diagnostics, |                 diagnostics, | ||||||
|             ); |             ); | ||||||
|         } |         } | ||||||
|         AstNodeRef::InterfaceDefaultOperatorFunction(interface_default_operator_function) => { |         AstNodeRefMut::InterfaceDefaultOperatorFunction(interface_default_operator_function) => { | ||||||
|             gather_interface_default_operator_function( |             gather_interface_default_operator_function( | ||||||
|                 interface_default_operator_function, |                 interface_default_operator_function, | ||||||
|                 symbol_table, |                 symbol_table, | ||||||
| @ -163,13 +164,13 @@ fn gather_node<'a>( | |||||||
|                 diagnostics, |                 diagnostics, | ||||||
|             ); |             ); | ||||||
|         } |         } | ||||||
|         AstNodeRef::FunctionBody(function_body) => { |         AstNodeRefMut::FunctionBody(function_body) => { | ||||||
|             gather_function_body(function_body, symbol_table, fqn_context, diagnostics); |             gather_function_body(function_body, symbol_table, fqn_context, diagnostics); | ||||||
|         } |         } | ||||||
|         AstNodeRef::Member(member) => { |         AstNodeRefMut::Member(member) => { | ||||||
|             gather_member(member, symbol_table, fqn_context, diagnostics); |             gather_member(member, symbol_table, fqn_context, diagnostics); | ||||||
|         } |         } | ||||||
|         AstNodeRef::VariableDeclaration(variable_declaration) => { |         AstNodeRefMut::VariableDeclaration(variable_declaration) => { | ||||||
|             gather_variable_declaration( |             gather_variable_declaration( | ||||||
|                 variable_declaration, |                 variable_declaration, | ||||||
|                 symbol_table, |                 symbol_table, | ||||||
| @ -177,32 +178,32 @@ fn gather_node<'a>( | |||||||
|                 diagnostics, |                 diagnostics, | ||||||
|             ); |             ); | ||||||
|         } |         } | ||||||
|         AstNodeRef::IfClause(if_clause) => { |         AstNodeRefMut::IfClause(if_clause) => { | ||||||
|             gather_if_clause(if_clause, symbol_table, fqn_context, diagnostics); |             gather_if_clause(if_clause, symbol_table, fqn_context, diagnostics); | ||||||
|         } |         } | ||||||
|         AstNodeRef::IfElseIf(if_else_if) => { |         AstNodeRefMut::IfElseIf(if_else_if) => { | ||||||
|             gather_node_children(if_else_if, symbol_table, fqn_context, diagnostics); |             gather_node_children(if_else_if, symbol_table, fqn_context, diagnostics); | ||||||
|         } |         } | ||||||
|         AstNodeRef::WhileStatement(while_statement) => { |         AstNodeRefMut::WhileStatement(while_statement) => { | ||||||
|             gather_while_statement(while_statement, symbol_table, fqn_context, diagnostics); |             gather_while_statement(while_statement, symbol_table, fqn_context, diagnostics); | ||||||
|         } |         } | ||||||
|         AstNodeRef::ForStatement(for_statement) => { |         AstNodeRefMut::ForStatement(for_statement) => { | ||||||
|             gather_for_statement(for_statement, symbol_table, fqn_context, diagnostics); |             gather_for_statement(for_statement, symbol_table, fqn_context, diagnostics); | ||||||
|         } |         } | ||||||
|         AstNodeRef::VariableUse(variable_use) => { |         AstNodeRefMut::VariableUse(variable_use) => { | ||||||
|             gather_variable_use(variable_use, symbol_table, diagnostics); |             gather_variable_use(variable_use, symbol_table, diagnostics); | ||||||
|         } |         } | ||||||
|         AstNodeRef::TernaryExpression(ternary_expression) => { |         AstNodeRefMut::TernaryExpression(ternary_expression) => { | ||||||
|             gather_ternary_expression(ternary_expression, symbol_table, fqn_context, diagnostics); |             gather_ternary_expression(ternary_expression, symbol_table, fqn_context, diagnostics); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         AstNodeRef::Closure(closure) => { |         AstNodeRefMut::Closure(closure) => { | ||||||
|             gather_closure(closure, symbol_table, fqn_context, diagnostics); |             gather_closure(closure, symbol_table, fqn_context, diagnostics); | ||||||
|         } |         } | ||||||
|         AstNodeRef::ClosureParameter(closure_parameter) => { |         AstNodeRefMut::ClosureParameter(closure_parameter) => { | ||||||
|             gather_closure_parameter(closure_parameter, symbol_table, fqn_context, diagnostics); |             gather_closure_parameter(closure_parameter, symbol_table, fqn_context, diagnostics); | ||||||
|         } |         } | ||||||
|         _ => gather_node_children(node, symbol_table, fqn_context, diagnostics), |         _ => todo!() | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -230,7 +231,7 @@ fn gather_generic_parameters<'a>( | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn gather_parameter<'a>( | fn gather_parameter<'a>( | ||||||
|     parameter: &'a Parameter, |     parameter: &'a mut Parameter, | ||||||
|     symbol_table: &mut SymbolTable, |     symbol_table: &mut SymbolTable, | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |     diagnostics: &mut Vec<DmDiagnostic>, | ||||||
| ) { | ) { | ||||||
| @ -251,7 +252,7 @@ fn gather_parameter<'a>( | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub fn gather_compilation_unit<'a>( | pub fn gather_compilation_unit<'a>( | ||||||
|     compilation_unit: &'a CompilationUnit, |     compilation_unit: &'a mut CompilationUnit, | ||||||
|     file_name: &str, |     file_name: &str, | ||||||
|     symbol_table: &mut SymbolTable, |     symbol_table: &mut SymbolTable, | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |     diagnostics: &mut Vec<DmDiagnostic>, | ||||||
| @ -337,7 +338,7 @@ fn gather_concrete_use_symbol( | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn gather_module<'a>( | fn gather_module<'a>( | ||||||
|     module: &'a Module, |     module: &'a mut Module, | ||||||
|     symbol_table: &mut SymbolTable, |     symbol_table: &mut SymbolTable, | ||||||
|     fqn_context: &mut FqnContext, |     fqn_context: &mut FqnContext, | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |     diagnostics: &mut Vec<DmDiagnostic>, | ||||||
| @ -362,7 +363,7 @@ fn gather_module<'a>( | |||||||
|     fqn_context.push(module.identifier().name()); |     fqn_context.push(module.identifier().name()); | ||||||
|     symbol_table.push_scope(&format!("ModuleScope {}", module.identifier().name())); |     symbol_table.push_scope(&format!("ModuleScope {}", module.identifier().name())); | ||||||
| 
 | 
 | ||||||
|     for declaration in module.declarations() { |     for declaration in module.declarations_mut() { | ||||||
|         gather_node(declaration, symbol_table, fqn_context, diagnostics); |         gather_node(declaration, symbol_table, fqn_context, diagnostics); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -371,7 +372,7 @@ fn gather_module<'a>( | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn gather_interface<'a>( | fn gather_interface<'a>( | ||||||
|     interface: &'a Interface, |     interface: &'a mut Interface, | ||||||
|     symbol_table: &mut SymbolTable, |     symbol_table: &mut SymbolTable, | ||||||
|     fqn_context: &mut FqnContext, |     fqn_context: &mut FqnContext, | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |     diagnostics: &mut Vec<DmDiagnostic>, | ||||||
| @ -399,7 +400,7 @@ fn gather_interface<'a>( | |||||||
|     fqn_context.push(interface.identifier().name()); |     fqn_context.push(interface.identifier().name()); | ||||||
|     symbol_table.push_scope(&format!("InterfaceScope {}", interface.identifier().name())); |     symbol_table.push_scope(&format!("InterfaceScope {}", interface.identifier().name())); | ||||||
| 
 | 
 | ||||||
|     for declaration in interface.declarations() { |     for declaration in interface.declarations_mut() { | ||||||
|         gather_node(declaration, symbol_table, fqn_context, diagnostics); |         gather_node(declaration, symbol_table, fqn_context, diagnostics); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -408,7 +409,7 @@ fn gather_interface<'a>( | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn gather_class<'a>( | fn gather_class<'a>( | ||||||
|     class: &'a Class, |     class: &'a mut Class, | ||||||
|     symbol_table: &mut SymbolTable, |     symbol_table: &mut SymbolTable, | ||||||
|     fqn_context: &mut FqnContext, |     fqn_context: &mut FqnContext, | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |     diagnostics: &mut Vec<DmDiagnostic>, | ||||||
| @ -437,12 +438,12 @@ fn gather_class<'a>( | |||||||
|     symbol_table.push_scope(&format!("ClassScope {}", class.identifier().name())); |     symbol_table.push_scope(&format!("ClassScope {}", class.identifier().name())); | ||||||
| 
 | 
 | ||||||
|     gather_node( |     gather_node( | ||||||
|         class.class_constructor(), |         class.class_constructor_mut(), | ||||||
|         symbol_table, |         symbol_table, | ||||||
|         fqn_context, |         fqn_context, | ||||||
|         diagnostics, |         diagnostics, | ||||||
|     ); |     ); | ||||||
|     for declaration in class.class_level_declarations() { |     for declaration in class.class_level_declarations_mut() { | ||||||
|         gather_node(declaration, symbol_table, fqn_context, diagnostics); |         gather_node(declaration, symbol_table, fqn_context, diagnostics); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -451,7 +452,7 @@ fn gather_class<'a>( | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn gather_function<'a>( | fn gather_function<'a>( | ||||||
|     function: &'a Function, |     function: &'a mut Function, | ||||||
|     symbol_table: &mut SymbolTable, |     symbol_table: &mut SymbolTable, | ||||||
|     fqn_context: &mut FqnContext, |     fqn_context: &mut FqnContext, | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |     diagnostics: &mut Vec<DmDiagnostic>, | ||||||
| @ -474,21 +475,21 @@ fn gather_function<'a>( | |||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
|     symbol_table.push_scope(&format!("FunctionScope {}", function.identifier().name())); |     symbol_table.push_scope(&format!("FunctionScope {}", function.identifier().name())); | ||||||
|     gather_node(function.generics(), symbol_table, fqn_context, diagnostics); |     gather_node(function.generics_mut(), symbol_table, fqn_context, diagnostics); | ||||||
|     gather_node( |     gather_node( | ||||||
|         function.parameters(), |         function.parameters_mut(), | ||||||
|         symbol_table, |         symbol_table, | ||||||
|         fqn_context, |         fqn_context, | ||||||
|         diagnostics, |         diagnostics, | ||||||
|     ); |     ); | ||||||
|     gather_node( |     gather_node( | ||||||
|         function.return_type(), |         function.return_type_mut(), | ||||||
|         symbol_table, |         symbol_table, | ||||||
|         fqn_context, |         fqn_context, | ||||||
|         diagnostics, |         diagnostics, | ||||||
|     ); |     ); | ||||||
|     gather_node( |     gather_node( | ||||||
|         function.function_body(), |         function.function_body_mut(), | ||||||
|         symbol_table, |         symbol_table, | ||||||
|         fqn_context, |         fqn_context, | ||||||
|         diagnostics, |         diagnostics, | ||||||
| @ -497,7 +498,7 @@ fn gather_function<'a>( | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn gather_operator_function<'a>( | fn gather_operator_function<'a>( | ||||||
|     operator_function: &'a OperatorFunction, |     operator_function: &'a mut OperatorFunction, | ||||||
|     symbol_table: &mut SymbolTable, |     symbol_table: &mut SymbolTable, | ||||||
|     fqn_context: &mut FqnContext, |     fqn_context: &mut FqnContext, | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |     diagnostics: &mut Vec<DmDiagnostic>, | ||||||
| @ -526,25 +527,25 @@ fn gather_operator_function<'a>( | |||||||
|         operator_function.operator().inner().name() |         operator_function.operator().inner().name() | ||||||
|     )); |     )); | ||||||
|     gather_node( |     gather_node( | ||||||
|         operator_function.generics(), |         operator_function.generics_mut(), | ||||||
|         symbol_table, |         symbol_table, | ||||||
|         fqn_context, |         fqn_context, | ||||||
|         diagnostics, |         diagnostics, | ||||||
|     ); |     ); | ||||||
|     gather_node( |     gather_node( | ||||||
|         operator_function.parameters(), |         operator_function.parameters_mut(), | ||||||
|         symbol_table, |         symbol_table, | ||||||
|         fqn_context, |         fqn_context, | ||||||
|         diagnostics, |         diagnostics, | ||||||
|     ); |     ); | ||||||
|     gather_node( |     gather_node( | ||||||
|         operator_function.return_type(), |         operator_function.return_type_mut(), | ||||||
|         symbol_table, |         symbol_table, | ||||||
|         fqn_context, |         fqn_context, | ||||||
|         diagnostics, |         diagnostics, | ||||||
|     ); |     ); | ||||||
|     gather_node( |     gather_node( | ||||||
|         operator_function.function_body(), |         operator_function.function_body_mut(), | ||||||
|         symbol_table, |         symbol_table, | ||||||
|         fqn_context, |         fqn_context, | ||||||
|         diagnostics, |         diagnostics, | ||||||
| @ -553,7 +554,7 @@ fn gather_operator_function<'a>( | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn gather_platform_function<'a>( | fn gather_platform_function<'a>( | ||||||
|     platform_function: &'a PlatformFunction, |     platform_function: &'a mut PlatformFunction, | ||||||
|     symbol_table: &mut SymbolTable, |     symbol_table: &mut SymbolTable, | ||||||
|     fqn_context: &mut FqnContext, |     fqn_context: &mut FqnContext, | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |     diagnostics: &mut Vec<DmDiagnostic>, | ||||||
| @ -582,19 +583,19 @@ fn gather_platform_function<'a>( | |||||||
|         platform_function.identifier().name() |         platform_function.identifier().name() | ||||||
|     )); |     )); | ||||||
|     gather_node( |     gather_node( | ||||||
|         platform_function.generics(), |         platform_function.generics_mut(), | ||||||
|         symbol_table, |         symbol_table, | ||||||
|         fqn_context, |         fqn_context, | ||||||
|         diagnostics, |         diagnostics, | ||||||
|     ); |     ); | ||||||
|     gather_node( |     gather_node( | ||||||
|         platform_function.parameters(), |         platform_function.parameters_mut(), | ||||||
|         symbol_table, |         symbol_table, | ||||||
|         fqn_context, |         fqn_context, | ||||||
|         diagnostics, |         diagnostics, | ||||||
|     ); |     ); | ||||||
|     gather_node( |     gather_node( | ||||||
|         platform_function.return_type(), |         platform_function.return_type_mut(), | ||||||
|         symbol_table, |         symbol_table, | ||||||
|         fqn_context, |         fqn_context, | ||||||
|         diagnostics, |         diagnostics, | ||||||
| @ -603,7 +604,7 @@ fn gather_platform_function<'a>( | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn gather_platform_operator_function<'a>( | fn gather_platform_operator_function<'a>( | ||||||
|     platform_operator_function: &'a PlatformOperatorFunction, |     platform_operator_function: &'a mut PlatformOperatorFunction, | ||||||
|     symbol_table: &mut SymbolTable, |     symbol_table: &mut SymbolTable, | ||||||
|     fqn_context: &mut FqnContext, |     fqn_context: &mut FqnContext, | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |     diagnostics: &mut Vec<DmDiagnostic>, | ||||||
| @ -632,19 +633,19 @@ fn gather_platform_operator_function<'a>( | |||||||
|         platform_operator_function.operator().inner().name() |         platform_operator_function.operator().inner().name() | ||||||
|     )); |     )); | ||||||
|     gather_node( |     gather_node( | ||||||
|         platform_operator_function.generics(), |         platform_operator_function.generics_mut(), | ||||||
|         symbol_table, |         symbol_table, | ||||||
|         fqn_context, |         fqn_context, | ||||||
|         diagnostics, |         diagnostics, | ||||||
|     ); |     ); | ||||||
|     gather_node( |     gather_node( | ||||||
|         platform_operator_function.parameters(), |         platform_operator_function.parameters_mut(), | ||||||
|         symbol_table, |         symbol_table, | ||||||
|         fqn_context, |         fqn_context, | ||||||
|         diagnostics, |         diagnostics, | ||||||
|     ); |     ); | ||||||
|     gather_node( |     gather_node( | ||||||
|         platform_operator_function.return_type(), |         platform_operator_function.return_type_mut(), | ||||||
|         symbol_table, |         symbol_table, | ||||||
|         fqn_context, |         fqn_context, | ||||||
|         diagnostics, |         diagnostics, | ||||||
| @ -653,7 +654,7 @@ fn gather_platform_operator_function<'a>( | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn gather_interface_function<'a>( | fn gather_interface_function<'a>( | ||||||
|     interface_function: &'a InterfaceFunction, |     interface_function: &'a mut InterfaceFunction, | ||||||
|     symbol_table: &mut SymbolTable, |     symbol_table: &mut SymbolTable, | ||||||
|     fqn_context: &mut FqnContext, |     fqn_context: &mut FqnContext, | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |     diagnostics: &mut Vec<DmDiagnostic>, | ||||||
| @ -682,19 +683,19 @@ fn gather_interface_function<'a>( | |||||||
|         interface_function.identifier().name() |         interface_function.identifier().name() | ||||||
|     )); |     )); | ||||||
|     gather_node( |     gather_node( | ||||||
|         interface_function.generics(), |         interface_function.generics_mut(), | ||||||
|         symbol_table, |         symbol_table, | ||||||
|         fqn_context, |         fqn_context, | ||||||
|         diagnostics, |         diagnostics, | ||||||
|     ); |     ); | ||||||
|     gather_node( |     gather_node( | ||||||
|         interface_function.parameters(), |         interface_function.parameters_mut(), | ||||||
|         symbol_table, |         symbol_table, | ||||||
|         fqn_context, |         fqn_context, | ||||||
|         diagnostics, |         diagnostics, | ||||||
|     ); |     ); | ||||||
|     gather_node( |     gather_node( | ||||||
|         interface_function.return_type(), |         interface_function.return_type_mut(), | ||||||
|         symbol_table, |         symbol_table, | ||||||
|         fqn_context, |         fqn_context, | ||||||
|         diagnostics, |         diagnostics, | ||||||
| @ -703,7 +704,7 @@ fn gather_interface_function<'a>( | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn gather_interface_default_function<'a>( | fn gather_interface_default_function<'a>( | ||||||
|     interface_default_function: &'a InterfaceDefaultFunction, |     interface_default_function: &'a mut InterfaceDefaultFunction, | ||||||
|     symbol_table: &mut SymbolTable, |     symbol_table: &mut SymbolTable, | ||||||
|     fqn_context: &mut FqnContext, |     fqn_context: &mut FqnContext, | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |     diagnostics: &mut Vec<DmDiagnostic>, | ||||||
| @ -732,25 +733,25 @@ fn gather_interface_default_function<'a>( | |||||||
|         interface_default_function.identifier().name() |         interface_default_function.identifier().name() | ||||||
|     )); |     )); | ||||||
|     gather_node( |     gather_node( | ||||||
|         interface_default_function.generics(), |         interface_default_function.generics_mut(), | ||||||
|         symbol_table, |         symbol_table, | ||||||
|         fqn_context, |         fqn_context, | ||||||
|         diagnostics, |         diagnostics, | ||||||
|     ); |     ); | ||||||
|     gather_node( |     gather_node( | ||||||
|         interface_default_function.parameters(), |         interface_default_function.parameters_mut(), | ||||||
|         symbol_table, |         symbol_table, | ||||||
|         fqn_context, |         fqn_context, | ||||||
|         diagnostics, |         diagnostics, | ||||||
|     ); |     ); | ||||||
|     gather_node( |     gather_node( | ||||||
|         interface_default_function.return_type(), |         interface_default_function.return_type_mut(), | ||||||
|         symbol_table, |         symbol_table, | ||||||
|         fqn_context, |         fqn_context, | ||||||
|         diagnostics, |         diagnostics, | ||||||
|     ); |     ); | ||||||
|     gather_node( |     gather_node( | ||||||
|         interface_default_function.function_body(), |         interface_default_function.function_body_mut(), | ||||||
|         symbol_table, |         symbol_table, | ||||||
|         fqn_context, |         fqn_context, | ||||||
|         diagnostics, |         diagnostics, | ||||||
| @ -759,7 +760,7 @@ fn gather_interface_default_function<'a>( | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn gather_interface_operator_function<'a>( | fn gather_interface_operator_function<'a>( | ||||||
|     interface_operator_function: &'a InterfaceOperatorFunction, |     interface_operator_function: &'a mut InterfaceOperatorFunction, | ||||||
|     symbol_table: &mut SymbolTable, |     symbol_table: &mut SymbolTable, | ||||||
|     fqn_context: &mut FqnContext, |     fqn_context: &mut FqnContext, | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |     diagnostics: &mut Vec<DmDiagnostic>, | ||||||
| @ -788,19 +789,19 @@ fn gather_interface_operator_function<'a>( | |||||||
|         interface_operator_function.operator().inner().name() |         interface_operator_function.operator().inner().name() | ||||||
|     )); |     )); | ||||||
|     gather_node( |     gather_node( | ||||||
|         interface_operator_function.generics(), |         interface_operator_function.generics_mut(), | ||||||
|         symbol_table, |         symbol_table, | ||||||
|         fqn_context, |         fqn_context, | ||||||
|         diagnostics, |         diagnostics, | ||||||
|     ); |     ); | ||||||
|     gather_node( |     gather_node( | ||||||
|         interface_operator_function.parameters(), |         interface_operator_function.parameters_mut(), | ||||||
|         symbol_table, |         symbol_table, | ||||||
|         fqn_context, |         fqn_context, | ||||||
|         diagnostics, |         diagnostics, | ||||||
|     ); |     ); | ||||||
|     gather_node( |     gather_node( | ||||||
|         interface_operator_function.return_type(), |         interface_operator_function.return_type_mut(), | ||||||
|         symbol_table, |         symbol_table, | ||||||
|         fqn_context, |         fqn_context, | ||||||
|         diagnostics, |         diagnostics, | ||||||
| @ -809,7 +810,7 @@ fn gather_interface_operator_function<'a>( | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn gather_interface_default_operator_function<'a>( | fn gather_interface_default_operator_function<'a>( | ||||||
|     interface_default_operator_function: &'a InterfaceDefaultOperatorFunction, |     interface_default_operator_function: &'a mut InterfaceDefaultOperatorFunction, | ||||||
|     symbol_table: &mut SymbolTable, |     symbol_table: &mut SymbolTable, | ||||||
|     fqn_context: &mut FqnContext, |     fqn_context: &mut FqnContext, | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |     diagnostics: &mut Vec<DmDiagnostic>, | ||||||
| @ -852,25 +853,25 @@ fn gather_interface_default_operator_function<'a>( | |||||||
|             .name() |             .name() | ||||||
|     )); |     )); | ||||||
|     gather_node( |     gather_node( | ||||||
|         interface_default_operator_function.generics(), |         interface_default_operator_function.generics_mut(), | ||||||
|         symbol_table, |         symbol_table, | ||||||
|         fqn_context, |         fqn_context, | ||||||
|         diagnostics, |         diagnostics, | ||||||
|     ); |     ); | ||||||
|     gather_node( |     gather_node( | ||||||
|         interface_default_operator_function.parameters(), |         interface_default_operator_function.parameters_mut(), | ||||||
|         symbol_table, |         symbol_table, | ||||||
|         fqn_context, |         fqn_context, | ||||||
|         diagnostics, |         diagnostics, | ||||||
|     ); |     ); | ||||||
|     gather_node( |     gather_node( | ||||||
|         interface_default_operator_function.return_type(), |         interface_default_operator_function.return_type_mut(), | ||||||
|         symbol_table, |         symbol_table, | ||||||
|         fqn_context, |         fqn_context, | ||||||
|         diagnostics, |         diagnostics, | ||||||
|     ); |     ); | ||||||
|     gather_node( |     gather_node( | ||||||
|         interface_default_operator_function.function_body(), |         interface_default_operator_function.function_body_mut(), | ||||||
|         symbol_table, |         symbol_table, | ||||||
|         fqn_context, |         fqn_context, | ||||||
|         diagnostics, |         diagnostics, | ||||||
| @ -879,7 +880,7 @@ fn gather_interface_default_operator_function<'a>( | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn gather_function_body<'a>( | fn gather_function_body<'a>( | ||||||
|     function_body: &'a FunctionBody, |     function_body: &'a mut FunctionBody, | ||||||
|     symbol_table: &mut SymbolTable, |     symbol_table: &mut SymbolTable, | ||||||
|     fqn_context: &mut FqnContext, |     fqn_context: &mut FqnContext, | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |     diagnostics: &mut Vec<DmDiagnostic>, | ||||||
| @ -890,7 +891,7 @@ fn gather_function_body<'a>( | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn gather_member<'a>( | fn gather_member<'a>( | ||||||
|     member: &'a Member, |     member: &'a mut Member, | ||||||
|     symbol_table: &mut SymbolTable, |     symbol_table: &mut SymbolTable, | ||||||
|     fqn_context: &mut FqnContext, |     fqn_context: &mut FqnContext, | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |     diagnostics: &mut Vec<DmDiagnostic>, | ||||||
| @ -911,11 +912,11 @@ fn gather_member<'a>( | |||||||
|             diagnostics, |             diagnostics, | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
|     gather_node(member.type_use(), symbol_table, fqn_context, diagnostics); |     gather_node(member.type_use_mut(), symbol_table, fqn_context, diagnostics); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn gather_variable_declaration<'a>( | fn gather_variable_declaration<'a>( | ||||||
|     variable_declaration: &'a VariableDeclaration, |     variable_declaration: &'a mut VariableDeclaration, | ||||||
|     symbol_table: &mut SymbolTable, |     symbol_table: &mut SymbolTable, | ||||||
|     fqn_context: &mut FqnContext, |     fqn_context: &mut FqnContext, | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |     diagnostics: &mut Vec<DmDiagnostic>, | ||||||
| @ -937,26 +938,26 @@ fn gather_variable_declaration<'a>( | |||||||
|             diagnostics, |             diagnostics, | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
|     if let Some(expression) = variable_declaration.expression() { |     if let Some(expression) = variable_declaration.expression_mut() { | ||||||
|         gather_node(expression, symbol_table, fqn_context, diagnostics); |         gather_node(expression, symbol_table, fqn_context, diagnostics); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn gather_if_clause<'a>( | fn gather_if_clause<'a>( | ||||||
|     if_clause: &'a IfClause, |     if_clause: &'a mut IfClause, | ||||||
|     symbol_table: &mut SymbolTable, |     symbol_table: &mut SymbolTable, | ||||||
|     fqn_context: &mut FqnContext, |     fqn_context: &mut FqnContext, | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |     diagnostics: &mut Vec<DmDiagnostic>, | ||||||
| ) { | ) { | ||||||
|     symbol_table.push_scope("IfClauseScope"); |     symbol_table.push_scope("IfClauseScope"); | ||||||
|     gather_node( |     gather_node( | ||||||
|         if_clause.expression(), |         if_clause.expression_mut(), | ||||||
|         symbol_table, |         symbol_table, | ||||||
|         fqn_context, |         fqn_context, | ||||||
|         diagnostics, |         diagnostics, | ||||||
|     ); |     ); | ||||||
|     symbol_table.push_scope("IfClauseStatementsScope"); |     symbol_table.push_scope("IfClauseStatementsScope"); | ||||||
|     for statement in if_clause.statements() { |     for statement in if_clause.statements_mut() { | ||||||
|         gather_node(statement, symbol_table, fqn_context, diagnostics); |         gather_node(statement, symbol_table, fqn_context, diagnostics); | ||||||
|     } |     } | ||||||
|     symbol_table.pop_scope(); |     symbol_table.pop_scope(); | ||||||
| @ -964,20 +965,20 @@ fn gather_if_clause<'a>( | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn gather_while_statement<'a>( | fn gather_while_statement<'a>( | ||||||
|     while_statement: &'a WhileStatement, |     while_statement: &'a mut WhileStatement, | ||||||
|     symbol_table: &mut SymbolTable, |     symbol_table: &mut SymbolTable, | ||||||
|     fqn_context: &mut FqnContext, |     fqn_context: &mut FqnContext, | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |     diagnostics: &mut Vec<DmDiagnostic>, | ||||||
| ) { | ) { | ||||||
|     symbol_table.push_scope("WhileStatementScope"); |     symbol_table.push_scope("WhileStatementScope"); | ||||||
|     gather_node( |     gather_node( | ||||||
|         while_statement.expression(), |         while_statement.expression_mut(), | ||||||
|         symbol_table, |         symbol_table, | ||||||
|         fqn_context, |         fqn_context, | ||||||
|         diagnostics, |         diagnostics, | ||||||
|     ); |     ); | ||||||
|     symbol_table.push_scope("WhileStatementStatementsScope"); |     symbol_table.push_scope("WhileStatementStatementsScope"); | ||||||
|     for statement in while_statement.statements() { |     for statement in while_statement.statements_mut() { | ||||||
|         gather_node(statement, symbol_table, fqn_context, diagnostics); |         gather_node(statement, symbol_table, fqn_context, diagnostics); | ||||||
|     } |     } | ||||||
|     symbol_table.pop_scope(); |     symbol_table.pop_scope(); | ||||||
| @ -985,13 +986,13 @@ fn gather_while_statement<'a>( | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn gather_for_statement<'a>( | fn gather_for_statement<'a>( | ||||||
|     for_statement: &'a ForStatement, |     for_statement: &'a mut ForStatement, | ||||||
|     symbol_table: &mut SymbolTable, |     symbol_table: &mut SymbolTable, | ||||||
|     fqn_context: &mut FqnContext, |     fqn_context: &mut FqnContext, | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |     diagnostics: &mut Vec<DmDiagnostic>, | ||||||
| ) { | ) { | ||||||
|     gather_node( |     gather_node( | ||||||
|         for_statement.expression(), |         for_statement.expression_mut(), | ||||||
|         symbol_table, |         symbol_table, | ||||||
|         fqn_context, |         fqn_context, | ||||||
|         diagnostics, |         diagnostics, | ||||||
| @ -1015,7 +1016,7 @@ fn gather_for_statement<'a>( | |||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
|     symbol_table.push_scope("ForStatementStatementsScope"); |     symbol_table.push_scope("ForStatementStatementsScope"); | ||||||
|     for statement in for_statement.statements() { |     for statement in for_statement.statements_mut() { | ||||||
|         gather_node(statement, symbol_table, fqn_context, diagnostics); |         gather_node(statement, symbol_table, fqn_context, diagnostics); | ||||||
|     } |     } | ||||||
|     symbol_table.pop_scope(); |     symbol_table.pop_scope(); | ||||||
| @ -1043,7 +1044,7 @@ fn gather_variable_use<'a>( | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn gather_ternary_expression<'a>( | fn gather_ternary_expression<'a>( | ||||||
|     ternary_expression: &'a TernaryExpression, |     ternary_expression: &'a mut TernaryExpression, | ||||||
|     symbol_table: &mut SymbolTable, |     symbol_table: &mut SymbolTable, | ||||||
|     fqn_context: &mut FqnContext, |     fqn_context: &mut FqnContext, | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |     diagnostics: &mut Vec<DmDiagnostic>, | ||||||
| @ -1054,20 +1055,20 @@ fn gather_ternary_expression<'a>( | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn gather_closure<'a>( | fn gather_closure<'a>( | ||||||
|     closure: &'a Closure, |     closure: &'a mut Closure, | ||||||
|     symbol_table: &mut SymbolTable, |     symbol_table: &mut SymbolTable, | ||||||
|     fqn_context: &mut FqnContext, |     fqn_context: &mut FqnContext, | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |     diagnostics: &mut Vec<DmDiagnostic>, | ||||||
| ) { | ) { | ||||||
|     symbol_table.push_scope("ClosureScope"); |     symbol_table.push_scope("ClosureScope"); | ||||||
|     gather_node( |     gather_node( | ||||||
|         closure.closure_parameters(), |         closure.closure_parameters_mut(), | ||||||
|         symbol_table, |         symbol_table, | ||||||
|         fqn_context, |         fqn_context, | ||||||
|         diagnostics, |         diagnostics, | ||||||
|     ); |     ); | ||||||
|     symbol_table.push_scope("ClosureStatementsScope"); |     symbol_table.push_scope("ClosureStatementsScope"); | ||||||
|     for statement in closure.statements() { |     for statement in closure.statements_mut() { | ||||||
|         gather_node(statement, symbol_table, fqn_context, diagnostics); |         gather_node(statement, symbol_table, fqn_context, diagnostics); | ||||||
|     } |     } | ||||||
|     symbol_table.pop_scope(); |     symbol_table.pop_scope(); | ||||||
| @ -1075,7 +1076,7 @@ fn gather_closure<'a>( | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn gather_closure_parameter<'a>( | fn gather_closure_parameter<'a>( | ||||||
|     closure_parameter: &'a ClosureParameter, |     closure_parameter: &'a mut ClosureParameter, | ||||||
|     symbol_table: &mut SymbolTable, |     symbol_table: &mut SymbolTable, | ||||||
|     fqn_context: &mut FqnContext, |     fqn_context: &mut FqnContext, | ||||||
|     diagnostics: &mut Vec<DmDiagnostic>, |     diagnostics: &mut Vec<DmDiagnostic>, | ||||||
| @ -1096,7 +1097,7 @@ fn gather_closure_parameter<'a>( | |||||||
|             diagnostics, |             diagnostics, | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
|     if let Some(type_use) = closure_parameter.type_use() { |     if let Some(type_use) = closure_parameter.type_use_mut() { | ||||||
|         gather_node(type_use, symbol_table, fqn_context, diagnostics); |         gather_node(type_use, symbol_table, fqn_context, diagnostics); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -23,7 +23,7 @@ The resolve phase has one main responsibility: resolve all references based on t | |||||||
| use crate::ast::ast_node::AstNode; | use crate::ast::ast_node::AstNode; | ||||||
| use crate::ast::node::CompilationUnit; | use crate::ast::node::CompilationUnit; | ||||||
| use crate::diagnostic::DmDiagnostic; | use crate::diagnostic::DmDiagnostic; | ||||||
| use crate::name_analysis::gather::gather_compilation_unit; | use crate::name_analysis::first_pass::np1_compilation_unit; | ||||||
| use crate::name_analysis::symbol_table::SymbolTable; | use crate::name_analysis::symbol_table::SymbolTable; | ||||||
| use codespan_reporting::files::Files; | use codespan_reporting::files::Files; | ||||||
| use std::hash::Hash; | use std::hash::Hash; | ||||||
| @ -31,26 +31,24 @@ use std::hash::Hash; | |||||||
| pub(self) mod fqn_context; | pub(self) mod fqn_context; | ||||||
| mod gather; | mod gather; | ||||||
| // mod resolve;
 | // mod resolve;
 | ||||||
|  | mod first_pass; | ||||||
|  | mod scope_table; | ||||||
|  | mod second_pass; | ||||||
| pub mod symbol; | pub mod symbol; | ||||||
| pub mod symbol_table; | pub mod symbol_table; | ||||||
| mod scope_table; | mod util; | ||||||
| 
 | 
 | ||||||
| pub fn analyze_names<'a, F: Files<'a, FileId = usize, Name = String>>( | pub fn analyze_names<'a, F: Files<'a, FileId = usize, Name = String>>( | ||||||
|     compilation_units: &[Box<CompilationUnit>], |     compilation_units: &mut Vec<Box<CompilationUnit>>, | ||||||
|     files: &'a F, |     files: &'a F, | ||||||
|     symbol_table: &mut SymbolTable, |     symbol_table: &mut SymbolTable, | ||||||
| ) -> Vec<DmDiagnostic> { | ) -> Vec<DmDiagnostic> { | ||||||
|     let mut diagnostics = vec![]; |     let mut diagnostics = vec![]; | ||||||
| 
 | 
 | ||||||
|     // gather symbols
 |     // gather symbols
 | ||||||
|     for compilation_unit in compilation_units { |     for compilation_unit in compilation_units.iter_mut() { | ||||||
|         let file_name = files.name(compilation_unit.file_id()).unwrap(); |         let file_name = files.name(compilation_unit.file_id()).unwrap(); | ||||||
|         gather_compilation_unit( |         np1_compilation_unit(&file_name, compilation_unit, symbol_table, &mut diagnostics); | ||||||
|             compilation_unit, |  | ||||||
|             &file_name, |  | ||||||
|             symbol_table, |  | ||||||
|             &mut diagnostics, |  | ||||||
|         ); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // resolve symbols
 |     // resolve symbols
 | ||||||
|  | |||||||
							
								
								
									
										87
									
								
								src/name_analysis/second_pass.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								src/name_analysis/second_pass.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,87 @@ | |||||||
|  | use crate::ast::node::{CompilationUnit, Identifier, UseStatement, UseStatementSuffix}; | ||||||
|  | use crate::diagnostic::DmDiagnostic; | ||||||
|  | use crate::name_analysis::symbol_table::{SymbolLookupError, SymbolTable}; | ||||||
|  | use crate::name_analysis::util::use_statement_base_fqn; | ||||||
|  | use codespan_reporting::diagnostic::{Diagnostic, Label}; | ||||||
|  | use std::range::Range; | ||||||
|  | 
 | ||||||
|  | fn handle_lookup_error( | ||||||
|  |     err: SymbolLookupError, | ||||||
|  |     error_symbol_name: &str, | ||||||
|  |     error_file_id: usize, | ||||||
|  |     error_range: Range<usize>, | ||||||
|  |     symbol_types: &str, | ||||||
|  |     diagnostics: &mut Vec<DmDiagnostic>, | ||||||
|  | ) { | ||||||
|  |     match err { | ||||||
|  |         SymbolLookupError::NoDefinition => { | ||||||
|  |             let diagnostic = Diagnostic::error() | ||||||
|  |                 .with_message(format!( | ||||||
|  |                     "No such {} symbol '{}' in scope.", | ||||||
|  |                     symbol_types, error_symbol_name, | ||||||
|  |                 )) | ||||||
|  |                 .with_label( | ||||||
|  |                     Label::primary(error_file_id, error_range).with_message("Symbol used here."), | ||||||
|  |                 ); | ||||||
|  |             diagnostics.push(diagnostic); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub fn nap2_compilation_unit( | ||||||
|  |     compilation_unit: &mut CompilationUnit, | ||||||
|  |     symbol_table: &SymbolTable, | ||||||
|  |     diagnostics: &mut Vec<DmDiagnostic>, | ||||||
|  | ) { | ||||||
|  |     // TODO: check namespace for proper file name
 | ||||||
|  |     for use_statement in compilation_unit.use_statements_mut() { | ||||||
|  |         nap2_use_statement(use_statement, symbol_table, diagnostics); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // TODO: declarations
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn nap2_use_statement( | ||||||
|  |     use_statement: &mut UseStatement, | ||||||
|  |     symbol_table: &SymbolTable, | ||||||
|  |     diagnostics: &mut Vec<DmDiagnostic>, | ||||||
|  | ) { | ||||||
|  |     let base_fqn = use_statement_base_fqn(use_statement); | ||||||
|  |     
 | ||||||
|  |     let mut handle_concrete_use_symbol = |identifier: &Identifier| { | ||||||
|  |         let fqn = format!("{}::{}", base_fqn, identifier.name()); | ||||||
|  |         if let Err(error) = symbol_table.resolve_usable_by_fqn(&fqn) { | ||||||
|  |             handle_lookup_error( | ||||||
|  |                 error, | ||||||
|  |                 &fqn, | ||||||
|  |                 use_statement.file_id(), | ||||||
|  |                 use_statement.range(), | ||||||
|  |                 "Usable Symbol", | ||||||
|  |                 diagnostics, | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     match use_statement.suffix() { | ||||||
|  |         UseStatementSuffix::Identifier(identifier) => { | ||||||
|  |             handle_concrete_use_symbol(identifier); | ||||||
|  |         } | ||||||
|  |         UseStatementSuffix::Star => { | ||||||
|  |             if let Err(error) = symbol_table.resolve_usable_star(&base_fqn) { | ||||||
|  |                 handle_lookup_error( | ||||||
|  |                     error, | ||||||
|  |                     &base_fqn, | ||||||
|  |                     use_statement.file_id(), | ||||||
|  |                     use_statement.range(), | ||||||
|  |                     "Star Usable Symbol", | ||||||
|  |                     diagnostics, | ||||||
|  |                 ); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         UseStatementSuffix::UseList(use_list) => { | ||||||
|  |             for identifier in use_list.identifiers() { | ||||||
|  |                 handle_concrete_use_symbol(identifier); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -377,6 +377,20 @@ impl SymbolTable { | |||||||
|         } |         } | ||||||
|         Err(NoDefinition) |         Err(NoDefinition) | ||||||
|     } |     } | ||||||
|  |     
 | ||||||
|  |     pub fn resolve_usable_by_fqn( | ||||||
|  |         &self, | ||||||
|  |         fqn: &str | ||||||
|  |     ) -> Result<Symbol, SymbolLookupError> { | ||||||
|  |         todo!() | ||||||
|  |     } | ||||||
|  |     
 | ||||||
|  |     pub fn resolve_usable_star( | ||||||
|  |         &self, | ||||||
|  |         base_fqn: &str, | ||||||
|  |     ) -> Result<(), SymbolLookupError> { | ||||||
|  |         todo!() | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Display for SymbolTable { | impl Display for SymbolTable { | ||||||
|  | |||||||
							
								
								
									
										11
									
								
								src/name_analysis/util.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/name_analysis/util.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | |||||||
|  | use crate::ast::node::UseStatement; | ||||||
|  | 
 | ||||||
|  | pub fn use_statement_base_fqn( | ||||||
|  |     use_statement: &UseStatement | ||||||
|  | ) -> String { | ||||||
|  |     use_statement | ||||||
|  |         .prefixes() | ||||||
|  |         .map(|prefix| prefix.identifier().name()) | ||||||
|  |         .collect::<Vec<_>>() | ||||||
|  |         .join("::") | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Jesse Brault
						Jesse Brault