refactor(ast): move functions to top level in ast macro (#5793)

Pure refactor. Convert nested functions to top level, to make it easier to read.
This commit is contained in:
overlookmotel 2024-09-16 04:10:31 +00:00
parent cf97f6d1ad
commit 17cd9038b7

View file

@ -42,54 +42,55 @@ fn enum_repr(enum_: &ItemEnum) -> TokenStream {
/// If `GetSpan` is not in scope, or it is not the correct `oxc_span::GetSpan`, /// If `GetSpan` is not in scope, or it is not the correct `oxc_span::GetSpan`,
/// this will raise a compilation error. /// this will raise a compilation error.
fn assert_generated_derives(attrs: &[Attribute]) -> TokenStream { fn assert_generated_derives(attrs: &[Attribute]) -> TokenStream {
#[inline]
fn parse(attr: &Attribute) -> impl Iterator<Item = Ident> {
attr.parse_args_with(Punctuated::<Ident, Comma>::parse_terminated)
.expect("`#[generate_derive]` only accepts traits as single segment paths. Found an invalid argument.")
.into_iter()
}
// TODO: benchmark this to see if a lazy static cell containing `HashMap` would perform better.
#[inline]
fn abs_trait(
ident: &Ident,
) -> (/* absolute type path */ TokenStream, /* possible generics */ TokenStream) {
#[cold]
fn invalid_derive(ident: &Ident) -> ! {
panic!(
"Invalid derive trait(generate_derive): {ident}.\n\
Help: If you are trying to implement a new `generate_derive` trait, \
Make sure to add it to the list below."
)
}
if ident == "CloneIn" {
(quote!(::oxc_allocator::CloneIn), quote!(<'static>))
} else if ident == "GetSpan" {
(quote!(::oxc_span::GetSpan), TokenStream::default())
} else if ident == "GetSpanMut" {
(quote!(::oxc_span::GetSpanMut), TokenStream::default())
} else if ident == "ContentEq" {
(quote!(::oxc_span::cmp::ContentEq), TokenStream::default())
} else if ident == "ContentHash" {
(quote!(::oxc_span::hash::ContentHash), TokenStream::default())
} else {
invalid_derive(ident)
}
}
// NOTE: At this level we don't care if a trait is derived multiple times, It is the // NOTE: At this level we don't care if a trait is derived multiple times, It is the
// responsibility of the `ast_tools` to raise errors for those. // responsibility of the `ast_tools` to raise errors for those.
let assertion = let assertion = attrs
attrs.iter().filter(|attr| attr.path().is_ident("generate_derive")).flat_map(parse).map( .iter()
|derive| { .filter(|attr| attr.path().is_ident("generate_derive"))
let (abs_derive, generics) = abs_trait(&derive); .flat_map(parse_attr)
quote! {{ .map(|derive| {
// NOTE: these are wrapped in a scope to avoid the need for unique identifiers. let (abs_derive, generics) = abs_trait(&derive);
trait AssertionTrait: #abs_derive #generics {} quote! {{
impl<T: #derive #generics> AssertionTrait for T {} // NOTE: these are wrapped in a scope to avoid the need for unique identifiers.
}} trait AssertionTrait: #abs_derive #generics {}
}, impl<T: #derive #generics> AssertionTrait for T {}
); }}
});
quote!(const _: () = { #(#assertion)* };) quote!(const _: () = { #(#assertion)* };)
} }
#[inline]
fn parse_attr(attr: &Attribute) -> impl Iterator<Item = Ident> {
attr.parse_args_with(Punctuated::<Ident, Comma>::parse_terminated)
.expect("`#[generate_derive]` only accepts traits as single segment paths. Found an invalid argument.")
.into_iter()
}
// TODO: benchmark this to see if a lazy static cell containing `HashMap` would perform better.
#[inline]
fn abs_trait(
ident: &Ident,
) -> (/* absolute type path */ TokenStream, /* possible generics */ TokenStream) {
if ident == "CloneIn" {
(quote!(::oxc_allocator::CloneIn), quote!(<'static>))
} else if ident == "GetSpan" {
(quote!(::oxc_span::GetSpan), TokenStream::default())
} else if ident == "GetSpanMut" {
(quote!(::oxc_span::GetSpanMut), TokenStream::default())
} else if ident == "ContentEq" {
(quote!(::oxc_span::cmp::ContentEq), TokenStream::default())
} else if ident == "ContentHash" {
(quote!(::oxc_span::hash::ContentHash), TokenStream::default())
} else {
invalid_derive(ident)
}
}
#[cold]
fn invalid_derive(ident: &Ident) -> ! {
panic!(
"Invalid derive trait(generate_derive): {ident}.\n\
Help: If you are trying to implement a new `generate_derive` trait, \
make sure to add it to the list in `abs_trait` function."
)
}