Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Guidance on parsing proc-macro attributes #53

Open
Bromeon opened this issue Jan 31, 2024 · 3 comments
Open

Guidance on parsing proc-macro attributes #53

Bromeon opened this issue Jan 31, 2024 · 3 comments
Labels
question Further information is requested

Comments

@Bromeon
Copy link
Collaborator

Bromeon commented Jan 31, 2024

It's currently not obvious how venial should be used to parse a #[proc_macro_attribute] macro.

I typically used this pattern, where I simply treat the attribute macro as an attribute in the item.

use proc_macro::TokenStream;
use proc_macro2::TokenStream as TokenStream2;

#[proc_macro_attribute]
pub fn itest(meta: TokenStream, input: TokenStream) -> TokenStream {
    let self_name = format_ident!("itest"); // name of this function
    let input2 = TokenStream2::from(input);
    let meta2 = TokenStream2::from(meta);

    let input2 = quote! {
        #[#self_name(#meta2)]
        #input2
    };

    let result2 = venial::parse_declaration(input2)
    // now work with result2, as if it were a regular attribute
    ...
}

But this is not the only usage pattern. Sometimes people don't care about the attribute, and usually they want it removed from the output.

Do you think it makes sense to provide a dedicated API for this? For example:

// 1) above use case: macro becomes an attribute
pub fn parse_attribute_macro(
    meta: TokenStream,
    item: TokenStream,
    macro_name: &str,
) -> Result<Declaration, Error>;

and

// 2) separate meta and item -- former would just be left unparsed
pub fn parse_attribute_macro(
    meta: TokenStream,
    item: TokenStream,
) -> Result<(ValueExpr, Declaration), Error>;

Or should we rather document different approaches and guide the user towards parse_declaration()?

@Bromeon Bromeon added the question Further information is requested label Jan 31, 2024
@PoignardAzur
Copy link
Owner

PoignardAzur commented Feb 1, 2024

I'd rather have a function like parse_macro_attribute_stream that takes the "meta" TokenStream and returns a Result<Attribute, Err>, but I haven't given this a lot of thought.

@Bromeon
Copy link
Collaborator Author

Bromeon commented Feb 1, 2024

I'd rather have a function like parse_macro_attribute_stream that takes the "meta" TokenStream and returns a Result<Attribute, Err>, but I haven't given this a lot of thought.

The Attribute needs a name, so that would have to be passed in -- I could make a PR proposal here, should be easy to add.

@PoignardAzur
Copy link
Owner

That works. Just keep in mind that name wouldn't necessarily be accurate, since the actual invocation could use a path and you'd have no way to know.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants