Compare commits
	
		
			No commits in common. "eda25307b06e6f94be511a5093586316da9ac36c" and "d5ac6dfc2d2a1319371b193e5b6e75c4077ac781" have entirely different histories.
		
	
	
		
			eda25307b0
			...
			d5ac6dfc2d
		
	
		
| @ -1,48 +1,37 @@ | ||||
| use crate::spec::tree_enum_spec::{ | ||||
|     EnumRuleChildKind, TreeEnumBuildSpec, TreeEnumRule, | ||||
| }; | ||||
| use convert_case::{Case, Casing}; | ||||
| use proc_macro2::{Ident, TokenStream}; | ||||
| use crate::spec::tree_enum_spec::{EnumRuleChildKind, TreeEnumBuildSpec}; | ||||
| use proc_macro2::TokenStream; | ||||
| use quote::{format_ident, quote}; | ||||
| 
 | ||||
| fn make_match_arm(rule: &TreeEnumRule, type_ident: &Ident, is_mut: bool) -> TokenStream { | ||||
|     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)); | ||||
|                 let as_node_ref_ident = if is_mut { | ||||
|                     quote! { as_node_ref_mut } | ||||
|                 } else { | ||||
|                     quote! { as_node_ref } | ||||
|                 }; | ||||
|                 quote! { | ||||
|                     #type_ident::#rule_ident(#child_ident) => vec![ | ||||
|                         #child_ident.#as_node_ref_ident() | ||||
|                     ] | ||||
|                 } | ||||
|             } | ||||
|             _ => quote! { | ||||
|                 #type_ident::#rule_ident(_) => vec![] | ||||
|             }, | ||||
|         }, | ||||
|         None => { | ||||
|             quote! { | ||||
|                 #type_ident::#rule_ident => vec![] | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub fn make_enum_ast_node_impl(enum_spec: &TreeEnumBuildSpec) -> TokenStream { | ||||
|     let type_ident = format_ident!("{}", enum_spec.build()); | ||||
|     let match_arms = enum_spec | ||||
|         .rules() | ||||
|         .map(|rule| make_match_arm(rule, &type_ident, false)) | ||||
|         .collect::<Vec<_>>(); | ||||
|     let match_arms_mut = enum_spec | ||||
|         .rules() | ||||
|         .map(|rule| make_match_arm(rule, &type_ident, true)) | ||||
|         .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) => vec![ | ||||
|                                     #child_ident.as_node_ref() | ||||
|                                 ] | ||||
|                             } | ||||
|                         } | ||||
|                         _ => quote! { | ||||
|                             #type_ident::#rule_ident(_) => vec![] | ||||
|                         } | ||||
|                     } | ||||
|                 }, | ||||
|                 None => { | ||||
|                     quote! { | ||||
|                         #type_ident::#rule_ident => vec![] | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }) | ||||
|         .collect::<Vec<_>>(); | ||||
|     
 | ||||
|     quote! { | ||||
| @ -53,19 +42,9 @@ pub fn make_enum_ast_node_impl(enum_spec: &TreeEnumBuildSpec) -> TokenStream { | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             fn children_mut(&mut self) -> Vec<AstNodeRefMut> { | ||||
|                 match self { | ||||
|                     #(#match_arms_mut,)* | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             fn as_node_ref(&self) -> AstNodeRef { | ||||
|                 AstNodeRef::#type_ident(&self) | ||||
|             } | ||||
| 
 | ||||
|             fn as_node_ref_mut(&mut self) -> AstNodeRefMut { | ||||
|                 AstNodeRefMut::#type_ident(self) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| use crate::spec::leaf_enum_spec::LeafEnumBuildSpec; | ||||
| use proc_macro2::TokenStream; | ||||
| use quote::{format_ident, quote}; | ||||
| use crate::spec::leaf_enum_spec::LeafEnumBuildSpec; | ||||
| 
 | ||||
| pub fn make_leaf_enum_ast_node_impl(spec: &LeafEnumBuildSpec) -> TokenStream { | ||||
|     let type_ident = format_ident!("{}", spec.build()); | ||||
| @ -10,17 +10,9 @@ pub fn make_leaf_enum_ast_node_impl(spec: &LeafEnumBuildSpec) -> TokenStream { | ||||
|                 vec![] | ||||
|             } | ||||
|             
 | ||||
|             fn children_mut(&mut self) -> Vec<AstNodeRefMut> { | ||||
|                 vec![] | ||||
|             } | ||||
| 
 | ||||
|             fn as_node_ref(&self) -> AstNodeRef { | ||||
|                 AstNodeRef::#type_ident(&self) | ||||
|             } | ||||
| 
 | ||||
|             fn as_node_ref_mut(&mut self) -> AstNodeRefMut { | ||||
|                 AstNodeRefMut::#type_ident(self) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -10,17 +10,9 @@ pub fn make_leaf_struct_ast_node_impl(spec: &LeafStructBuildSpec) -> TokenStream | ||||
|                 vec![] | ||||
|             } | ||||
|             
 | ||||
|             fn children_mut(&mut self) -> Vec<AstNodeRefMut> { | ||||
|                 vec![] | ||||
|             } | ||||
| 
 | ||||
|             fn as_node_ref(&self) -> AstNodeRef { | ||||
|                 AstNodeRef::#type_ident(&self) | ||||
|             } | ||||
| 
 | ||||
|             fn as_node_ref_mut(&mut self) -> AstNodeRefMut { | ||||
|                 AstNodeRefMut::#type_ident(self) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,47 +1,63 @@ | ||||
| mod enum_ast_node; | ||||
| mod leaf_enum_ast_node; | ||||
| mod leaf_struct_ast_node; | ||||
| mod polymorphic_enum_loop_ast_node; | ||||
| mod polymorphic_type_ast_node; | ||||
| mod struct_ast_node; | ||||
| mod leaf_struct_ast_node; | ||||
| mod polymorphic_type_ast_node; | ||||
| mod polymorphic_enum_loop_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::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::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::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> { | ||||
|     match build_spec { | ||||
|         BuildSpec::Enum(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::LeafStruct(leaf_struct) => Some(make_leaf_struct_ast_node_impl(leaf_struct)), | ||||
|         BuildSpec::Enum(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::LeafStruct(leaf_struct) => { | ||||
|             Some(make_leaf_struct_ast_node_impl(leaf_struct)) | ||||
|         } | ||||
|         BuildSpec::Production(_) => None, | ||||
|         BuildSpec::NodeProduction(_) => None, | ||||
|         BuildSpec::PolymorphicType(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::PolymorphicEnumLoop(polymorphic_enum_loop) => { | ||||
|             Some(make_polymorphic_enum_loop_ast_node_impl(polymorphic_enum_loop)) | ||||
|         } | ||||
|         BuildSpec::PolymorphicPassThrough(_) => None, | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn make_ast_enum_ident(build_spec: &BuildSpec) -> Option<Ident> { | ||||
| pub fn make_ast_enum_member(build_spec: &BuildSpec) -> Option<TokenStream> { 
 | ||||
|     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::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) => { | ||||
|             Some(format_ident!("{}", polymorphic_enum_loop.name())) | ||||
|         } | ||||
| @ -49,20 +65,9 @@ fn make_ast_enum_ident(build_spec: &BuildSpec) -> Option<Ident> { | ||||
|         BuildSpec::Production(_) => None, | ||||
|         BuildSpec::NodeProduction(_) => None, | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub fn make_ast_enum_member(build_spec: &BuildSpec) -> Option<TokenStream> { | ||||
|     make_ast_enum_ident(build_spec).map(|type_ident| { | ||||
|         quote! { | ||||
|             #type_ident(&'a #type_ident) | ||||
|         } | ||||
|     }) | ||||
| } | ||||
| 
 | ||||
| pub fn make_ast_enum_member_mut(build_spec: &BuildSpec) -> Option<TokenStream> { | ||||
|     make_ast_enum_ident(build_spec).map(|type_ident| { | ||||
|         quote! { | ||||
|             #type_ident(&'a mut #type_ident) | ||||
|         } | ||||
|     }) | ||||
|         .map(|type_ident| { | ||||
|             quote! { | ||||
|                 #type_ident(&'a #type_ident) | ||||
|             } | ||||
|         }) | ||||
| } | ||||
| @ -4,33 +4,6 @@ use crate::spec::polymorphic_enum_loop_spec::{ | ||||
| use proc_macro2::TokenStream; | ||||
| use quote::{format_ident, quote}; | ||||
| 
 | ||||
| fn make_child_adder(child: &PolymorphicEnumLoopRuleBuildChild, is_mut: bool) -> TokenStream { | ||||
|     let child_ident = { | ||||
|         let base = match child { | ||||
|             PolymorphicEnumLoopRuleBuildChild::UseCurrent(use_current) => { | ||||
|                 format_ident!("{}", use_current.name()) | ||||
|             } | ||||
|             PolymorphicEnumLoopRuleBuildChild::OnEach(on_each) => { | ||||
|                 format_ident!("{}", on_each.name()) | ||||
|             } | ||||
|         }; | ||||
|         if is_mut { | ||||
|             format_ident!("{}_mut", base) | ||||
|         } else { | ||||
|             base | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     let as_node_ref_ident = if is_mut { | ||||
|         quote! { as_node_ref_mut } | ||||
|     } else { | ||||
|         quote! { as_node_ref } | ||||
|     }; | ||||
|     quote! { | ||||
|         children.push(self.#child_ident().#as_node_ref_ident()); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub fn make_polymorphic_enum_loop_ast_node_impl( | ||||
|     spec: &PolymorphicEnumLoopBuildSpec, | ||||
| ) -> TokenStream { | ||||
| @ -45,12 +18,19 @@ pub fn make_polymorphic_enum_loop_ast_node_impl( | ||||
|         .unwrap(); | ||||
|     let child_adders = build_rule | ||||
|         .children() | ||||
|         .map(|child| make_child_adder(child, false)) | ||||
|         .collect::<Vec<_>>(); | ||||
| 
 | ||||
|     let child_adders_mut = build_rule | ||||
|         .children() | ||||
|         .map(|child| make_child_adder(child, true)) | ||||
|         .map(|child| { | ||||
|             let child_ident = match child { | ||||
|                 PolymorphicEnumLoopRuleBuildChild::UseCurrent(use_current) => { | ||||
|                     format_ident!("{}", use_current.name()) | ||||
|                 } | ||||
|                 PolymorphicEnumLoopRuleBuildChild::OnEach(on_each) => { | ||||
|                     format_ident!("{}", on_each.name()) | ||||
|                 } | ||||
|             }; | ||||
|             quote! { | ||||
|                 children.push(self.#child_ident().as_node_ref()) | ||||
|             } | ||||
|         }) | ||||
|         .collect::<Vec<_>>(); | ||||
| 
 | ||||
|     quote! { | ||||
| @ -61,19 +41,9 @@ pub fn make_polymorphic_enum_loop_ast_node_impl( | ||||
|                 children | ||||
|             } | ||||
| 
 | ||||
|             fn children_mut(&mut self) -> Vec<AstNodeRefMut> { | ||||
|                 let mut children: Vec<AstNodeRefMut> = vec![]; | ||||
|                 #(#child_adders_mut;)* | ||||
|                 children | ||||
|             } | ||||
| 
 | ||||
|             fn as_node_ref(&self) -> AstNodeRef { | ||||
|                 AstNodeRef::#type_ident(&self) | ||||
|             } | ||||
| 
 | ||||
|             fn as_node_ref_mut(&mut self) -> AstNodeRefMut { | ||||
|                 AstNodeRefMut::#type_ident(self) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,36 +1,19 @@ | ||||
| use crate::spec::polymorphic_type_spec::{PolymorphicTypeBuildSpec, PolymorphicTypeVariant}; | ||||
| use crate::spec::polymorphic_type_spec::PolymorphicTypeBuildSpec; | ||||
| use convert_case::{Case, Casing}; | ||||
| use proc_macro2::{Ident, TokenStream}; | ||||
| use proc_macro2::TokenStream; | ||||
| use quote::{format_ident, quote}; | ||||
| 
 | ||||
| fn make_match_arm( | ||||
|     variant: &PolymorphicTypeVariant, | ||||
|     type_ident: &Ident, | ||||
|     is_mut: bool, | ||||
| ) -> TokenStream { | ||||
|     let variant_ident = format_ident!("{}", variant.name()); | ||||
|     let child_ident = format_ident!("{}", variant.inner_kind().to_case(Case::Snake)); | ||||
|     let as_node_ref_ident = if is_mut { | ||||
|         quote! { as_node_ref_mut } | ||||
|     } else { | ||||
|         quote! { as_node_ref } | ||||
|     }; | ||||
| 
 | ||||
|     quote! { | ||||
|         #type_ident::#variant_ident(#child_ident) => vec![#child_ident.#as_node_ref_ident()] | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub fn make_polymorphic_type_ast_node_impl(spec: &PolymorphicTypeBuildSpec) -> TokenStream { | ||||
|     let type_ident = format_ident!("{}", spec.name()); | ||||
|     let match_arms = spec | ||||
|         .variants() | ||||
|         .map(|variant| make_match_arm(variant, &type_ident, false)) | ||||
|         .collect::<Vec<_>>(); | ||||
| 
 | ||||
|     let match_arms_mut = spec | ||||
|         .variants() | ||||
|         .map(|variant| make_match_arm(variant, &type_ident, true)) | ||||
|         .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) => vec![#child_ident.as_node_ref()] | ||||
|             } | ||||
|         }) | ||||
|         .collect::<Vec<_>>(); | ||||
| 
 | ||||
|     quote! { | ||||
| @ -41,19 +24,9 @@ pub fn make_polymorphic_type_ast_node_impl(spec: &PolymorphicTypeBuildSpec) -> T | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             fn children_mut(&mut self) -> Vec<AstNodeRefMut> { | ||||
|                 match self { | ||||
|                     #(#match_arms_mut,)* | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             fn as_node_ref(&self) -> AstNodeRef { | ||||
|                 AstNodeRef::#type_ident(&self) | ||||
|             } | ||||
| 
 | ||||
|             fn as_node_ref_mut(&mut self) -> AstNodeRefMut { | ||||
|                 AstNodeRefMut::#type_ident(self) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -2,69 +2,43 @@ use crate::spec::struct_spec::{MemberChildBuild, StructChild, StructSpec, VecChi | ||||
| use proc_macro2::TokenStream; | ||||
| use quote::{format_ident, quote}; | ||||
| 
 | ||||
| fn make_child_adder(child: &StructChild, is_mut: bool) -> Option<TokenStream> { | ||||
|     let as_node_ref_ident = if is_mut { | ||||
|         format_ident!("as_node_ref_mut") | ||||
|     } else { | ||||
|         format_ident!("as_node_ref") | ||||
|     }; | ||||
| 
 | ||||
|     match child { | ||||
|         StructChild::SkipChild(_) => None, | ||||
|         StructChild::VecChild(vec_child) => match vec_child.build() { | ||||
|             VecChildBuild::String(_) => None, | ||||
|             VecChildBuild::Node(_) => { | ||||
|                 let child_ident = if is_mut { | ||||
|                     format_ident!("{}_mut", vec_child.name()) | ||||
|                 } else { | ||||
|                     format_ident!("{}", vec_child.name()) | ||||
|                 }; | ||||
| 
 | ||||
|                 let children_stream = quote! { | ||||
|                     for child in self.#child_ident().map(AstNode::#as_node_ref_ident) { | ||||
|                         children.push(child); | ||||
|                     } | ||||
|                 }; | ||||
|                 Some(children_stream) | ||||
|             } | ||||
|         }, | ||||
|         StructChild::MemberChild(member_child) => match member_child.build() { | ||||
|             MemberChildBuild::Node(_) => { | ||||
|                 let child_ident = if is_mut { | ||||
|                     format_ident!("{}_mut", member_child.name()) | ||||
|                 } else { | ||||
|                     format_ident!("{}", member_child.name()) | ||||
|                 }; | ||||
|                 if member_child.optional() { | ||||
|                     Some(quote! { | ||||
|                         if let Some(#child_ident) = self.#child_ident() { | ||||
|                             children.push(#child_ident.#as_node_ref_ident()); | ||||
|                         } | ||||
|                     }) | ||||
|                 } else { | ||||
|                     Some(quote! { | ||||
|                         children.push(self.#child_ident().#as_node_ref_ident()); | ||||
|                     }) | ||||
|                 } | ||||
|             } | ||||
|             MemberChildBuild::Boolean(_) => None, | ||||
|         }, | ||||
|         StructChild::Special(_) => None, | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub fn make_struct_ast_node_impl(spec: &StructSpec) -> TokenStream { | ||||
|     let type_ident = format_ident!("{}", spec.build()); | ||||
|     let child_adders = spec | ||||
|         .children() | ||||
|         .map(|child| make_child_adder(child, false)) | ||||
|         .filter(Option::is_some) | ||||
|         .map(Option::unwrap) | ||||
|         .collect::<Vec<_>>(); | ||||
| 
 | ||||
|     let child_adders_mut = spec | ||||
|         .children() | ||||
|         .map(|child| make_child_adder(child, true)) | ||||
|         .map(|child| match child { | ||||
|             StructChild::SkipChild(_) => None, | ||||
|             StructChild::VecChild(vec_child) => match vec_child.build() { | ||||
|                 VecChildBuild::String(_) => None, | ||||
|                 VecChildBuild::Node(_) => { | ||||
|                     let child_ident = format_ident!("{}", vec_child.name()); | ||||
|                     let children_stream = quote! { | ||||
|                         for child in self.#child_ident().map(AstNode::as_node_ref) { | ||||
|                             children.push(child); | ||||
|                         } | ||||
|                     }; | ||||
|                     Some(children_stream) | ||||
|                 } | ||||
|             }, | ||||
|             StructChild::MemberChild(member_child) => match member_child.build() { | ||||
|                 MemberChildBuild::Node(_) => { | ||||
|                     let child_ident = format_ident!("{}", member_child.name()); | ||||
|                     if member_child.optional() { | ||||
|                         Some(quote! { | ||||
|                             if let Some(#child_ident) = self.#child_ident() { | ||||
|                                 children.push(#child_ident.as_node_ref()); | ||||
|                             } | ||||
|                         }) | ||||
|                     } else { | ||||
|                         Some(quote! { | ||||
|                             children.push(self.#child_ident().as_node_ref()) | ||||
|                         }) | ||||
|                     } | ||||
|                 } | ||||
|                 MemberChildBuild::Boolean(_) => None, | ||||
|             }, | ||||
|             StructChild::Special(_) => None, | ||||
|         }) | ||||
|         .filter(Option::is_some) | ||||
|         .map(Option::unwrap) | ||||
|         .collect::<Vec<_>>(); | ||||
| @ -77,19 +51,9 @@ pub fn make_struct_ast_node_impl(spec: &StructSpec) -> TokenStream { | ||||
|                 children | ||||
|             } | ||||
| 
 | ||||
|             fn children_mut(&mut self) -> Vec<AstNodeRefMut> { | ||||
|                 let mut children: Vec<AstNodeRefMut> = vec![]; | ||||
|                 #(#child_adders_mut;)* | ||||
|                 children | ||||
|             } | ||||
| 
 | ||||
|             fn as_node_ref(&self) -> AstNodeRef { | ||||
|                 AstNodeRef::#type_ident(&self) | ||||
|             } | ||||
| 
 | ||||
|             fn as_node_ref_mut(&mut self) -> AstNodeRefMut { | ||||
|                 AstNodeRefMut::#type_ident(self) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,8 +1,5 @@ | ||||
| use crate::deserialize::util::{make_build_fn_name, make_build_pair}; | ||||
| use crate::spec::struct_spec::{ | ||||
|     MemberChildBuild, NodeMemberBuild, SpecialChild, SpecialChildKind, StructChild, StructSpec, | ||||
|     VecChild, VecChildBuild, | ||||
| }; | ||||
| use crate::spec::struct_spec::{MemberChildBuild, NodeMemberBuild, SpecialChild, SpecialChildKind, StructChild, StructSpec, VecChild, VecChildBuild}; | ||||
| use proc_macro2::{Ident, TokenStream}; | ||||
| use quote::{format_ident, quote}; | ||||
| 
 | ||||
| @ -128,7 +125,7 @@ fn make_rule_matcher(child_spec: &StructChild) -> Option<TokenStream> { | ||||
|             Some(quote! { | ||||
|                 Rule::#rule_ident => {} | ||||
|             }) | ||||
|         } | ||||
|         }, | ||||
|         StructChild::VecChild(vec_child) => { | ||||
|             let rule_ident = format_ident!("{}", vec_child.rule()); | ||||
|             let action = make_vec_child_match_action(vec_child); | ||||
| @ -136,24 +133,28 @@ fn make_rule_matcher(child_spec: &StructChild) -> Option<TokenStream> { | ||||
|                 Rule::#rule_ident => { #action } | ||||
|             }) | ||||
|         } | ||||
|         StructChild::MemberChild(member_child) => match member_child.build() { | ||||
|             MemberChildBuild::Node(node_member_build) => { | ||||
|                 let rule_ident = format_ident!("{}", member_child.rule()); | ||||
|                 let action = | ||||
|                     make_node_member_child_match_action(member_child.name(), node_member_build); | ||||
|                 Some(quote! { | ||||
|                     Rule::#rule_ident => { #action } | ||||
|                 }) | ||||
|             } | ||||
|             MemberChildBuild::Boolean(_) => { | ||||
|                 let rule_ident = format_ident!("{}", member_child.rule()); | ||||
|                 let action = make_boolean_member_child_match_action(member_child.name()); | ||||
|                 Some(quote! { | ||||
|                     Rule::#rule_ident => { #action } | ||||
|                 }) | ||||
|         StructChild::MemberChild(member_child) => { | ||||
|             match member_child.build() { | ||||
|                 MemberChildBuild::Node(node_member_build) => { | ||||
|                     let rule_ident = format_ident!("{}", member_child.rule()); | ||||
|                     let action = make_node_member_child_match_action( | ||||
|                         member_child.name(), | ||||
|                         node_member_build | ||||
|                     ); | ||||
|                     Some(quote! { | ||||
|                         Rule::#rule_ident => { #action } | ||||
|                     }) | ||||
|                 } | ||||
|                 MemberChildBuild::Boolean(_) => { | ||||
|                     let rule_ident = format_ident!("{}", member_child.rule()); | ||||
|                     let action = make_boolean_member_child_match_action(member_child.name()); | ||||
|                     Some(quote! { | ||||
|                         Rule::#rule_ident => { #action } | ||||
|                     }) | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         StructChild::Special(_) => None, | ||||
|         StructChild::Special(_) => None | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -191,7 +192,7 @@ fn make_special_child_arg(special_child: &SpecialChild) -> TokenStream { | ||||
|     quote! { #child_ident } | ||||
| } | ||||
| 
 | ||||
| fn make_child_arg(child_spec: &StructChild) -> Option<TokenStream> { | ||||
| fn make_child_arg(child_spec: &StructChild, pair_ident: &Ident) -> Option<TokenStream> { | ||||
|     match child_spec { | ||||
|         StructChild::SkipChild(_) => None, | ||||
|         StructChild::VecChild(vec_child) => Some(make_vec_child_arg(vec_child)), | ||||
| @ -203,7 +204,7 @@ fn make_child_arg(child_spec: &StructChild) -> Option<TokenStream> { | ||||
|             )), | ||||
|             MemberChildBuild::Boolean(_) => { | ||||
|                 Some(make_boolean_member_child_arg(member_child.name())) | ||||
|             } | ||||
|             }, | ||||
|         }, | ||||
|         StructChild::Special(special_child) => Some(make_special_child_arg(special_child)), | ||||
|     } | ||||
| @ -213,7 +214,7 @@ fn make_return_value_stream(build_spec: &StructSpec, pair_ident: &Ident) -> Toke | ||||
|     let type_ident = format_ident!("{}", build_spec.build()); | ||||
|     let child_args = build_spec | ||||
|         .children() | ||||
|         .map(|child| make_child_arg(child)) | ||||
|         .map(|child| make_child_arg(child, pair_ident)) | ||||
|         .filter(|child_arg| child_arg.is_some()) | ||||
|         .map(|child_arg| child_arg.unwrap()) | ||||
|         .collect::<Vec<_>>(); | ||||
|  | ||||
| @ -5,23 +5,6 @@ use crate::deserialize::util::{get_as_bool, make_build_fn_name, unwrap_single_me | ||||
| use crate::spec::struct_spec::*; | ||||
| use yaml_rust2::Yaml; | ||||
| 
 | ||||
| fn deserialize_fields(fields: &Yaml) -> Vec<Box<StructField>> { | ||||
|     fields | ||||
|         .as_vec() | ||||
|         .unwrap() | ||||
|         .iter() | ||||
|         .map(|field| unwrap_single_member_hash(field)) | ||||
|         .map(|(name, props)| { | ||||
|             let kind = match props["kind"].as_str().unwrap() { | ||||
|                 "usize" => StructFieldKind::USize, | ||||
|                 _ => panic!() | ||||
|             }; | ||||
|             StructField::new(&name, kind, get_as_bool(&props["optional"])) | ||||
|         }) | ||||
|         .map(Box::new) | ||||
|         .collect() | ||||
| } | ||||
| 
 | ||||
| fn deserialize_skip_child(props: &Yaml) -> StructChild { | ||||
|     let rule = props["rule"].as_str().unwrap(); | ||||
|     StructChild::SkipChild(SkipChild::new(rule)) | ||||
| @ -113,11 +96,7 @@ fn deserialize_special_child(name: &str, props: &Yaml) -> StructChild { | ||||
|     match props["kind"].as_str().unwrap() { | ||||
|         "file_id" => StructChild::Special(SpecialChild::new(name, SpecialChildKind::FileId)), | ||||
|         "range" => StructChild::Special(SpecialChild::new(name, SpecialChildKind::Range)), | ||||
|         _ => panic!( | ||||
|             "Invalid special child kind {} in {}", | ||||
|             props["kind"].as_str().unwrap(), | ||||
|             name | ||||
|         ), | ||||
|         _ => panic!("Invalid special child kind {} in {}", props["kind"].as_str().unwrap(), name), | ||||
|     }    
 | ||||
| } | ||||
| 
 | ||||
| @ -172,11 +151,5 @@ pub fn deserialize_struct_spec(name: &str, struct_yaml: &Yaml) -> StructSpec { | ||||
|     } else { | ||||
|         deserialize_error!("array", "children", name); | ||||
|     }; | ||||
|     let fields = if struct_yaml["fields"].is_array() { | ||||
|         deserialize_fields(&struct_yaml["fields"]) | ||||
|     } else { | ||||
|         vec![] | ||||
|     }; | ||||
| 
 | ||||
|     StructSpec::new(name, children, fields) | ||||
|     StructSpec::new(name, children) | ||||
| } | ||||
|  | ||||
| @ -6,7 +6,7 @@ mod spec; | ||||
| mod type_gen; | ||||
| mod walk; | ||||
| 
 | ||||
| use crate::ast_node::{make_ast_enum_member, make_ast_enum_member_mut, make_ast_node_impl}; | ||||
| use crate::ast_node::{make_ast_enum_member, make_ast_node_impl}; | ||||
| use crate::build_fn::make_build_fn; | ||||
| use crate::deserialize::deserialize_yaml_spec; | ||||
| use crate::pretty_print::make_pretty_print_impl; | ||||
| @ -165,13 +165,6 @@ fn generate_ast_node_file(build_specs: &[BuildSpec]) -> AstGeneratedFile { | ||||
|         .map(Option::unwrap) | ||||
|         .collect::<Vec<_>>(); | ||||
| 
 | ||||
|     let ast_enum_members_mut = build_specs | ||||
|         .iter() | ||||
|         .map(|build_spec| make_ast_enum_member_mut(build_spec)) | ||||
|         .filter(Option::is_some) | ||||
|         .map(Option::unwrap) | ||||
|         .collect::<Vec<_>>(); | ||||
| 
 | ||||
|     let combined = quote! { | ||||
|         use crate::ast::node::*; | ||||
| 
 | ||||
| @ -179,18 +172,10 @@ fn generate_ast_node_file(build_specs: &[BuildSpec]) -> AstGeneratedFile { | ||||
|             #(#ast_enum_members,)* | ||||
|         } | ||||
| 
 | ||||
|         pub enum AstNodeRefMut<'a> { | ||||
|             #(#ast_enum_members_mut,)* | ||||
|         } | ||||
| 
 | ||||
|         pub trait AstNode { | ||||
|             fn children(&self) -> Vec<AstNodeRef>; | ||||
| 
 | ||||
|             fn children_mut(&mut self) -> Vec<AstNodeRefMut>; | ||||
| 
 | ||||
|             fn as_node_ref(&self) -> AstNodeRef; | ||||
| 
 | ||||
|             fn as_node_ref_mut(&mut self) -> AstNodeRefMut; | ||||
|         } | ||||
| 
 | ||||
|         #(#impls)* | ||||
|  | ||||
| @ -1,19 +1,13 @@ | ||||
| pub struct StructSpec { | ||||
|     build: String, | ||||
|     children: Vec<Box<StructChild>>, | ||||
|     fields: Vec<Box<StructField>>, | ||||
| } | ||||
| 
 | ||||
| impl StructSpec { | ||||
|     pub fn new( | ||||
|         build: &str, | ||||
|         children: Vec<Box<StructChild>>, | ||||
|         fields: Vec<Box<StructField>>, | ||||
|     ) -> Self { | ||||
|     pub fn new(build: &str, children: Vec<Box<StructChild>>) -> Self { | ||||
|         Self { | ||||
|             build: build.to_string(), | ||||
|             children, | ||||
|             fields, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @ -26,10 +20,6 @@ impl StructSpec { | ||||
|     pub fn children(&self) -> impl Iterator<Item = &StructChild> { | ||||
|         self.children.iter().map(Box::as_ref) | ||||
|     } | ||||
| 
 | ||||
|     pub fn fields(&self) -> impl Iterator<Item = &StructField> { | ||||
|         self.fields.iter().map(Box::as_ref) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub enum StructChild { | ||||
| @ -49,8 +39,10 @@ impl StructChild { | ||||
|     
 | ||||
|     pub fn unwrap_special(&self) -> Option<&SpecialChild> { | ||||
|         match self { | ||||
|             StructChild::Special(special_child) => Some(special_child), | ||||
|             _ => None, | ||||
|             StructChild::Special(special_child) => { | ||||
|                 Some(special_child) | ||||
|             }, | ||||
|             _ => None | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -250,7 +242,7 @@ impl SpecialChild { | ||||
|     pub fn new(name: &str, kind: SpecialChildKind) -> Self { | ||||
|         Self { | ||||
|             name: name.to_string(), | ||||
|             kind, | ||||
|             kind | ||||
|         } | ||||
|     } | ||||
|     
 | ||||
| @ -268,35 +260,3 @@ pub enum SpecialChildKind { | ||||
|     FileId, | ||||
|     Range, | ||||
| } | ||||
| 
 | ||||
| pub struct StructField { | ||||
|     name: String, | ||||
|     kind: StructFieldKind, | ||||
|     optional: bool, | ||||
| } | ||||
| 
 | ||||
| impl StructField { | ||||
|     pub fn new(name: &str, kind: StructFieldKind, optional: bool) -> Self { | ||||
|         Self { | ||||
|             name: name.to_string(), | ||||
|             kind, | ||||
|             optional, | ||||
|         } | ||||
|     } | ||||
|     
 | ||||
|     pub fn name(&self) -> &str { | ||||
|         &self.name | ||||
|     } | ||||
|     
 | ||||
|     pub fn kind(&self) -> &StructFieldKind { | ||||
|         &self.kind | ||||
|     } | ||||
|     
 | ||||
|     pub fn optional(&self) -> bool { | ||||
|         self.optional | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub enum StructFieldKind { | ||||
|     USize, | ||||
| } | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| use crate::spec::struct_spec::{ | ||||
|     MemberChild, MemberChildBuild, SpecialChild, SpecialChildKind, StructChild, StructField, | ||||
|     StructFieldKind, StructSpec, VecChild, VecChildBuild, | ||||
|     MemberChild, MemberChildBuild, SpecialChild, SpecialChildKind, StructChild, StructSpec, | ||||
|     VecChild, VecChildBuild, | ||||
| }; | ||||
| use proc_macro2::{Ident, TokenStream}; | ||||
| use quote::{format_ident, quote}; | ||||
| @ -99,7 +99,7 @@ fn make_special_child_accessors(special_child: &SpecialChild) -> TokenStream { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn make_child_accessors(child: &StructChild) -> Option<TokenStream> { | ||||
| fn make_accessors(child: &StructChild) -> Option<TokenStream> { | ||||
|     match child { | ||||
|         StructChild::SkipChild(_) => None, | ||||
|         StructChild::VecChild(vec_child) => Some(make_vec_child_accessors(vec_child)), | ||||
| @ -182,68 +182,15 @@ fn make_annotated_member(child: &StructChild) -> Option<TokenStream> { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn make_annotated_field(field: &StructField) -> TokenStream { | ||||
|     let field_ident = format_ident!("{}", field.name()); | ||||
|     let field_type_ident = match field.kind() { | ||||
|         StructFieldKind::USize => quote! { usize }, | ||||
|     }; | ||||
|     if field.optional() { | ||||
|         quote! { | ||||
|             #field_ident: Option<#field_type_ident> | ||||
|         } | ||||
|     } else { | ||||
|         quote! { | ||||
|             #field_ident: #field_type_ident | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn make_field_init(field: &StructField) -> TokenStream { | ||||
|     let field_ident = format_ident!("{}", field.name()); | ||||
|     if field.optional() { | ||||
|         quote! { | ||||
|             #field_ident: None | ||||
|         } | ||||
|     } else { | ||||
|         todo!() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn make_field_accessors(field: &StructField) -> TokenStream { | ||||
|     let field_ident = format_ident!("{}", field.name()); | ||||
|     let field_type_ident = match field.kind() { | ||||
|         StructFieldKind::USize => quote! { usize }, | ||||
|     }; | ||||
|     if field.optional() { | ||||
|         let setter_ident = format_ident!("set_{}", field.name()); | ||||
|         quote! { | ||||
|             pub fn #field_ident(&self) -> Option<#field_type_ident> { | ||||
|                 self.#field_ident | ||||
|             } | ||||
| 
 | ||||
|             pub fn #setter_ident(&mut self, #field_ident: #field_type_ident) { | ||||
|                 self.#field_ident = Some(#field_ident); | ||||
|             } | ||||
|         } | ||||
|     } else { | ||||
|         todo!() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub fn make_struct_type(build_spec: &StructSpec) -> TokenStream { | ||||
|     let type_ident = format_ident!("{}", build_spec.build()); | ||||
|     let annotated_children = build_spec | ||||
|     let annotated_members = build_spec | ||||
|         .children() | ||||
|         .map(|child| make_annotated_member(child)) | ||||
|         .filter(Option::is_some) | ||||
|         .map(Option::unwrap) | ||||
|         .collect::<Vec<_>>(); | ||||
| 
 | ||||
|     let annotated_fields = build_spec | ||||
|         .fields() | ||||
|         .map(|field| make_annotated_field(field)) | ||||
|         .collect::<Vec<_>>(); | ||||
| 
 | ||||
|     let member_names = build_spec | ||||
|         .children() | ||||
|         .map(|child| make_member_ident(child)) | ||||
| @ -251,39 +198,26 @@ pub fn make_struct_type(build_spec: &StructSpec) -> TokenStream { | ||||
|         .map(Option::unwrap) | ||||
|         .collect::<Vec<_>>(); | ||||
| 
 | ||||
|     let field_inits = build_spec | ||||
|         .fields() | ||||
|         .map(|field| make_field_init(field)) | ||||
|         .collect::<Vec<_>>(); | ||||
| 
 | ||||
|     let child_accessors = build_spec | ||||
|     let accessors = build_spec | ||||
|         .children() | ||||
|         .map(|child| make_child_accessors(child)) | ||||
|         .map(|child| make_accessors(child)) | ||||
|         .filter(Option::is_some) | ||||
|         .map(Option::unwrap) | ||||
|         .collect::<Vec<_>>(); | ||||
| 
 | ||||
|     let field_accessors = build_spec | ||||
|         .fields() | ||||
|         .map(|field| make_field_accessors(field)) | ||||
|         .collect::<Vec<_>>(); | ||||
| 
 | ||||
|     quote! { | ||||
|         pub struct #type_ident { | ||||
|             #(#annotated_children,)* | ||||
|             #(#annotated_fields,)* | ||||
|             #(#annotated_members),* | ||||
|         } | ||||
| 
 | ||||
|         impl #type_ident { | ||||
|             pub fn new(#(#annotated_children),*) -> Self { | ||||
|             pub fn new(#(#annotated_members),*) -> Self { | ||||
|                 Self { | ||||
|                     #(#member_names,)* | ||||
|                     #(#field_inits,)* | ||||
|                     #(#member_names),* | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             #(#child_accessors)* | ||||
|             #(#field_accessors)* | ||||
|             #(#accessors)* | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,36 +1,6 @@ | ||||
| pub mod node { | ||||
|     include!(concat!(env!("OUT_DIR"), "/src/ast/node.rs")); | ||||
| 
 | ||||
|     impl OperatorInner { | ||||
|         pub fn name(&self) -> &'static str { | ||||
|             match self { | ||||
|                 OperatorInner::Or => "op_or", | ||||
|                 OperatorInner::And => "op_and", | ||||
|                 OperatorInner::EqualTo => "op_eq", | ||||
|                 OperatorInner::NotEqualTo => "op_neq", | ||||
|                 OperatorInner::Greater => "op_gt", | ||||
|                 OperatorInner::Less => "op_lt", | ||||
|                 OperatorInner::GreaterEqual => "op_ge", | ||||
|                 OperatorInner::LessEqual => "op_le", | ||||
|                 OperatorInner::Add => "op_add", | ||||
|                 OperatorInner::Subtract => "op_sub", | ||||
|                 OperatorInner::Multiply => "op_mul", | ||||
|                 OperatorInner::Divide => "op_div", | ||||
|                 OperatorInner::Modulo => "op_mod", | ||||
|                 OperatorInner::LeftShift => "op_ls", | ||||
|                 OperatorInner::RightShift => "op_rs", | ||||
|                 OperatorInner::Spread => "op_spread", | ||||
|                 OperatorInner::Star => "op_star", | ||||
|                 OperatorInner::Not => "op_not", | ||||
|                 OperatorInner::Negative => "op_neg", | ||||
|                 OperatorInner::PlusPlus => "op_pp", | ||||
|                 OperatorInner::MinusMinus => "op_mm", | ||||
|                 OperatorInner::CallOp => "op_call", | ||||
|                 OperatorInner::Index => "op_index", | ||||
|             } | ||||
|         }    
 | ||||
|     } | ||||
|     
 | ||||
|     impl Default for Parameters { | ||||
|         fn default() -> Self { | ||||
|             Self::new(vec![]) | ||||
|  | ||||
| @ -1,13 +1,10 @@ | ||||
| use crate::ast::ast_node::{AstNode, AstNodeRef}; | ||||
| use crate::ast::node::{ | ||||
|     Class, CompilationUnit, Function, FunctionBody, Identifier, Interface, | ||||
|     InterfaceDefaultFunction, InterfaceDefaultOperatorFunction, InterfaceFunction, | ||||
|     InterfaceOperatorFunction, Member, Module, Namespace, OperatorFunction, PlatformFunction, | ||||
|     PlatformOperatorFunction, UseStatement, UseStatementSuffix, VariableDeclaration, VariableUse, | ||||
|     Class, CompilationUnit, Function, FunctionBlockBody, FunctionBody, Identifier, Interface, | ||||
|     Module, Namespace, Statement, UseStatement, UseStatementSuffix, VariableDeclaration, | ||||
| }; | ||||
| use crate::diagnostic::DmDiagnostic; | ||||
| use crate::name_analysis::fqn_context::FqnContext; | ||||
| use crate::name_analysis::symbol::class_member_symbol::ClassMemberSymbol; | ||||
| use crate::name_analysis::symbol::function_symbol::FunctionSymbol; | ||||
| use crate::name_analysis::symbol::module_symbol::ModuleSymbol; | ||||
| use crate::name_analysis::symbol::source_definition::SourceDefinition; | ||||
| @ -70,14 +67,9 @@ fn gather_node( | ||||
|     diagnostics: &mut Vec<DmDiagnostic>, | ||||
| ) { | ||||
|     match node { | ||||
|         AstNodeRef::Operator(_) => { | ||||
|             unreachable!(); | ||||
|         } | ||||
|         AstNodeRef::OperatorInner(_) => { | ||||
|             unreachable!(); | ||||
|         } | ||||
|         AstNodeRef::Operator(_) => {} | ||||
|         AstNodeRef::Identifier(_) => { | ||||
|             unreachable!(); | ||||
|             unreachable!() | ||||
|         } | ||||
|         AstNodeRef::FullyQualifiedName(_) => {} | ||||
|         AstNodeRef::TypeUseList(_) => {} | ||||
| @ -106,13 +98,13 @@ fn gather_node( | ||||
|             gather_use_statement(use_statement, symbol_table, diagnostics); | ||||
|         } | ||||
|         AstNodeRef::UseStatementPrefix(_) => { | ||||
|             unreachable!(); | ||||
|             unreachable!() | ||||
|         } | ||||
|         AstNodeRef::UseStatementSuffix(_) => { | ||||
|             unreachable!(); | ||||
|             unreachable!() | ||||
|         } | ||||
|         AstNodeRef::UseList(_) => { | ||||
|             unreachable!(); | ||||
|             unreachable!() | ||||
|         } | ||||
|         AstNodeRef::ModuleLevelDeclaration(module_level_declaration) => { | ||||
|             gather_node_children( | ||||
| @ -150,76 +142,62 @@ fn gather_node( | ||||
|         AstNodeRef::Function(function) => { | ||||
|             gather_function(function, symbol_table, fqn_context, diagnostics); | ||||
|         } | ||||
|         AstNodeRef::OperatorFunction(operator_function) => { | ||||
|             gather_operator_function(operator_function, symbol_table, fqn_context, diagnostics); | ||||
|         } | ||||
|         AstNodeRef::PlatformFunction(platform_function) => { | ||||
|             gather_platform_function(platform_function, symbol_table, fqn_context, diagnostics); | ||||
|         } | ||||
|         AstNodeRef::PlatformOperatorFunction(platform_operator_function) => { | ||||
|             gather_platform_operator_function( | ||||
|                 platform_operator_function, | ||||
|                 symbol_table, | ||||
|                 fqn_context, | ||||
|                 diagnostics, | ||||
|             ); | ||||
|         } | ||||
|         AstNodeRef::InterfaceFunction(interface_function) => { | ||||
|             gather_interface_function(interface_function, symbol_table, fqn_context, diagnostics); | ||||
|         } | ||||
|         AstNodeRef::InterfaceDefaultFunction(interface_default_function) => { | ||||
|             gather_interface_default_function( | ||||
|                 interface_default_function, | ||||
|                 symbol_table, | ||||
|                 fqn_context, | ||||
|                 diagnostics, | ||||
|             ); | ||||
|         } | ||||
|         AstNodeRef::InterfaceOperatorFunction(interface_operator_function) => { | ||||
|             gather_interface_operator_function( | ||||
|                 interface_operator_function, | ||||
|                 symbol_table, | ||||
|                 fqn_context, | ||||
|                 diagnostics, | ||||
|             ); | ||||
|         } | ||||
|         AstNodeRef::InterfaceDefaultOperatorFunction(interface_default_operator_function) => { | ||||
|             gather_interface_default_operator_function( | ||||
|                 interface_default_operator_function, | ||||
|                 symbol_table, | ||||
|                 fqn_context, | ||||
|                 diagnostics, | ||||
|             ); | ||||
|         } | ||||
|         AstNodeRef::FunctionBody(function_body) => { | ||||
|             gather_function_body(function_body, symbol_table, fqn_context, diagnostics); | ||||
|         } | ||||
|         AstNodeRef::FunctionEqualsBody(function_equals_body) => { | ||||
|             gather_node_children(function_equals_body, symbol_table, fqn_context, diagnostics); | ||||
|         } | ||||
|         AstNodeRef::FunctionAliasBody(_) => { | ||||
|             // no-op
 | ||||
|         } | ||||
|         AstNodeRef::FunctionBlockBody(function_block_body) => { | ||||
|             gather_node_children(function_block_body, symbol_table, fqn_context, diagnostics); | ||||
|         } | ||||
|         AstNodeRef::ClassConstructor(class_constructor) => { | ||||
|             gather_node_children(class_constructor, symbol_table, fqn_context, diagnostics); | ||||
|         } | ||||
|         AstNodeRef::Member(member) => { | ||||
|             gather_member(member, symbol_table, fqn_context, diagnostics); | ||||
|         } | ||||
|         AstNodeRef::Statement(statement) => { | ||||
|             gather_node_children(statement, symbol_table, fqn_context, diagnostics); | ||||
|         } | ||||
|         AstNodeRef::VariableDeclaration(variable_declaration) => { | ||||
|             gather_variable_declaration( | ||||
|                 variable_declaration, | ||||
|                 symbol_table, | ||||
|                 fqn_context, | ||||
|                 diagnostics, | ||||
|             ); | ||||
|         AstNodeRef::OperatorFunction(_) => {} | ||||
|         AstNodeRef::PlatformFunction(_) => {} | ||||
|         AstNodeRef::InterfaceFunction(_) => {} | ||||
|         AstNodeRef::InterfaceDefaultFunction(_) => {} | ||||
|         AstNodeRef::InterfaceOperatorFunction(_) => {} | ||||
|         AstNodeRef::InterfaceDefaultOperatorFunction(_) => {} | ||||
|         AstNodeRef::FunctionBody(function_body) => match function_body { | ||||
|             FunctionBody::FunctionAliasBody(alias_body) => { | ||||
|                 gather_node( | ||||
|                     alias_body.as_node_ref(), | ||||
|                     symbol_table, | ||||
|                     fqn_context, | ||||
|                     diagnostics, | ||||
|                 ); | ||||
|             } | ||||
|             FunctionBody::FunctionEqualsBody(equals_body) => { | ||||
|                 gather_node( | ||||
|                     equals_body.as_node_ref(), | ||||
|                     symbol_table, | ||||
|                     fqn_context, | ||||
|                     diagnostics, | ||||
|                 ); | ||||
|             } | ||||
|             FunctionBody::FunctionBlockBody(block_body) => { | ||||
|                 gather_node( | ||||
|                     block_body.as_node_ref(), | ||||
|                     symbol_table, | ||||
|                     fqn_context, | ||||
|                     diagnostics, | ||||
|                 ); | ||||
|             } | ||||
|         }, | ||||
|         AstNodeRef::FunctionEqualsBody(_) => {} | ||||
|         AstNodeRef::FunctionAliasBody(_) => {} | ||||
|         AstNodeRef::FunctionBlockBody(block_body) => { | ||||
|             gather_function_block_body(block_body, symbol_table, fqn_context, diagnostics); | ||||
|         } | ||||
|         AstNodeRef::ClassConstructor(_) => {} | ||||
|         AstNodeRef::Member(_) => {} | ||||
|         AstNodeRef::Statement(statement) => match statement { | ||||
|             Statement::VariableDeclaration(variable_declaration) => { | ||||
|                 gather_node( | ||||
|                     variable_declaration.as_node_ref(), | ||||
|                     symbol_table, | ||||
|                     fqn_context, | ||||
|                     diagnostics, | ||||
|                 ); | ||||
|             } | ||||
|             Statement::AssignmentStatement(_) => {} | ||||
|             Statement::ExpressionStatement(_) => {} | ||||
|             Statement::UseStatement(_) => {} | ||||
|             Statement::IfStatement(_) => {} | ||||
|             Statement::WhileStatement(_) => {} | ||||
|             Statement::ForStatement(_) => {} | ||||
|         }, | ||||
|         AstNodeRef::VariableDeclaration(_) => {} | ||||
|         AstNodeRef::AssignmentStatement(_) => {} | ||||
|         AstNodeRef::ExpressionStatement(_) => {} | ||||
|         AstNodeRef::IfStatement(_) => {} | ||||
| @ -228,11 +206,6 @@ fn gather_node( | ||||
|         AstNodeRef::IfElse(_) => {} | ||||
|         AstNodeRef::WhileStatement(_) => {} | ||||
|         AstNodeRef::ForStatement(_) => {} | ||||
|         AstNodeRef::LValue(_) => {} | ||||
|         AstNodeRef::LValueSuffix(_) => {} | ||||
|         AstNodeRef::VariableUse(variable_use) => { | ||||
|             gather_variable_use(variable_use, symbol_table, fqn_context, diagnostics); | ||||
|         } | ||||
|         AstNodeRef::Expression(_) => {} | ||||
|         AstNodeRef::TernaryExpression(_) => {} | ||||
|         AstNodeRef::TernaryRhs(_) => {} | ||||
| @ -470,12 +443,6 @@ fn gather_class( | ||||
|     fqn_context.push(class.identifier().name()); | ||||
|     symbol_table.push_scope(&format!("ClassScope {}", class.identifier().name())); | ||||
| 
 | ||||
|     gather_node( | ||||
|         class.class_constructor().as_node_ref(), | ||||
|         symbol_table, | ||||
|         fqn_context, | ||||
|         diagnostics, | ||||
|     ); | ||||
|     for declaration in class.class_level_declarations() { | ||||
|         gather_node( | ||||
|             declaration.as_node_ref(), | ||||
| @ -512,488 +479,25 @@ fn gather_function( | ||||
|             diagnostics, | ||||
|         ); | ||||
|     } | ||||
|     symbol_table.push_scope(&format!("FunctionScope {}", function.identifier().name())); | ||||
|     gather_node( | ||||
|         function.generics().as_node_ref(), | ||||
|         symbol_table, | ||||
|         fqn_context, | ||||
|         diagnostics, | ||||
|     ); | ||||
|     gather_node( | ||||
|         function.parameters().as_node_ref(), | ||||
|         symbol_table, | ||||
|         fqn_context, | ||||
|         diagnostics, | ||||
|     ); | ||||
|     gather_node( | ||||
|         function.return_type().as_node_ref(), | ||||
|         symbol_table, | ||||
|         fqn_context, | ||||
|         diagnostics, | ||||
|     ); | ||||
|     gather_node( | ||||
|         function.function_body().as_node_ref(), | ||||
|         symbol_table, | ||||
|         fqn_context, | ||||
|         diagnostics, | ||||
|     ); | ||||
|     symbol_table.pop_scope(); | ||||
| } | ||||
| 
 | ||||
| fn gather_operator_function( | ||||
|     operator_function: &OperatorFunction, | ||||
| fn gather_function_block_body( | ||||
|     function_block_body: &FunctionBlockBody, | ||||
|     symbol_table: &mut SymbolTable, | ||||
|     fqn_context: &mut FqnContext, | ||||
|     diagnostics: &mut Vec<DmDiagnostic>, | ||||
| ) { | ||||
|     let function_symbol = FunctionSymbol::without_parameters_or_return_type( | ||||
|         &fqn_context.resolve(&operator_function.operator().inner().name()), | ||||
|         operator_function.operator().inner().name(), | ||||
|         operator_function.is_public(), | ||||
|         false, | ||||
|         Some(SourceDefinition::from_operator( | ||||
|             operator_function.operator(), | ||||
|         )), | ||||
|     ); | ||||
|     if let Err(insert_error) = symbol_table.insert_function_symbol(function_symbol) { | ||||
|         handle_insert_error( | ||||
|             insert_error, | ||||
|             operator_function.operator().inner().name(), | ||||
|             operator_function.operator().file_id(), | ||||
|             operator_function.operator().range(), | ||||
|             "Operator", | ||||
|             diagnostics, | ||||
|         ); | ||||
|     } | ||||
|     symbol_table.push_scope(&format!( | ||||
|         "FunctionScope {}", | ||||
|         operator_function.operator().inner().name() | ||||
|     )); | ||||
|     gather_node( | ||||
|         operator_function.generics().as_node_ref(), | ||||
|         symbol_table, | ||||
|         fqn_context, | ||||
|         diagnostics, | ||||
|     ); | ||||
|     gather_node( | ||||
|         operator_function.parameters().as_node_ref(), | ||||
|         symbol_table, | ||||
|         fqn_context, | ||||
|         diagnostics, | ||||
|     ); | ||||
|     gather_node( | ||||
|         operator_function.return_type().as_node_ref(), | ||||
|         symbol_table, | ||||
|         fqn_context, | ||||
|         diagnostics, | ||||
|     ); | ||||
|     gather_node( | ||||
|         operator_function.function_body().as_node_ref(), | ||||
|         symbol_table, | ||||
|         fqn_context, | ||||
|         diagnostics, | ||||
|     ); | ||||
|     symbol_table.push_scope("FunctionBlockBody"); | ||||
|     gather_node_children(function_block_body, symbol_table, fqn_context, diagnostics); | ||||
|     symbol_table.pop_scope(); | ||||
| } | ||||
| 
 | ||||
| fn gather_platform_function( | ||||
|     platform_function: &PlatformFunction, | ||||
|     symbol_table: &mut SymbolTable, | ||||
|     fqn_context: &mut FqnContext, | ||||
|     diagnostics: &mut Vec<DmDiagnostic>, | ||||
| ) { | ||||
|     let function_symbol = FunctionSymbol::without_parameters_or_return_type( | ||||
|         &fqn_context.resolve(platform_function.identifier().name()), | ||||
|         platform_function.identifier().name(), | ||||
|         platform_function.is_public(), | ||||
|         true, | ||||
|         Some(SourceDefinition::from_identifier( | ||||
|             platform_function.identifier(), | ||||
|         )), | ||||
|     ); | ||||
|     if let Err(insert_error) = symbol_table.insert_function_symbol(function_symbol) { | ||||
|         handle_insert_error( | ||||
|             insert_error, | ||||
|             platform_function.identifier().name(), | ||||
|             platform_function.identifier().file_id(), | ||||
|             platform_function.identifier().range(), | ||||
|             "Function", | ||||
|             diagnostics, | ||||
|         ); | ||||
|     } | ||||
|     symbol_table.push_scope(&format!( | ||||
|         "PlatformFunctionScope {}", | ||||
|         platform_function.identifier().name() | ||||
|     )); | ||||
|     gather_node( | ||||
|         platform_function.generics().as_node_ref(), | ||||
|         symbol_table, | ||||
|         fqn_context, | ||||
|         diagnostics, | ||||
|     ); | ||||
|     gather_node( | ||||
|         platform_function.parameters().as_node_ref(), | ||||
|         symbol_table, | ||||
|         fqn_context, | ||||
|         diagnostics, | ||||
|     ); | ||||
|     gather_node( | ||||
|         platform_function.return_type().as_node_ref(), | ||||
|         symbol_table, | ||||
|         fqn_context, | ||||
|         diagnostics, | ||||
|     ); | ||||
|     symbol_table.pop_scope(); | ||||
| } | ||||
| 
 | ||||
| fn gather_platform_operator_function( | ||||
|     platform_operator_function: &PlatformOperatorFunction, | ||||
|     symbol_table: &mut SymbolTable, | ||||
|     fqn_context: &mut FqnContext, | ||||
|     diagnostics: &mut Vec<DmDiagnostic>, | ||||
| ) { | ||||
|     let function_symbol = FunctionSymbol::without_parameters_or_return_type( | ||||
|         &fqn_context.resolve(platform_operator_function.operator().inner().name()), | ||||
|         platform_operator_function.operator().inner().name(), | ||||
|         platform_operator_function.is_public(), | ||||
|         true, | ||||
|         Some(SourceDefinition::from_operator( | ||||
|             platform_operator_function.operator(), | ||||
|         )), | ||||
|     ); | ||||
|     if let Err(insert_error) = symbol_table.insert_function_symbol(function_symbol) { | ||||
|         handle_insert_error( | ||||
|             insert_error, | ||||
|             platform_operator_function.operator().inner().name(), | ||||
|             platform_operator_function.operator().file_id(), | ||||
|             platform_operator_function.operator().range(), | ||||
|             "Function", | ||||
|             diagnostics, | ||||
|         ); | ||||
|     } | ||||
|     symbol_table.push_scope(&format!( | ||||
|         "PlatformOperatorFunctionScope {}", | ||||
|         platform_operator_function.operator().inner().name() | ||||
|     )); | ||||
|     gather_node( | ||||
|         platform_operator_function.generics().as_node_ref(), | ||||
|         symbol_table, | ||||
|         fqn_context, | ||||
|         diagnostics, | ||||
|     ); | ||||
|     gather_node( | ||||
|         platform_operator_function.parameters().as_node_ref(), | ||||
|         symbol_table, | ||||
|         fqn_context, | ||||
|         diagnostics, | ||||
|     ); | ||||
|     gather_node( | ||||
|         platform_operator_function.return_type().as_node_ref(), | ||||
|         symbol_table, | ||||
|         fqn_context, | ||||
|         diagnostics, | ||||
|     ); | ||||
|     symbol_table.pop_scope(); | ||||
| } | ||||
| 
 | ||||
| fn gather_interface_function( | ||||
|     interface_function: &InterfaceFunction, | ||||
|     symbol_table: &mut SymbolTable, | ||||
|     fqn_context: &mut FqnContext, | ||||
|     diagnostics: &mut Vec<DmDiagnostic>, | ||||
| ) { | ||||
|     let function_symbol = FunctionSymbol::without_parameters_or_return_type( | ||||
|         &fqn_context.resolve(interface_function.identifier().name()), | ||||
|         interface_function.identifier().name(), | ||||
|         true, | ||||
|         false, | ||||
|         Some(SourceDefinition::from_identifier( | ||||
|             interface_function.identifier(), | ||||
|         )), | ||||
|     ); | ||||
|     if let Err(insert_error) = symbol_table.insert_function_symbol(function_symbol) { | ||||
|         handle_insert_error( | ||||
|             insert_error, | ||||
|             interface_function.identifier().name(), | ||||
|             interface_function.identifier().file_id(), | ||||
|             interface_function.identifier().range(), | ||||
|             "Type", | ||||
|             diagnostics, | ||||
|         ); | ||||
|     } | ||||
|     symbol_table.push_scope(&format!( | ||||
|         "InterfaceFunctionScope {}", | ||||
|         interface_function.identifier().name() | ||||
|     )); | ||||
|     gather_node( | ||||
|         interface_function.generics().as_node_ref(), | ||||
|         symbol_table, | ||||
|         fqn_context, | ||||
|         diagnostics, | ||||
|     ); | ||||
|     gather_node( | ||||
|         interface_function.parameters().as_node_ref(), | ||||
|         symbol_table, | ||||
|         fqn_context, | ||||
|         diagnostics, | ||||
|     ); | ||||
|     gather_node( | ||||
|         interface_function.return_type().as_node_ref(), | ||||
|         symbol_table, | ||||
|         fqn_context, | ||||
|         diagnostics, | ||||
|     ); | ||||
|     symbol_table.pop_scope(); | ||||
| } | ||||
| 
 | ||||
| fn gather_interface_default_function( | ||||
|     interface_default_function: &InterfaceDefaultFunction, | ||||
|     symbol_table: &mut SymbolTable, | ||||
|     fqn_context: &mut FqnContext, | ||||
|     diagnostics: &mut Vec<DmDiagnostic>, | ||||
| ) { | ||||
|     let function_symbol = FunctionSymbol::without_parameters_or_return_type( | ||||
|         &fqn_context.resolve(interface_default_function.identifier().name()), | ||||
|         interface_default_function.identifier().name(), | ||||
|         true, | ||||
|         false, | ||||
|         Some(SourceDefinition::from_identifier( | ||||
|             interface_default_function.identifier(), | ||||
|         )), | ||||
|     ); | ||||
|     if let Err(insert_error) = symbol_table.insert_function_symbol(function_symbol) { | ||||
|         handle_insert_error( | ||||
|             insert_error, | ||||
|             interface_default_function.identifier().name(), | ||||
|             interface_default_function.identifier().file_id(), | ||||
|             interface_default_function.identifier().range(), | ||||
|             "Function", | ||||
|             diagnostics, | ||||
|         ); | ||||
|     } | ||||
|     symbol_table.push_scope(&format!( | ||||
|         "InterfaceDefaultFunctionScope {}", | ||||
|         interface_default_function.identifier().name() | ||||
|     )); | ||||
|     gather_node( | ||||
|         interface_default_function.generics().as_node_ref(), | ||||
|         symbol_table, | ||||
|         fqn_context, | ||||
|         diagnostics, | ||||
|     ); | ||||
|     gather_node( | ||||
|         interface_default_function.parameters().as_node_ref(), | ||||
|         symbol_table, | ||||
|         fqn_context, | ||||
|         diagnostics, | ||||
|     ); | ||||
|     gather_node( | ||||
|         interface_default_function.return_type().as_node_ref(), | ||||
|         symbol_table, | ||||
|         fqn_context, | ||||
|         diagnostics, | ||||
|     ); | ||||
|     gather_node( | ||||
|         interface_default_function.function_body().as_node_ref(), | ||||
|         symbol_table, | ||||
|         fqn_context, | ||||
|         diagnostics, | ||||
|     ); | ||||
|     symbol_table.pop_scope(); | ||||
| } | ||||
| 
 | ||||
| fn gather_interface_operator_function( | ||||
|     interface_operator_function: &InterfaceOperatorFunction, | ||||
|     symbol_table: &mut SymbolTable, | ||||
|     fqn_context: &mut FqnContext, | ||||
|     diagnostics: &mut Vec<DmDiagnostic>, | ||||
| ) { | ||||
|     let function_symbol = FunctionSymbol::without_parameters_or_return_type( | ||||
|         &fqn_context.resolve(interface_operator_function.operator().inner().name()), | ||||
|         interface_operator_function.operator().inner().name(), | ||||
|         true, | ||||
|         false, | ||||
|         Some(SourceDefinition::from_operator( | ||||
|             interface_operator_function.operator(), | ||||
|         )), | ||||
|     ); | ||||
|     if let Err(insert_error) = symbol_table.insert_function_symbol(function_symbol) { | ||||
|         handle_insert_error( | ||||
|             insert_error, | ||||
|             interface_operator_function.operator().inner().name(), | ||||
|             interface_operator_function.operator().file_id(), | ||||
|             interface_operator_function.operator().range(), | ||||
|             "Function", | ||||
|             diagnostics, | ||||
|         ); | ||||
|     } | ||||
|     symbol_table.push_scope(&format!( | ||||
|         "InterfaceOperatorFunctionScope {}", | ||||
|         interface_operator_function.operator().inner().name() | ||||
|     )); | ||||
|     gather_node( | ||||
|         interface_operator_function.generics().as_node_ref(), | ||||
|         symbol_table, | ||||
|         fqn_context, | ||||
|         diagnostics, | ||||
|     ); | ||||
|     gather_node( | ||||
|         interface_operator_function.parameters().as_node_ref(), | ||||
|         symbol_table, | ||||
|         fqn_context, | ||||
|         diagnostics, | ||||
|     ); | ||||
|     gather_node( | ||||
|         interface_operator_function.return_type().as_node_ref(), | ||||
|         symbol_table, | ||||
|         fqn_context, | ||||
|         diagnostics, | ||||
|     ); | ||||
|     symbol_table.pop_scope(); | ||||
| } | ||||
| 
 | ||||
| fn gather_interface_default_operator_function( | ||||
|     interface_default_operator_function: &InterfaceDefaultOperatorFunction, | ||||
|     symbol_table: &mut SymbolTable, | ||||
|     fqn_context: &mut FqnContext, | ||||
|     diagnostics: &mut Vec<DmDiagnostic>, | ||||
| ) { | ||||
|     let function_symbol = FunctionSymbol::without_parameters_or_return_type( | ||||
|         &fqn_context.resolve( | ||||
|             interface_default_operator_function | ||||
|                 .operator() | ||||
|                 .inner() | ||||
|                 .name(), | ||||
|         ), | ||||
|         interface_default_operator_function | ||||
|             .operator() | ||||
|             .inner() | ||||
|             .name(), | ||||
|         true, | ||||
|         false, | ||||
|         Some(SourceDefinition::from_operator( | ||||
|             interface_default_operator_function.operator(), | ||||
|         )), | ||||
|     ); | ||||
|     if let Err(insert_error) = symbol_table.insert_function_symbol(function_symbol) { | ||||
|         handle_insert_error( | ||||
|             insert_error, | ||||
|             interface_default_operator_function | ||||
|                 .operator() | ||||
|                 .inner() | ||||
|                 .name(), | ||||
|             interface_default_operator_function.operator().file_id(), | ||||
|             interface_default_operator_function.operator().range(), | ||||
|             "Function", | ||||
|             diagnostics, | ||||
|         ); | ||||
|     } | ||||
|     symbol_table.push_scope(&format!( | ||||
|         "InterfaceDefaultOperatorFunctionScope {}", | ||||
|         interface_default_operator_function | ||||
|             .operator() | ||||
|             .inner() | ||||
|             .name() | ||||
|     )); | ||||
|     gather_node( | ||||
|         interface_default_operator_function.generics().as_node_ref(), | ||||
|         symbol_table, | ||||
|         fqn_context, | ||||
|         diagnostics, | ||||
|     ); | ||||
|     gather_node( | ||||
|         interface_default_operator_function | ||||
|             .parameters() | ||||
|             .as_node_ref(), | ||||
|         symbol_table, | ||||
|         fqn_context, | ||||
|         diagnostics, | ||||
|     ); | ||||
|     gather_node( | ||||
|         interface_default_operator_function | ||||
|             .return_type() | ||||
|             .as_node_ref(), | ||||
|         symbol_table, | ||||
|         fqn_context, | ||||
|         diagnostics, | ||||
|     ); | ||||
|     gather_node( | ||||
|         interface_default_operator_function | ||||
|             .function_body() | ||||
|             .as_node_ref(), | ||||
|         symbol_table, | ||||
|         fqn_context, | ||||
|         diagnostics, | ||||
|     ); | ||||
|     symbol_table.pop_scope(); | ||||
| } | ||||
| 
 | ||||
| fn gather_function_body( | ||||
|     function_body: &FunctionBody, | ||||
|     symbol_table: &mut SymbolTable, | ||||
|     fqn_context: &mut FqnContext, | ||||
|     diagnostics: &mut Vec<DmDiagnostic>, | ||||
| ) { | ||||
|     symbol_table.push_scope("FunctionBodyScope"); | ||||
|     match function_body { | ||||
|         FunctionBody::FunctionAliasBody(alias_body) => { | ||||
|             gather_node( | ||||
|                 alias_body.as_node_ref(), | ||||
|                 symbol_table, | ||||
|                 fqn_context, | ||||
|                 diagnostics, | ||||
|             ); | ||||
|         } | ||||
|         FunctionBody::FunctionEqualsBody(equals_body) => { | ||||
|             gather_node( | ||||
|                 equals_body.as_node_ref(), | ||||
|                 symbol_table, | ||||
|                 fqn_context, | ||||
|                 diagnostics, | ||||
|             ); | ||||
|         } | ||||
|         FunctionBody::FunctionBlockBody(block_body) => { | ||||
|             gather_node( | ||||
|                 block_body.as_node_ref(), | ||||
|                 symbol_table, | ||||
|                 fqn_context, | ||||
|                 diagnostics, | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
|     symbol_table.pop_scope(); | ||||
| } | ||||
| 
 | ||||
| fn gather_member( | ||||
|     member: &Member, | ||||
|     symbol_table: &mut SymbolTable, | ||||
|     fqn_context: &mut FqnContext, | ||||
|     diagnostics: &mut Vec<DmDiagnostic>, | ||||
| ) { | ||||
|     let member_symbol = ClassMemberSymbol::new( | ||||
|         member.is_public(), | ||||
|         member.is_mut(), | ||||
|         member.identifier().name(), | ||||
|         Some(SourceDefinition::from_identifier(member.identifier())), | ||||
|     ); | ||||
|     if let Err(insert_error) = symbol_table.insert_class_member_symbol(member_symbol) { | ||||
|         handle_insert_error( | ||||
|             insert_error, | ||||
|             member.identifier().name(), | ||||
|             member.identifier().file_id(), | ||||
|             member.identifier().range(), | ||||
|             "Class Member", | ||||
|             diagnostics, | ||||
|         ); | ||||
|     } | ||||
|     gather_node( | ||||
|         member.type_use().as_node_ref(), | ||||
|         symbol_table, | ||||
|         fqn_context, | ||||
|         diagnostics, | ||||
|     ); | ||||
| } | ||||
| 
 | ||||
| fn gather_variable_declaration( | ||||
|     variable_declaration: &VariableDeclaration, | ||||
|     symbol_table: &mut SymbolTable, | ||||
| @ -1026,12 +530,3 @@ fn gather_variable_declaration( | ||||
|         ); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn gather_variable_use( | ||||
|     variable_use: &mut VariableUse, | ||||
|     symbol_table: &mut SymbolTable, | ||||
|     fqn_context: &mut FqnContext, | ||||
|     diagnostics: &mut Vec<DmDiagnostic>, | ||||
| ) { | ||||
|     variable_use.set_scope_id(symbol_table.current_scope_id()); | ||||
| } | ||||
|  | ||||
| @ -3,39 +3,32 @@ use std::fmt::{Debug, Formatter}; | ||||
| 
 | ||||
| #[derive(Clone)] | ||||
| pub struct ClassMemberSymbol { | ||||
|     is_public: bool, | ||||
|     is_mut: bool, | ||||
|     declared_name: String, | ||||
|     is_field: bool, | ||||
|     source_definition: Option<SourceDefinition>, | ||||
| } | ||||
| 
 | ||||
| impl ClassMemberSymbol { | ||||
|     pub fn new( | ||||
|         is_public: bool, | ||||
|         is_mut: bool, | ||||
|         declared_name: &str, | ||||
|         is_field: bool, | ||||
|         source_definition: Option<SourceDefinition>, | ||||
|     ) -> Self { | ||||
|         Self { | ||||
|             is_public, | ||||
|             is_mut, | ||||
|             declared_name: declared_name.to_string(), | ||||
|             is_field, | ||||
|             source_definition, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn is_public(&self) -> bool { | ||||
|         self.is_public | ||||
|     } | ||||
|     
 | ||||
|     pub fn is_mut(&self) -> bool { | ||||
|         self.is_mut | ||||
|     } | ||||
| 
 | ||||
|     pub fn declared_name(&self) -> &str { | ||||
|         &self.declared_name | ||||
|     } | ||||
| 
 | ||||
|     pub fn is_field(&self) -> bool { | ||||
|         self.is_field | ||||
|     } | ||||
| 
 | ||||
|     pub fn source_definition(&self) -> Option<&SourceDefinition> { | ||||
|         self.source_definition.as_ref() | ||||
|     } | ||||
| @ -44,9 +37,8 @@ impl ClassMemberSymbol { | ||||
| impl Debug for ClassMemberSymbol { | ||||
|     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { | ||||
|         f.debug_struct("ClassMemberSymbol") | ||||
|             .field("is_public", &self.is_public) | ||||
|             .field("is_mut", &self.is_mut) | ||||
|             .field("declared_name", &self.declared_name) | ||||
|             .field("is_field", &self.is_field) | ||||
|             .field("source_definition", &self.source_definition) | ||||
|             .finish() | ||||
|     } | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| use std::cell::RefCell; | ||||
| use std::range::Range; | ||||
| use std::rc::Rc; | ||||
| use crate::ast::node::{Identifier, Operator, UseStatement}; | ||||
| use crate::ast::node::{Identifier, UseStatement}; | ||||
| 
 | ||||
| #[derive(Clone, Debug)] | ||||
| pub struct SourceDefinition { | ||||
| @ -17,6 +17,14 @@ impl SourceDefinition { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn from_identifier_rc(identifier: Rc<RefCell<Identifier>>) -> Self { | ||||
|         let borrowed = identifier.borrow(); | ||||
|         SourceDefinition { | ||||
|             file_id: borrowed.file_id(), | ||||
|             range: borrowed.range(), | ||||
|         } | ||||
|     } | ||||
|     
 | ||||
|     pub fn from_use_statement(use_statement: &UseStatement) -> Self { | ||||
|         Self { | ||||
|             file_id: use_statement.file_id(), | ||||
| @ -24,13 +32,6 @@ impl SourceDefinition { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn from_operator(operator: &Operator) -> Self { | ||||
|         Self { | ||||
|             file_id: operator.file_id(), | ||||
|             range: operator.range(), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn file_id(&self) -> usize { | ||||
|         self.file_id | ||||
|     } | ||||
|  | ||||
| @ -57,11 +57,11 @@ impl SymbolTable { | ||||
|     } | ||||
| 
 | ||||
|     fn current_scope(&self) -> &Scope { | ||||
|         &self.scopes[self.current_scope_id] | ||||
|         self.scopes.last().unwrap() | ||||
|     } | ||||
| 
 | ||||
|     fn current_scope_mut(&mut self) -> &mut Scope { | ||||
|         &mut self.scopes[self.current_scope_id] | ||||
|         self.scopes.last_mut().unwrap() | ||||
|     } | ||||
| 
 | ||||
|     fn find_current_scope_concrete_use_symbol( | ||||
|  | ||||
| @ -127,13 +127,7 @@ macro_rules! write_symbols { | ||||
| 
 | ||||
| impl Display for Scope { | ||||
|     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { | ||||
|         writeln!( | ||||
|             f, | ||||
|             "----Scope {} (p: {}) {}----", | ||||
|             self.id(), | ||||
|             self.parent().map(|parent_id| format!("{}", parent_id)).unwrap_or_else(|| "None".to_string()), | ||||
|             self.debug_name() | ||||
|         )?; | ||||
|         writeln!(f, "----Scope {} {}----", self.id(), self.debug_name())?; | ||||
|         write_symbols!(f, self.concrete_use_symbols()); | ||||
|         write_symbols!(f, self.star_use_symbols()); | ||||
|         write_symbols!(f, self.module_symbols()); | ||||
|  | ||||
| @ -1,18 +1,6 @@ | ||||
| # $schema: ./ast.schema.yaml | ||||
| # Operators | ||||
| Operator: | ||||
|   struct: | ||||
|     children: | ||||
|       - inner: | ||||
|           member: | ||||
|             rule: OperatorInner | ||||
|       - file_id: | ||||
|           special: | ||||
|             kind: file_id | ||||
|       - range: | ||||
|           special: | ||||
|             kind: range | ||||
| OperatorInner: | ||||
|   leaf_enum: | ||||
|     rules: | ||||
|       - Or | ||||
| @ -441,30 +429,6 @@ PlatformFunction: | ||||
|       - identifier | ||||
|       - parameters | ||||
|       - return_type | ||||
| PlatformOperatorFunction: | ||||
|   struct: | ||||
|     children: | ||||
|       - is_public: | ||||
|           member: | ||||
|             rule: Pub | ||||
|             build: | ||||
|               boolean: | ||||
|                 on: rule_present | ||||
|       - platform_kw: | ||||
|           skip: | ||||
|             rule: Platform | ||||
|       - op_kw: | ||||
|           skip: | ||||
|             rule: Op | ||||
|       - generics: | ||||
|           member: | ||||
|             rule: GenericParameters | ||||
|             build: | ||||
|               node: | ||||
|                 or_else_default: true | ||||
|       - operator | ||||
|       - parameters | ||||
|       - return_type | ||||
| InterfaceFunction: | ||||
|   struct: | ||||
|     children: | ||||
| @ -628,8 +592,12 @@ VariableDeclaration: | ||||
| AssignmentStatement: | ||||
|   struct: | ||||
|     children: | ||||
|       - l_value | ||||
|       - expression | ||||
|       - left: | ||||
|           member: | ||||
|             rule: Expression | ||||
|       - right: | ||||
|           member: | ||||
|             rule: Expression | ||||
| ExpressionStatement: | ||||
|   struct: | ||||
|     children: | ||||
| @ -711,30 +679,6 @@ ForStatement: | ||||
|           skip: | ||||
|             rule: End | ||||
| 
 | ||||
| # LValue | ||||
| LValue: | ||||
|   struct: | ||||
|     children: | ||||
|       - variable_use | ||||
|       - suffixes: | ||||
|           vec: | ||||
|             rule: LValueSuffix | ||||
| LValueSuffix: | ||||
|   tree_enum: | ||||
|     rules: | ||||
|       - ObjectProperty | ||||
|       - ObjectIndex | ||||
| 
 | ||||
| # VariableUse | ||||
| VariableUse: | ||||
|   struct: | ||||
|     children: | ||||
|       - identifier | ||||
|     fields: | ||||
|       - scope_id: | ||||
|           kind: usize | ||||
|           optional: true | ||||
| 
 | ||||
| # Expressions | ||||
| Expression: | ||||
|   polymorphic_type: | ||||
| @ -769,9 +713,6 @@ Expression: | ||||
|       - Literal: | ||||
|           inner: | ||||
|             kind: Literal | ||||
|       - VariableUse: | ||||
|           inner: | ||||
|             kind: VariableUse | ||||
|       - Fqn: | ||||
|           inner: | ||||
|             kind: FullyQualifiedName | ||||
| @ -1114,9 +1055,6 @@ PrimaryExpression: | ||||
|       - Literal: | ||||
|           inner: | ||||
|             kind: Literal | ||||
|       - VariableUse: | ||||
|           inner: | ||||
|             kind: VariableUse | ||||
|       - Fqn: | ||||
|           inner: | ||||
|             kind: FullyQualifiedName | ||||
|  | ||||
| @ -131,10 +131,6 @@ Index = { "[]" } | ||||
| BorrowMut = { Borrow ~ Mut } | ||||
| 
 | ||||
| Operator = { | ||||
|       OperatorInner | ||||
| } | ||||
| 
 | ||||
| OperatorInner = { | ||||
|       Or | ||||
|     | And | ||||
|     | EqualTo | ||||
| @ -435,16 +431,6 @@ PlatformFunction = { | ||||
|     ~ ReturnType | ||||
| } | ||||
| 
 | ||||
| PlatformOperatorFunction = { | ||||
|       Pub? | ||||
|     ~ Platform | ||||
|     ~ Op | ||||
|     ~ GenericParameters? | ||||
|     ~ Operator | ||||
|     ~ Parameters | ||||
|     ~ ReturnType | ||||
| } | ||||
| 
 | ||||
| InterfaceFunction = { | ||||
|       Fn | ||||
|     ~ GenericParameters? | ||||
| @ -542,7 +528,7 @@ VariableDeclaration = { | ||||
| } | ||||
| 
 | ||||
| AssignmentStatement = { | ||||
|       LValue | ||||
|       Expression | ||||
|     ~ "=" | ||||
|     ~ Expression | ||||
| } | ||||
| @ -593,24 +579,6 @@ ForStatement = { | ||||
|     ~ End | ||||
| } | ||||
| 
 | ||||
| // LValue | ||||
| 
 | ||||
| LValue = { | ||||
|       VariableUse | ||||
|     ~ LValueSuffix* | ||||
| } | ||||
| 
 | ||||
| LValueSuffix = { | ||||
|       ObjectProperty | ||||
|     | ObjectIndex | ||||
| } | ||||
| 
 | ||||
| // Variable Use | ||||
| 
 | ||||
| VariableUse = { | ||||
|       Identifier | ||||
| } | ||||
| 
 | ||||
| // Expressions | ||||
| 
 | ||||
| Expression = { | ||||
| @ -759,7 +727,6 @@ ObjectIndex = { | ||||
| 
 | ||||
| PrimaryExpression = { | ||||
|       Literal | ||||
|     | VariableUse | ||||
|     | FullyQualifiedName | ||||
|     | Closure | ||||
|     | ListExpression | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user