Inline some small code generation helpers
diff --git a/codegen/src/fold.rs b/codegen/src/fold.rs
index fabe598..bb6e37d 100644
--- a/codegen/src/fold.rs
+++ b/codegen/src/fold.rs
@@ -19,108 +19,12 @@
fn simple_visit(item: &str, name: &TokenStream) -> TokenStream {
let ident = under_name(item);
-
let method = Ident::new(&format!("fold_{}", ident), Span::call_site());
quote! {
_visitor.#method(#name)
}
}
-fn box_visit(
- elem: &types::Type,
- features: &types::Features,
- defs: &types::Definitions,
- name: &TokenStream,
-) -> Option<TokenStream> {
- let res = visit(elem, features, defs, "e!(*#name))?;
- Some(quote! {
- Box::new(#res)
- })
-}
-
-fn vec_visit(
- elem: &types::Type,
- features: &types::Features,
- defs: &types::Definitions,
- name: &TokenStream,
-) -> Option<TokenStream> {
- let operand = quote!(it);
- let val = visit(elem, features, defs, &operand)?;
- Some(quote! {
- FoldHelper::lift(#name, |it| { #val })
- })
-}
-
-fn punctuated_visit(
- elem: &types::Type,
- features: &types::Features,
- defs: &types::Definitions,
- name: &TokenStream,
-) -> Option<TokenStream> {
- let operand = quote!(it);
- let val = visit(elem, features, defs, &operand)?;
- Some(quote! {
- FoldHelper::lift(#name, |it| { #val })
- })
-}
-
-fn option_visit(
- elem: &types::Type,
- features: &types::Features,
- defs: &types::Definitions,
- name: &TokenStream,
-) -> Option<TokenStream> {
- let it = quote!(it);
- let val = visit(elem, features, defs, &it)?;
- Some(quote! {
- (#name).map(|it| { #val })
- })
-}
-
-fn tuple_visit(
- elems: &[types::Type],
- features: &types::Features,
- defs: &types::Definitions,
- name: &TokenStream,
-) -> Option<TokenStream> {
- if elems.is_empty() {
- return None;
- }
-
- let mut code = TokenStream::new();
- for (i, elem) in elems.iter().enumerate() {
- let i = Index::from(i);
- let it = quote!((#name).#i);
- let val = visit(elem, features, defs, &it).unwrap_or(it);
- code.append_all(val);
- code.append_all(quote!(,));
- }
- Some(quote! {
- (#code)
- })
-}
-
-fn token_punct_visit(repr: &str, name: &TokenStream) -> TokenStream {
- let ty: TokenStream = syn::parse_str(&format!("Token![{}]", repr)).unwrap();
- quote! {
- #ty(tokens_helper(_visitor, &#name.spans))
- }
-}
-
-fn token_keyword_visit(repr: &str, name: &TokenStream) -> TokenStream {
- let ty: TokenStream = syn::parse_str(&format!("Token![{}]", repr)).unwrap();
- quote! {
- #ty(tokens_helper(_visitor, &#name.span))
- }
-}
-
-fn token_group_visit(ty: &str, name: &TokenStream) -> TokenStream {
- let ty = Ident::new(ty, Span::call_site());
- quote! {
- #ty(tokens_helper(_visitor, &#name.span))
- }
-}
-
fn visit(
ty: &types::Type,
features: &types::Features,
@@ -128,39 +32,75 @@
name: &TokenStream,
) -> Option<TokenStream> {
match ty {
- types::Type::Box(t) => box_visit(&*t, features, defs, name),
- types::Type::Vec(t) => vec_visit(&*t, features, defs, name),
- types::Type::Punctuated(p) => punctuated_visit(&p.element, features, defs, name),
- types::Type::Option(t) => option_visit(&*t, features, defs, name),
- types::Type::Tuple(t) => tuple_visit(t, features, defs, name),
+ types::Type::Box(t) => {
+ let res = visit(t, features, defs, "e!(*#name))?;
+ Some(quote! {
+ Box::new(#res)
+ })
+ }
+ types::Type::Vec(t) => {
+ let operand = quote!(it);
+ let val = visit(t, features, defs, &operand)?;
+ Some(quote! {
+ FoldHelper::lift(#name, |it| { #val })
+ })
+ }
+ types::Type::Punctuated(p) => {
+ let operand = quote!(it);
+ let val = visit(&p.element, features, defs, &operand)?;
+ Some(quote! {
+ FoldHelper::lift(#name, |it| { #val })
+ })
+ }
+ types::Type::Option(t) => {
+ let it = quote!(it);
+ let val = visit(t, features, defs, &it)?;
+ Some(quote! {
+ (#name).map(|it| { #val })
+ })
+ }
+ types::Type::Tuple(t) => {
+ let mut code = TokenStream::new();
+ for (i, elem) in t.iter().enumerate() {
+ let i = Index::from(i);
+ let it = quote!((#name).#i);
+ let val = visit(elem, features, defs, &it).unwrap_or(it);
+ code.append_all(val);
+ code.append_all(quote!(,));
+ }
+ Some(quote! {
+ (#code)
+ })
+ }
types::Type::Token(t) => {
let repr = &defs.tokens[t];
let is_keyword = repr.chars().next().unwrap().is_alphabetic();
- if is_keyword {
- Some(token_keyword_visit(repr, name))
+ let spans = if is_keyword {
+ quote!(span)
} else {
- Some(token_punct_visit(repr, name))
- }
+ quote!(spans)
+ };
+ let ty: TokenStream = syn::parse_str(&format!("Token![{}]", repr)).unwrap();
+ Some(quote! {
+ #ty(tokens_helper(_visitor, &#name.#spans))
+ })
}
- types::Type::Group(t) => Some(token_group_visit(&t[..], name)),
+ types::Type::Group(t) => {
+ let ty = Ident::new(t, Span::call_site());
+ Some(quote! {
+ #ty(tokens_helper(_visitor, &#name.span))
+ })
+ }
types::Type::Syn(t) => {
fn requires_full(features: &types::Features) -> bool {
features.any.contains("full") && features.any.len() == 1
}
-
- let res = simple_visit(t, name);
-
+ let mut res = simple_visit(t, name);
let target = defs.types.iter().find(|ty| ty.ident == *t).unwrap();
-
- Some(
- if requires_full(&target.features) && !requires_full(features) {
- quote! {
- full!(#res)
- }
- } else {
- res
- },
- )
+ if requires_full(&target.features) && !requires_full(features) {
+ res = quote!(full!(#res));
+ }
+ Some(res)
}
types::Type::Ext(t) if gen::TERMINAL_TYPES.contains(&&t[..]) => Some(simple_visit(t, name)),
types::Type::Ext(_) | types::Type::Std(_) => None,