-
Notifications
You must be signed in to change notification settings - Fork 104
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
Generalize attribute syntax #93
Conversation
I think backwards compatibility is not a concern since Rust's grammar is still evolving and this project doesn't promise to be stable (still in the 0.x releases). For highlighting, selection and editing purposes, it shouldn't make a difference if those items are considered a meta-item or something else, as long as it's consumable. People's queries might need some slight update, but that's to be expected given the reasons I mentioned at the beginning.
Can you go over why this isn't a "perfect solution"? What would be one? I am thinking you implied this work is "imperfect" because you couldn't decide which way to go, but I would personally lean towards interpreting the word as referring to something "incomplete". Is that the case? Is the implementation not fully done for what you wanted to do, or what's the meaning of "imperfect" here? EDIT: Forgot to comment
I think solution 3 is the best if this is right. |
I was hoping for a solution that wouldn't change any existing successful parse results. If breaking changes are allowable, then option 3 seems fine to me. It does produce more consistent & accurate-to-spec results. Its only other disadvantage is that the resulting parse (which consists of just nested tokentrees) isn't as useful to consumers as the meta-item grammar, which has more structure; consumers who did make use of the meta-item grammar would have to re-parse the attr's arguments. (A similar workflow is used in |
tree-sitter has Injections (https://tree-sitter.github.io/tree-sitter/syntax-highlighting#language-injection). One could "re-inject" the Rust parser inside of arbitrary nodes in order to parse them further. It's something I use, in practice, for highlighting interpolated code inside of JS strings. It's supported by the API already, but I don't know about how common of a practice this is. Re-reading the OP
I think 2 is a suitable solution as well, given this reasoning. If nothing's missing then you could move it out of Draft (AFAIK it's generally for unfinished work). |
Personally, I'd prefer option 3 if practical, since re-parsing attr arguments as the desired type is a cleaner interface than having to branch on whether the arguments are Regardless, there are still design decisions to make: should the type of non-meta attr arguments be This PR is also currently blocked by #96, which introduces some of the same grammar productions (general token trees) and should be a much simpler/less controversial change. |
@ninevra found this comment about reparsing on another issue The injections are also showcased in the queries here. Yet another situation is what I've described in #93 (comment). |
@ninevra @resolritter this looks like a great PR. Would you mind rebasing on the latest to avoid the conflicts? |
6f5e5fb
to
f27d28b
Compare
Supports the syntax added in the extended_key_value_attributes feature.
f27d28b
to
467fd2c
Compare
@aryx I've rebased this and updated it to reflect (afaict) the current spec, adding support for |
@@ -35,6 +35,54 @@ const numeric_types = [ | |||
|
|||
const primitive_types = numeric_types.concat(['bool', 'str', 'char']) | |||
|
|||
const built_in_attributes = [ |
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.
Would it be possible to add a link to a section of the rust reference manual that lists those builtin attributes?
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.
Sure? I'm not sure how best to do that given this PR has already been merged - should I create a second PR for that and any other changes that might be requested on review?
The reference section is https://doc.rust-lang.org/reference/attributes.html#built-in-attributes-index.
Keeping this updated is a little more complicated than checking that list; according to the current reference, only "most" built-in attributes follow the meta item syntax (although I haven't yet found one that doesn't), and additionally there may be other well-known attributes (e.g. tool attributes) that do use the meta item syntax.
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.
You can make a second PR, or maybe because it's a small thing, you can fix it when you make another PR for fixing another problem.
I attempted to fix #92. I didn't find a perfect solution; here's the resulting code, in case maintainers are interested.
I considered several approaches:
meta-items
iff they match themeta-item
syntax, and as generalattrs
otherwise. This preserves backwards compatibility, but creates a highly ambiguous grammar, since anymeta-item
is also a validattr
. I played around withprec()
,conflicts
, andprec.dynamic()
but wasn't able to resolve the ambiguity correctly. Someone more familiar with LR/GLR parsing might be able to? In-progress code at https://github.com/ninevra/tree-sitter-rust/tree/ambiguitiy-and-precedence.meta-items
, and all others asattrs
. This breaks backwards compatibility in that some custom attributes previously successfully parsed asmeta-items
and will now parse asattrs
. It's arguably more correct than (1), since only built-in attributes are actually restricted to themeta-item
syntax (see Stabilizeunrestricted_attribute_tokens
rust-lang/rust#57367, Tracking issue for future-incompatibility lintill_formed_attribute_input
rust-lang/rust#57571). This is the approach taken in this PR.meta-item
grammar at all and just useattr
. This is fairly trivial, and I'd be happy to implement it if anyone wants. Breaks backwards compatibility for all attributes.Are any of these options worth pursuing further?