From 6d3e99a871924b8d290a53e401d9fc9e7b821800 Mon Sep 17 00:00:00 2001 From: Oscar Beaumont Date: Mon, 25 Dec 2023 22:44:22 +0800 Subject: [PATCH] fix macros --- macros/src/type/enum.rs | 2 +- macros/src/type/generics.rs | 37 ++++++++++++++++++------ macros/src/type/mod.rs | 56 +++++++++++++++---------------------- macros/src/type/struct.rs | 2 +- src/type/mod.rs | 2 ++ tests/ty_override.rs | 2 +- 6 files changed, 56 insertions(+), 45 deletions(-) diff --git a/macros/src/type/enum.rs b/macros/src/type/enum.rs index 9a9502ea..31354951 100644 --- a/macros/src/type/enum.rs +++ b/macros/src/type/enum.rs @@ -43,7 +43,7 @@ pub fn parse_enum( generics .get(#i) .cloned() - .unwrap_or_else(|| <#ident as #crate_ref::Type>::reference(type_map, std::borrow::Cow::Borrowed(&[])).inner) + .unwrap_or_else(|| <#ident as #crate_ref::Type>::reference(type_map, &[]).inner) ) } }); diff --git a/macros/src/type/generics.rs b/macros/src/type/generics.rs index f538ebcf..58852835 100644 --- a/macros/src/type/generics.rs +++ b/macros/src/type/generics.rs @@ -80,6 +80,11 @@ pub fn add_type_to_where_clause(ty: &TokenStream, generics: &Generics) -> Option } } +type DtGenericFn = fn(&TokenStream, TokenStream) -> TokenStream; +fn dt_generic_fn(f: DtGenericFn) -> DtGenericFn { + f +} + pub fn construct_datatype( var_ident: Ident, ty: &Type, @@ -87,9 +92,17 @@ pub fn construct_datatype( crate_ref: &TokenStream, inline: bool, ) -> syn::Result { - let (method, transform) = match inline { - true => (quote!(inline), quote!()), - false => (quote!(reference), quote!(.inner)), + let (method, transform, generics) = match inline { + true => ( + quote!(inline), + quote!(), + dt_generic_fn(|crate_ref, tokens| quote!(#crate_ref::Generics::Provided(#tokens))), + ), + false => ( + quote!(reference), + quote!(.inner), + dt_generic_fn(|_, tokens| tokens), + ), }; let path = match ty { @@ -115,10 +128,11 @@ pub fn construct_datatype( .enumerate() .map(|(i, _)| format_ident!("{}_{}", &var_ident, i)); + let generics = generics(&crate_ref, quote!(&[#(#generic_var_idents),*])); return Ok(quote! { #(#elems)* - let #var_ident = <#ty as #crate_ref::Type>::#method(type_map, &[#(#generic_var_idents),*])#transform; + let #var_ident = <#ty as #crate_ref::Type>::#method(type_map, #generics)#transform; }); } Type::Paren(p) => { @@ -134,10 +148,11 @@ pub fn construct_datatype( inline, )?; + let generics = generics(&crate_ref, quote!(&[#elem_var_ident])); return Ok(quote! { #elem - let #var_ident = <#ty as #crate_ref::Type>::#method(type_map, &[#elem_var_ident])#transform; + let #var_ident = <#ty as #crate_ref::Type>::#method(type_map, #generics)#transform; }); } Type::Ptr(TypePtr { elem, .. }) | Type::Reference(TypeReference { elem, .. }) => { @@ -151,8 +166,9 @@ pub fn construct_datatype( )); } Type::Macro(m) => { + let generics = generics(&crate_ref, quote!(&[])); return Ok(quote! { - let #var_ident = <#m as #crate_ref::Type>::#method(type_map, std::borrow::Cow::Borrowed(&[]))#transform; + let #var_ident = <#m as #crate_ref::Type>::#method(type_map, #generics)#transform; }); } ty => { @@ -172,10 +188,14 @@ pub fn construct_datatype( .find(|(_, ident)| ident == &type_ident) { let type_ident = type_ident.to_string(); + let generics = generics( + &crate_ref, + quote!(&[#crate_ref::DataType::Generic(std::borrow::Cow::Borrowed(#type_ident).into())]), + ); return Ok(quote! { let #var_ident = generics.get(#i).cloned().unwrap_or_else( || { - <#generic_ident as #crate_ref::Type>::#method(type_map, &[#crate_ref::DataType::Generic(std::borrow::Cow::Borrowed(#type_ident).into())])#transform + <#generic_ident as #crate_ref::Type>::#method(type_map, #generics)#transform }, ); }); @@ -218,9 +238,10 @@ pub fn construct_datatype( .iter() .map(|(i, _)| format_ident!("{}_{}", &var_ident, i)); + let generics = generics(&crate_ref, quote!(&[#(#generic_var_idents),*])); Ok(quote! { #(#generic_vars)* - let #var_ident = <#ty as #crate_ref::Type>::#method(type_map, &[#(#generic_var_idents),*])#transform; + let #var_ident = <#ty as #crate_ref::Type>::#method(type_map, #generics)#transform; }) } diff --git a/macros/src/type/mod.rs b/macros/src/type/mod.rs index 30d4f513..ba55529d 100644 --- a/macros/src/type/mod.rs +++ b/macros/src/type/mod.rs @@ -135,26 +135,16 @@ pub fn derive(input: proc_macro::TokenStream) -> syn::Result #crate_ref::DataType { - // let generics = match generics { + let generics = match generics { + #crate_ref::Generics::Definition => DEFINITION_GENERICS, + #crate_ref::Generics::Provided(generics) => generics, + }; - // }; - - - // #inlines - - - // fn definition(type_map: &mut #crate_ref::TypeMap) -> #crate_ref::DataType { - // Self::inline( - // type_map, - // &DEFINITION_GENERICS - // ) - // } - todo!(); + #inlines } fn reference(type_map: &mut #crate_ref::TypeMap, generics: &[#crate_ref::DataType]) -> #crate_ref::reference::Reference { - // #reference - todo!(); + #reference } } @@ -164,27 +154,25 @@ pub fn derive(input: proc_macro::TokenStream) -> syn::Result #crate_ref::NamedDataType { - // #crate_ref::internal::construct::named_data_type( - // #name.into(), - // #comments.into(), - // #deprecated, - // SID, - // IMPL_LOCATION, - // ::inline(type_map, generics) - // ) - todo!(); + #crate_ref::internal::construct::named_data_type( + #name.into(), + #comments.into(), + #deprecated, + SID, + IMPL_LOCATION, + ::inline(type_map, #crate_ref::Generics::Provided(generics)) + ) } fn definition_named_data_type(type_map: &mut #crate_ref::TypeMap) -> #crate_ref::NamedDataType { - // #crate_ref::internal::construct::named_data_type( - // #name.into(), - // #comments.into(), - // #deprecated, - // SID, - // IMPL_LOCATION, - // ::definition(type_map) - // ) - todo!(); + #crate_ref::internal::construct::named_data_type( + #name.into(), + #comments.into(), + #deprecated, + SID, + IMPL_LOCATION, + ::inline(type_map, #crate_ref::Generics::Definition) + ) } } diff --git a/macros/src/type/struct.rs b/macros/src/type/struct.rs index 3ef4b9be..79749e3d 100644 --- a/macros/src/type/struct.rs +++ b/macros/src/type/struct.rs @@ -57,7 +57,7 @@ pub fn parse_struct( generics .get(#i) .cloned() - .unwrap_or_else(|| <#ident as #crate_ref::Type>::reference(type_map, std::borrow::Cow::Borrowed(&[])).inner) + .unwrap_or_else(|| <#ident as #crate_ref::Type>::reference(type_map, &[]).inner) } }); let reference_generics = diff --git a/src/type/mod.rs b/src/type/mod.rs index b04ddce3..1a73993f 100644 --- a/src/type/mod.rs +++ b/src/type/mod.rs @@ -63,9 +63,11 @@ pub trait NamedType: Type { const SID: SpectaID; const IMPL_LOCATION: ImplLocation; // TODO: I don't think this is used so maybe remove it? + // TODO: Should take `Generics` instead of `&[DataType]` but I plan to remove this trait so not fixing it for now. /// this is equivalent to [Type::inline] but returns a [NamedDataType] instead. fn named_data_type(type_map: &mut TypeMap, generics: &[DataType]) -> NamedDataType; + // TODO: Just remove this method given we removed `Type::definition` /// this is equivalent to [Type::definition] but returns a [NamedDataType] instead. fn definition_named_data_type(type_map: &mut TypeMap) -> NamedDataType; } diff --git a/tests/ty_override.rs b/tests/ty_override.rs index 52b7cfec..423b5631 100644 --- a/tests/ty_override.rs +++ b/tests/ty_override.rs @@ -1,4 +1,4 @@ -use specta::Type; +use specta::{Any, Type}; use crate::ts::assert_ts;