62 lines
2.3 KiB
Rust
62 lines
2.3 KiB
Rust
use crate::spec::BuildSpec;
|
|
use convert_case::{Case, Casing};
|
|
use proc_macro2::TokenStream;
|
|
use quote::{format_ident, quote};
|
|
|
|
pub fn make_walk_fn(specs: &[BuildSpec]) -> TokenStream {
|
|
let child_match_arms = specs
|
|
.iter()
|
|
.map(|spec| match spec {
|
|
BuildSpec::Enum(enum_spec) => Some((
|
|
format_ident!("{}", enum_spec.build()),
|
|
format_ident!("{}", enum_spec.build().to_case(Case::Snake)),
|
|
)),
|
|
BuildSpec::LeafEnum(leaf_enum) => Some((
|
|
format_ident!("{}", leaf_enum.build()),
|
|
format_ident!("{}", leaf_enum.build().to_case(Case::Snake)),
|
|
)),
|
|
BuildSpec::Struct(struct_spec) => Some((
|
|
format_ident!("{}", struct_spec.build()),
|
|
format_ident!("{}", struct_spec.build().to_case(Case::Snake)),
|
|
)),
|
|
BuildSpec::LeafStruct(leaf_struct) => Some((
|
|
format_ident!("{}", leaf_struct.build()),
|
|
format_ident!("{}", leaf_struct.build().to_case(Case::Snake)),
|
|
)),
|
|
BuildSpec::Production(_) => None,
|
|
BuildSpec::NodeProduction(_) => None,
|
|
BuildSpec::PolymorphicType(polymorphic_type) => Some((
|
|
format_ident!("{}", polymorphic_type.name()),
|
|
format_ident!("{}", polymorphic_type.name().to_case(Case::Snake)),
|
|
)),
|
|
BuildSpec::PolymorphicEnumLoop(polymorphic_enum_loop) => Some((
|
|
format_ident!("{}", polymorphic_enum_loop.name()),
|
|
format_ident!("{}", polymorphic_enum_loop.name().to_case(Case::Snake)),
|
|
)),
|
|
BuildSpec::PolymorphicPassThrough(_) => None,
|
|
})
|
|
.filter(Option::is_some)
|
|
.map(Option::unwrap)
|
|
.map(|(type_ident, inner_ident)| {
|
|
quote! {
|
|
#type_ident(#inner_ident) => walk_depth_first(#inner_ident, f)
|
|
}
|
|
})
|
|
.collect::<Vec<_>>();
|
|
|
|
quote! {
|
|
use crate::ast::node::*;
|
|
use crate::ast::ast_node::*;
|
|
|
|
pub fn walk_depth_first(node: &impl AstNode, f: &mut impl FnMut(AstNodeRef)) {
|
|
use AstNodeRef::*;
|
|
for child in node.children() {
|
|
match child {
|
|
#(#child_match_arms,)*
|
|
}
|
|
}
|
|
f(node.as_node_ref());
|
|
}
|
|
}
|
|
}
|