blob: ba86fbf09f15f5bb60032c38dd7bcb2155737d4c [file] [log] [blame]
David Tolnay9ee641a2019-05-08 17:00:16 -07001use inflections::Inflect;
David Tolnaycc8d14e2019-05-08 17:23:09 -07002use proc_macro2::{Ident, Span, TokenStream};
David Tolnayc94e1a02019-05-08 17:26:35 -07003use quote::quote;
David Tolnayb2188a62019-05-09 11:42:44 -07004use syn_codegen::{Data, Definitions, Features, Node};
David Tolnay1e99fa32019-05-08 16:18:36 -07005
6pub const TERMINAL_TYPES: &[&str] = &["Span", "Ident"];
7
David Tolnay9ee641a2019-05-08 17:00:16 -07008pub fn under_name(name: &str) -> Ident {
9 Ident::new(&name.to_snake_case(), Span::call_site())
10}
11
David Tolnaycc8d14e2019-05-08 17:23:09 -070012pub fn traverse(
13 defs: &Definitions,
14 node: fn(&mut TokenStream, &mut TokenStream, &Node, &Definitions),
15) -> (TokenStream, TokenStream) {
16 let mut traits = TokenStream::new();
17 let mut impls = TokenStream::new();
David Tolnay1e99fa32019-05-08 16:18:36 -070018 for s in &defs.types {
David Tolnayc94e1a02019-05-08 17:26:35 -070019 let features = &s.features.any;
20 let features = match features.len() {
21 0 => quote!(),
22 1 => quote!(#[cfg(feature = #(#features)*)]),
23 _ => quote!(#[cfg(any(#(feature = #features),*))]),
24 };
25 traits.extend(features.clone());
26 impls.extend(features);
David Tolnaycc8d14e2019-05-08 17:23:09 -070027 node(&mut traits, &mut impls, s, defs);
David Tolnay1e99fa32019-05-08 16:18:36 -070028 }
29 for tt in TERMINAL_TYPES {
David Tolnaycc8d14e2019-05-08 17:23:09 -070030 let s = Node {
David Tolnay1e99fa32019-05-08 16:18:36 -070031 ident: tt.to_string(),
David Tolnaycc8d14e2019-05-08 17:23:09 -070032 features: Features::default(),
33 data: Data::Private,
David Tolnay1e99fa32019-05-08 16:18:36 -070034 };
David Tolnaycc8d14e2019-05-08 17:23:09 -070035 node(&mut traits, &mut impls, &s, defs);
David Tolnay1e99fa32019-05-08 16:18:36 -070036 }
David Tolnaycc8d14e2019-05-08 17:23:09 -070037 (traits, impls)
David Tolnay1e99fa32019-05-08 16:18:36 -070038}