@@ -2,6 +2,8 @@ use proc_macro2::TokenStream;
22use quote:: quote;
33use syn:: { punctuated:: Punctuated , token:: Comma , Attribute , Fields , Ident , Item , ItemEnum } ;
44
5+ use crate :: generated:: get_trait_crate_and_generics;
6+
57pub fn ast ( input : & Item ) -> TokenStream {
68 let ( head, tail) = match input {
79 Item :: Enum ( enum_) => ( enum_repr ( enum_) , assert_generated_derives ( & enum_. attrs ) ) ,
@@ -44,19 +46,20 @@ fn enum_repr(enum_: &ItemEnum) -> TokenStream {
4446fn assert_generated_derives ( attrs : & [ Attribute ] ) -> TokenStream {
4547 // NOTE: At this level we don't care if a trait is derived multiple times, It is the
4648 // responsibility of the `ast_tools` to raise errors for those.
47- let assertion = attrs
49+ let assertions = attrs
4850 . iter ( )
4951 . filter ( |attr| attr. path ( ) . is_ident ( "generate_derive" ) )
5052 . flat_map ( parse_attr)
51- . map ( |derive| {
52- let ( abs_derive, generics) = abs_trait ( & derive) ;
53+ . map ( |trait_ident| {
54+ let trait_name = trait_ident. to_string ( ) ;
55+ let ( trait_path, generics) = get_trait_crate_and_generics ( & trait_name) ;
5356 quote ! { {
5457 // NOTE: these are wrapped in a scope to avoid the need for unique identifiers.
55- trait AssertionTrait : #abs_derive #generics { }
56- impl <T : #derive #generics> AssertionTrait for T { }
58+ trait AssertionTrait : #trait_path #generics { }
59+ impl <T : #trait_ident #generics> AssertionTrait for T { }
5760 } }
5861 } ) ;
59- quote ! ( const _: ( ) = { #( #assertion ) * } ; )
62+ quote ! ( const _: ( ) = { #( #assertions ) * } ; )
6063}
6164
6265#[ inline]
@@ -65,34 +68,3 @@ fn parse_attr(attr: &Attribute) -> impl Iterator<Item = Ident> {
6568 . expect ( "`#[generate_derive]` only accepts traits as single segment paths. Found an invalid argument." )
6669 . into_iter ( )
6770}
68-
69- // TODO: benchmark this to see if a lazy static cell containing `HashMap` would perform better.
70- #[ inline]
71- fn abs_trait (
72- ident : & Ident ,
73- ) -> ( /* absolute type path */ TokenStream , /* possible generics */ TokenStream ) {
74- if ident == "CloneIn" {
75- ( quote ! ( :: oxc_allocator:: CloneIn ) , quote ! ( <' static >) )
76- } else if ident == "GetSpan" {
77- ( quote ! ( :: oxc_span:: GetSpan ) , TokenStream :: default ( ) )
78- } else if ident == "GetSpanMut" {
79- ( quote ! ( :: oxc_span:: GetSpanMut ) , TokenStream :: default ( ) )
80- } else if ident == "GetAddress" {
81- ( quote ! ( :: oxc_allocator:: GetAddress ) , TokenStream :: default ( ) )
82- } else if ident == "ContentEq" {
83- ( quote ! ( :: oxc_span:: ContentEq ) , TokenStream :: default ( ) )
84- } else if ident == "ESTree" {
85- ( quote ! ( :: oxc_estree:: ESTree ) , TokenStream :: default ( ) )
86- } else {
87- invalid_derive ( ident)
88- }
89- }
90-
91- #[ cold]
92- fn invalid_derive ( ident : & Ident ) -> ! {
93- panic ! (
94- "Invalid derive trait(generate_derive): {ident}.\n \
95- Help: If you are trying to implement a new `generate_derive` trait, \
96- make sure to add it to the list in `abs_trait` function."
97- )
98- }
0 commit comments