refactor(derive): Only pass around what is needed

This commit is contained in:
Ed Page 2022-09-01 13:21:57 -05:00
parent a86cb8a26c
commit a47462123c
4 changed files with 41 additions and 33 deletions

View file

@ -36,7 +36,8 @@ pub fn derive_args(input: &DeriveInput) -> TokenStream {
}) => {
let name = Name::Derived(ident.clone());
let item = Item::from_args_struct(input, name);
gen_for_struct(&item, ident, &input.generics, &fields.named)
let fields = &fields.named;
gen_for_struct(&item, ident, &input.generics, fields)
}
Data::Struct(DataStruct {
fields: Fields::Unit,
@ -44,12 +45,8 @@ pub fn derive_args(input: &DeriveInput) -> TokenStream {
}) => {
let name = Name::Derived(ident.clone());
let item = Item::from_args_struct(input, name);
gen_for_struct(
&item,
ident,
&input.generics,
&Punctuated::<Field, Comma>::new(),
)
let fields = &Punctuated::<Field, Comma>::new();
gen_for_struct(&item, ident, &input.generics, fields)
}
_ => abort_call_site!("`#[derive(Args)]` only supports non-tuple structs"),
}

View file

@ -16,9 +16,11 @@ use proc_macro2::TokenStream;
use proc_macro_error::abort_call_site;
use quote::quote;
use syn::Ident;
use syn::Token;
use syn::Variant;
use syn::{
self, punctuated::Punctuated, token::Comma, Data, DataEnum, DataStruct, DeriveInput, Field,
Fields, Generics,
self, punctuated::Punctuated, token::Comma, Data, DataStruct, DeriveInput, Field, Fields,
Generics,
};
use crate::derives::{args, into_app, subcommand};
@ -40,7 +42,8 @@ pub fn derive_parser(input: &DeriveInput) -> TokenStream {
.ok()
.unwrap_or_default()));
let item = Item::from_args_struct(input, name);
gen_for_struct(&item, ident, &input.generics, &fields.named)
let fields = &fields.named;
gen_for_struct(&item, ident, &input.generics, fields)
}
Data::Struct(DataStruct {
fields: Fields::Unit,
@ -52,12 +55,8 @@ pub fn derive_parser(input: &DeriveInput) -> TokenStream {
.ok()
.unwrap_or_default()));
let item = Item::from_args_struct(input, name);
gen_for_struct(
&item,
ident,
&input.generics,
&Punctuated::<Field, Comma>::new(),
)
let fields = &Punctuated::<Field, Comma>::new();
gen_for_struct(&item, ident, &input.generics, fields)
}
Data::Enum(ref e) => {
dummies::parser_enum(ident);
@ -66,7 +65,8 @@ pub fn derive_parser(input: &DeriveInput) -> TokenStream {
.ok()
.unwrap_or_default()));
let item = Item::from_subcommand_enum(input, name);
gen_for_enum(&item, ident, &input.generics, e)
let variants = &e.variants;
gen_for_enum(&item, ident, &input.generics, variants)
}
_ => abort_call_site!("`#[derive(Parser)]` only supports non-tuple structs and enums"),
}
@ -91,11 +91,16 @@ fn gen_for_struct(
}
}
fn gen_for_enum(item: &Item, item_name: &Ident, generics: &Generics, e: &DataEnum) -> TokenStream {
fn gen_for_enum(
item: &Item,
item_name: &Ident,
generics: &Generics,
variants: &Punctuated<Variant, Token![,]>,
) -> TokenStream {
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
let into_app = into_app::gen_for_enum(item, item_name, generics);
let subcommand = subcommand::gen_for_enum(item, item_name, generics, e);
let subcommand = subcommand::gen_for_enum(item, item_name, generics, variants);
quote! {
impl #impl_generics clap::Parser for #item_name #ty_generics #where_clause {}

View file

@ -16,8 +16,8 @@ use proc_macro2::{Ident, Span, TokenStream};
use proc_macro_error::{abort, abort_call_site};
use quote::{format_ident, quote, quote_spanned};
use syn::{
punctuated::Punctuated, spanned::Spanned, Data, DataEnum, DeriveInput, FieldsUnnamed, Generics,
Token, Variant,
punctuated::Punctuated, spanned::Spanned, Data, DeriveInput, FieldsUnnamed, Generics, Token,
Variant,
};
use crate::derives::args;
@ -34,7 +34,8 @@ pub fn derive_subcommand(input: &DeriveInput) -> TokenStream {
Data::Enum(ref e) => {
let name = Name::Derived(ident.clone());
let item = Item::from_subcommand_enum(input, name);
gen_for_enum(&item, ident, &input.generics, e)
let variants = &e.variants;
gen_for_enum(&item, ident, &input.generics, variants)
}
_ => abort_call_site!("`#[derive(Subcommand)]` only supports enums"),
}
@ -44,16 +45,16 @@ pub fn gen_for_enum(
item: &Item,
item_name: &Ident,
generics: &Generics,
e: &DataEnum,
variants: &Punctuated<Variant, Token![,]>,
) -> TokenStream {
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
let from_arg_matches = gen_from_arg_matches(&e.variants, item);
let update_from_arg_matches = gen_update_from_arg_matches(&e.variants, item);
let from_arg_matches = gen_from_arg_matches(variants, item);
let update_from_arg_matches = gen_update_from_arg_matches(variants, item);
let augmentation = gen_augment(&e.variants, item, false);
let augmentation_update = gen_augment(&e.variants, item, true);
let has_subcommand = gen_has_subcommand(&e.variants, item);
let augmentation = gen_augment(variants, item, false);
let augmentation_update = gen_augment(variants, item, true);
let has_subcommand = gen_has_subcommand(variants, item);
quote! {
#[allow(dead_code, unreachable_code, unused_variables, unused_braces)]

View file

@ -13,8 +13,8 @@ use proc_macro_error::{abort, abort_call_site};
use quote::quote;
use quote::quote_spanned;
use syn::{
punctuated::Punctuated, spanned::Spanned, token::Comma, Data, DataEnum, DeriveInput, Fields,
Ident, Variant,
punctuated::Punctuated, spanned::Spanned, token::Comma, Data, DeriveInput, Fields, Ident,
Variant,
};
use crate::dummies;
@ -29,14 +29,19 @@ pub fn derive_value_enum(input: &DeriveInput) -> TokenStream {
Data::Enum(ref e) => {
let name = Name::Derived(ident.clone());
let item = Item::from_value_enum(input, name);
gen_for_enum(&item, ident, e)
let variants = &e.variants;
gen_for_enum(&item, ident, variants)
}
_ => abort_call_site!("`#[derive(ValueEnum)]` only supports enums"),
}
}
pub fn gen_for_enum(item: &Item, item_name: &Ident, e: &DataEnum) -> TokenStream {
let lits = lits(&e.variants, item);
pub fn gen_for_enum(
item: &Item,
item_name: &Ident,
variants: &Punctuated<Variant, Comma>,
) -> TokenStream {
let lits = lits(variants, item);
let value_variants = gen_value_variants(&lits);
let to_possible_value = gen_to_possible_value(&lits);