1fad3a1d3Sopenharmony_ciuse crate::cfg;
2fad3a1d3Sopenharmony_ciuse inflections::Inflect;
3fad3a1d3Sopenharmony_ciuse proc_macro2::{Ident, Span, TokenStream};
4fad3a1d3Sopenharmony_ciuse syn_codegen::{Data, Definitions, Features, Node};
5fad3a1d3Sopenharmony_ci
6fad3a1d3Sopenharmony_cipub const TERMINAL_TYPES: &[&str] = &["Span", "Ident"];
7fad3a1d3Sopenharmony_ci
8fad3a1d3Sopenharmony_cipub fn under_name(name: &str) -> Ident {
9fad3a1d3Sopenharmony_ci    Ident::new(&name.to_snake_case(), Span::call_site())
10fad3a1d3Sopenharmony_ci}
11fad3a1d3Sopenharmony_ci
12fad3a1d3Sopenharmony_cipub fn traverse(
13fad3a1d3Sopenharmony_ci    defs: &Definitions,
14fad3a1d3Sopenharmony_ci    node: fn(&mut TokenStream, &mut TokenStream, &Node, &Definitions),
15fad3a1d3Sopenharmony_ci) -> (TokenStream, TokenStream) {
16fad3a1d3Sopenharmony_ci    let mut types = defs.types.clone();
17fad3a1d3Sopenharmony_ci    for &terminal in TERMINAL_TYPES {
18fad3a1d3Sopenharmony_ci        types.push(Node {
19fad3a1d3Sopenharmony_ci            ident: terminal.to_owned(),
20fad3a1d3Sopenharmony_ci            features: Features::default(),
21fad3a1d3Sopenharmony_ci            data: Data::Private,
22fad3a1d3Sopenharmony_ci            exhaustive: true,
23fad3a1d3Sopenharmony_ci        });
24fad3a1d3Sopenharmony_ci    }
25fad3a1d3Sopenharmony_ci    types.sort_by(|a, b| a.ident.cmp(&b.ident));
26fad3a1d3Sopenharmony_ci
27fad3a1d3Sopenharmony_ci    let mut traits = TokenStream::new();
28fad3a1d3Sopenharmony_ci    let mut impls = TokenStream::new();
29fad3a1d3Sopenharmony_ci    for s in types {
30fad3a1d3Sopenharmony_ci        let features = cfg::features(&s.features, None);
31fad3a1d3Sopenharmony_ci        traits.extend(features.clone());
32fad3a1d3Sopenharmony_ci        impls.extend(features);
33fad3a1d3Sopenharmony_ci        node(&mut traits, &mut impls, &s, defs);
34fad3a1d3Sopenharmony_ci    }
35fad3a1d3Sopenharmony_ci
36fad3a1d3Sopenharmony_ci    (traits, impls)
37fad3a1d3Sopenharmony_ci}
38