Giter Site home page Giter Site logo

Support attributes about rune HOT 11 OPEN

udoprog avatar udoprog commented on August 23, 2024 2
Support attributes

from rune.

Comments (11)

killercup avatar killercup commented on August 23, 2024

FYI, this is one of the main things I dislike in Rust's syntax because of the typing overhead and the fact that pretty much any tokens are valid in #[here]. Using @Foo(param=foo) (or #[Foo(param=foo)] if you like typing braces) and supporting exactly this style of calling a macro would reduce complexity quite a bit.

from rune.

udoprog avatar udoprog commented on August 23, 2024

FYI, this is one of the main things I dislike in Rust's syntax because of the typing overhead and the fact that pretty much any tokens are valid in #[here]. Using @Foo(param=foo) (or #[Foo(param=foo)] if you like typing braces) and supporting exactly this style of calling a macro would reduce complexity quite a bit.

I appreciate the point of view. But this is another instance when I want to maintain feature parity with Rust to make it possible to more easily transfer ideas. A note is that attributes are pretty much macro calls with different call syntax (and are associated with the AST they are tacked on to). You can see this in syn, with the Macro (macro call) and Attribute. They both take a Path and a raw TokenStream.

syn also provides a convenience function to parse its content as meta items. Something like this can be done to unobtrusively enforce more opinion. Or something like darling can be ported to Rune.

from rune.

ModProg avatar ModProg commented on August 23, 2024

Might look into this in the next few days, what should be the input of a function handling a macro? everything after the path? or should it only be the "input" as it is in rust: https://doc.rust-lang.org/reference/procedural-macros.html#attribute-macros i.e. if you call #[attribute(some_input)] the macro implementation would only get some_input and not (some_input).

from rune.

udoprog avatar udoprog commented on August 23, 2024

Doing it in the same way as Rust sounds good to me.

from rune.

ModProg avatar ModProg commented on August 23, 2024

this would mean, that a macro could not detect whether they got #[path(...)], #[path[...]], #[path={...} or #[path = ...] . Though I guess that should be fine, as it would be strange to have a different behavior depending on the exact syntax used to invoke (similar to how normal macros also don't differentiate`.

from rune.

udoprog avatar udoprog commented on August 23, 2024

I think so, all though I must admit I'm not sure what happens with the #[path = ..] variant 😅. I'm guessing .. is what's being fed in? The = is mentioned in the reference as part of meta syntax. Or is it not supported for proc-macro's?

from rune.

ModProg avatar ModProg commented on August 23, 2024

IIRC it is not supported for the actual macro, only for it's helper macros.

I guess this information could also just be added to the AttributeMacroContext.
I.e. outer vs inner, what kind of delimiter was used etc., though I could also see an argument be made that this is just preference of the macro user, and the macro dev shouldn't try to enforce anything.

AFAICT we need to have a bunch of seperate types for the attribute macros anyway, as they e.g. in the AttributeMacroContext would need to have input_span and item_span instead of only stream_span.

As we have builtin ast which is different from rust's proc-macros, we could also have the attribute macro input be something like syn's https://docs.rs/syn/latest/syn/enum.Meta.html instead of a plain token_stream.

from rune.

udoprog avatar udoprog commented on August 23, 2024

As we have builtin ast which is different from rust's proc-macros, we could also have the attribute macro input be something like syn's https://docs.rs/syn/latest/syn/enum.Meta.html instead of a plain token_stream.

I'd be a bit careful with that. Even in Rust a meta item is only defined to the extent that it is used as a convention for most built-in macros. I frequently include things which is not valid meta type syntax in macros (types, patterns, bounds, ...). If a macro wants the meta syntax, they can opt to parse it out and there's really no difference in diagnostics.

If I'm being honest, I'd probably prefer specialized AST constructs derived in many cases instead of using generic containers such as syn::Meta (which you'd need to decompose / parse further anyway). Many attribute parsing needs can then be done by derives, like:

// Parses `= "<string>"` in an a `#[path]` attribute.
#[derive(Parse, ToTokens, Spanned)]
pub struct PathValue(T![=], LitStr);

The benefit here is that instead of having to match out syn::Meta::NameValue and match out its expression to a literal string or raise an error, that happens during the first round of parsing instead.

from rune.

ModProg avatar ModProg commented on August 23, 2024

I'd be a bit careful with that. Even in Rust a meta item is only defined to the extent that it is used as a convention for most built-in macros. I frequently include things which is not valid meta type syntax in macros (types, patterns, bounds, ...). If a macro wants the meta syntax, they can opt to parse it out and there's really no difference in diagnostics.

Actually in syn2, the MetaList variant contains unparsed tokenstreams, so it would only enforce that the top level macro matches meta which (at least in rust) is enforced by the syntax itself, but I agree that having the derived Parse is quite nice, and you would lose that when preparsed in some way.

Another place where this question arises is with the item, as an attribute macro can be applied only to valid items (and attributes themselves also to modules, statements and fields/params) the item could also be forwarded in it's parsed form, though the same argument could be applied here, that one could want to call ItemFn::parse directly instead of matching on the Item.

from rune.

ModProg avatar ModProg commented on August 23, 2024

One future question is, should macros be able to have helper attributes, like rust derive macros have? I.e. attributes that will be ignored when not in scope instead of raising an error.

In rust, only derive macros can have them, attribute macros need to clean them up themselves.

from rune.

udoprog avatar udoprog commented on August 23, 2024

Derive macros should definitely declare and have their helper attributes cleaned up by the compiler. The reason there would be that other than removing those attributes the original item remains untouched. Anything added is added as separate items after it. It can safely be punted on, since I don't think there's any particular infrastructure overlap in the compiler between the two, but I might be wrong! Unless you want to implement derives as well.

For attribute macros, do what Rust does basically 😄 (unless there's a really good reason). Which I think amounts to "follow a top to bottom expansion order, unless nested macros are present". But no helper attributes.

from rune.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.