-
-
Notifications
You must be signed in to change notification settings - Fork 313
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
Prototype for support of custom keywords #480
Conversation
First prototype for support of custom keywords with syn's new parsing API. Documentation and tests aren't present for now as I'm mainly reaching for feedback. This patch introduces a new Keyword trait, a new macro custom_keyword! and exposes the existing TokenMarker enum. The Keyword trait automatically implements the Token trait, making it possible to peek on custom keywords (this is why I had to make TokenMarker public). The custom macro generates a structure storing an Ident and implementing the Keyword and Parse traits. A function with the same name as the structure is also generated in order to use it like any predefined keyword.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I think this is broadly the right approach. Some suggestions:
-
Please do not add any public APIs other than
custom_keyword!
. Everything underneath is an implementation detail. This should also make your life easier when it comes to documentation. -
Please make custom keywords act as much as possible like builtin keywords. If you look at
Token![return]
for example there is a publicspan
field and several useful trait impls.
#[macro_export] | ||
macro_rules! custom_keyword { | ||
($ident:ident) => { | ||
custom_keyword_internal!({ pub(in self) } $ident); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is the default pub(in self)
rather than the usual default empty visibility? Actually is there any difference between empty visibility and in self
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The default is pub(in self)
because of an older version of the custom_keyword_internal!
macro, and I forgot to update this call, it can be safely removed. According to https://doc.rust-lang.org/rust-by-example/mod/visibility.html, empty visibility and in self
seem to have the same effect.
As an update: I worked a little on this and mostly struggled to come up with an acceptable solution. I'm starting to run out of ideas and I probably won't get to finish this before you release 0.15 so feel free to close this PR if you find a solution in the meantime.
By public API, do you mean 1) items exposed by the crate and visible in the generated documentation, or 2) an item exposed by the crate regardless of their documentation visibility ? Because I cannot see how it would be possible to hook into the
Regarding the Regarding the extra traits impls: because of the way |
Ah, to clarify: if something is hidden from docs, we don't need to consider it public API. I like to put a short I would be on board with re-exporting I imagine the cfg would be done as something like: macro_rules! custom_keyword {
/* ... */
clone_for_custom_keyword!(/* ... */);
extra_traits_for_custom_keyword!(/* ... */);
}
#[cfg(feature = "clone-impls")]
macro_rules! clone_for_custom_keyword { /* ... */ }
#[cfg(not(feature = "clone-impls"))]
macro_rules! clone_for_custom_keyword { /* expand to nothing */ }
#[cfg(feature = "extra-traits")]
macro_rules! extra_traits_for_custom_keyword { /* ... */ }
#[cfg(not(feature = "extra-traits"))]
macro_rules! extra_traits_for_custom_keyword { /* expand to nothing */ } |
Closing in favor of #481 which includes your commit. Thanks for getting the work started on this! |
Awesome, thanks a lot for getting this over the line! |
First prototype for support of custom keywords with syn's new parsing
API. Documentation and tests aren't present for now as I'm mainly
reaching for feedback.
This patch introduces a new Keyword trait, a new macro custom_keyword!
and exposes the existing TokenMarker enum. The Keyword trait
automatically implements the Token trait, making it possible to peek on
custom keywords (this is why I had to make TokenMarker public).
The custom macro generates a structure storing an Ident and implementing
the Keyword and Parse traits. A function with the same name as the
structure is also generated in order to use it like any predefined
keyword.
Unresolved questions:
Ref: #476