diff --git a/ast-generator/src/ast_node/mod.rs b/ast-generator/src/ast_node/mod.rs index f09cf79..b6d5264 100644 --- a/ast-generator/src/ast_node/mod.rs +++ b/ast-generator/src/ast_node/mod.rs @@ -67,7 +67,7 @@ pub fn make_ast_enum_member(build_spec: &BuildSpec) -> Option { } .map(|type_ident| { quote! { - #type_ident(#type_ident) + #type_ident(&'a #type_ident) } }) } \ No newline at end of file diff --git a/ast-generator/src/ast_node/polymorphic_type_ast_node.rs b/ast-generator/src/ast_node/polymorphic_type_ast_node.rs index 2df90ee..d698160 100644 --- a/ast-generator/src/ast_node/polymorphic_type_ast_node.rs +++ b/ast-generator/src/ast_node/polymorphic_type_ast_node.rs @@ -11,7 +11,7 @@ pub fn make_polymorphic_type_ast_node_impl(spec: &PolymorphicTypeBuildSpec) -> T 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] + #type_ident::#variant_ident(#child_ident) => vec![#child_ident.as_node_ref()] } }) .collect::>(); diff --git a/ast-generator/src/ast_node/struct_ast_node.rs b/ast-generator/src/ast_node/struct_ast_node.rs index 102874f..ff32739 100644 --- a/ast-generator/src/ast_node/struct_ast_node.rs +++ b/ast-generator/src/ast_node/struct_ast_node.rs @@ -8,41 +8,44 @@ pub fn make_struct_ast_node_impl(spec: &StructSpec) -> TokenStream { .children() .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).collect() { - children.push(child); + 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(node_child) => { + 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()); } - }; - Some(children_stream) + }) + } else { + Some(quote! { + children.push(self.#child_ident().as_node_ref()) + }) } } - } - StructChild::MemberChild(member_child) => { - match member_child.build() { - MemberChildBuild::Node(_) => { - let child_ident = format_ident!("{}", member_child.name()); - let child_stream = quote! { - children.add(self.#child_ident().as_node_ref()) - }; - Some(child_stream) - } - MemberChildBuild::Boolean(_) => None - } - } + MemberChildBuild::Boolean(_) => None, + }, }) .filter(Option::is_some) .map(Option::unwrap) .collect::>(); - + quote! { impl AstNode for #type_ident { fn children(&self) -> Vec { - let children: Vec = vec![]; + let mut children: Vec = vec![]; #(#child_adders;)* children } diff --git a/ast-generator/src/lib.rs b/ast-generator/src/lib.rs index 2e11e1c..b013867 100644 --- a/ast-generator/src/lib.rs +++ b/ast-generator/src/lib.rs @@ -11,11 +11,11 @@ use crate::build_fn::make_build_fn; use crate::deserialize::deserialize_yaml_spec; use crate::pretty_print::make_pretty_print_impl; use crate::type_gen::make_type; +use crate::walk::make_walk_fn; use proc_macro2::TokenStream; use quote::quote; use spec::BuildSpec; use syn::File; -use crate::walk::make_walk_fn; fn debug_built_spec(build_spec: &BuildSpec, token_stream: &TokenStream) { println!("*** BuildSpec ***"); @@ -168,7 +168,7 @@ fn generate_ast_node_file(build_specs: &[BuildSpec]) -> AstGeneratedFile { let combined = quote! { use crate::ast::node::*; - pub enum AstNodeRef { + pub enum AstNodeRef<'a> { #(#ast_enum_members,)* }