deimos-lang/ast-generator/src/ast_node/enum_ast_node.rs
2025-09-29 09:12:28 -05:00

51 lines
1.7 KiB
Rust

use convert_case::{Case, Casing};
use crate::spec::tree_enum_spec::{EnumRuleChildKind, TreeEnumBuildSpec};
use proc_macro2::TokenStream;
use quote::{format_ident, quote};
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| {
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! {
impl AstNode for #type_ident {
fn children(&self) -> Vec<AstNodeRef> {
match self {
#(#match_arms,)*
}
}
fn as_node_ref(&self) -> AstNodeRef {
AstNodeRef::#type_ident(&self)
}
}
}
}