-
Notifications
You must be signed in to change notification settings - Fork 237
Decouple JSDoc from JavaScript grammar / Highlight examples #496
Conversation
This could risk triggering incorrect highlighting if a theme colours the
contents of interpolated `${ literal }` sequences.
|
/cc @50Wliu @bgriffith |
|
Oh look, another huge PR to review from @Alhadis 😁. I may need to punt this for a while to get a language-c rewrite merged first, as that grammar is in pretty bad shape right now. |
grammars/jsdoc.cson
Outdated
| '3': | ||
| 'name': 'entity.name.type.instance.jsdoc' | ||
| '4': | ||
| 'name': 'punctuation.definition.begin.jsdoc' |
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.
.bracket.angle
grammars/jsdoc.cson
Outdated
| 'match': '''(?x) | ||
| ((@)borrows) \\s+ | ||
| ((?:[^@\\s*/]|\\*[^/])++) # <that namepath> | ||
| \\s++ (as) \\s++ # as |
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 the possessive match?
grammars/jsdoc.cson
Outdated
| # URL | ||
| ( | ||
| (?=https?://) | ||
| (?:[^\\s*]|\\*[/])+ |
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 forwards slash in a character class? Did you perhaps forget a ^? I noticed it also looks different from all the other patterns similar to this one.
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.
Good catch, fixed.
grammars/jsdoc.cson
Outdated
| # JSDoc namepath | ||
| ( | ||
| (?!https?://) | ||
| (?:[^@\\s*/]|\\*[^/])++ |
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 possessive?
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.
Because I'm a possessive prick.
(removed)*+
| [A-Za-z_$] # First character: non-numeric word character | ||
| [\\w$.\\[\\]]* # Rest of identifier | ||
| (?: # Possible list of additional identifiers | ||
| \\s* , \\s* |
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 comma should be tokenized
grammars/jsdoc.cson
Outdated
| ] | ||
| } | ||
| ] | ||
|
|
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.
🔥 empty line
spec/jsdoc-spec.coffee
Outdated
| runs -> | ||
| grammar = atom.grammars.grammarForScopeName("source.js") | ||
|
|
||
|
|
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.
🔥 empty line
spec/jsdoc-spec.coffee
Outdated
| expect(tokens[1]).toEqual value: ' Text ', scopes: ['source.js', 'comment.block.documentation.js'] | ||
| expect(tokens[2]).toEqual value: '{@', scopes: ['source.js', 'comment.block.documentation.js', 'entity.name.type.instance.jsdoc', 'storage.type.class.jsdoc', 'punctuation.definition.inline.tag.begin.jsdoc'] | ||
| expect(tokens[3]).toEqual value: 'link', scopes: ['source.js', 'comment.block.documentation.js', 'entity.name.type.instance.jsdoc', 'storage.type.class.jsdoc'] | ||
| expect(tokens[4]).toEqual value: 'plain', scopes: ['source.js', 'comment.block.documentation.js', 'entity.name.type.instance.jsdoc', 'variable.other.description.jsdoc'] |
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.
This is interesting...shouldn't it be tokenized as linkplain and not separately?
spec/jsdoc-spec.coffee
Outdated
| expect(tokens[1]).toEqual value: ' Text ', scopes: ['source.js', 'comment.block.documentation.js'] | ||
| expect(tokens[2]).toEqual value: '{@', scopes: ['source.js', 'comment.block.documentation.js', 'entity.name.type.instance.jsdoc', 'storage.type.class.jsdoc', 'punctuation.definition.inline.tag.begin.jsdoc'] | ||
| expect(tokens[3]).toEqual value: 'link', scopes: ['source.js', 'comment.block.documentation.js', 'entity.name.type.instance.jsdoc', 'storage.type.class.jsdoc'] | ||
| expect(tokens[4]).toEqual value: 'code', scopes: ['source.js', 'comment.block.documentation.js', 'entity.name.type.instance.jsdoc', 'variable.other.description.jsdoc'] |
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.
Ditto
| expect(tokens[5]).toEqual value: '{', scopes: ['source.js', 'comment.block.documentation.js', 'entity.name.type.instance.jsdoc', 'punctuation.definition.bracket.curly.begin.jsdoc'] | ||
| expect(tokens[6]).toEqual value: '*', scopes: ['source.js', 'comment.block.documentation.js', 'entity.name.type.instance.jsdoc'] | ||
| expect(tokens[7]).toEqual value: '}', scopes: ['source.js', 'comment.block.documentation.js', 'entity.name.type.instance.jsdoc', 'punctuation.definition.bracket.curly.end.jsdoc'] | ||
| expect(tokens[9]).toEqual value: 'variable', scopes: ['source.js', 'comment.block.documentation.js', 'variab |
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.
🔥 empty line
|
Would it be worthwhile to tokenize default values as actual JS? |
|
Possibly, but that would likely leave us at the mercy of runaway |
|
... never mind, I said nothing. I shouldn't be allowed to communicate with humans until I've finished waking up. |
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.
Note: All I did was highlight instances of possessive matching. I'm unsure if any of those are intentional, if so, just ignore the comment.
grammars/jsdoc.cson
Outdated
| 'match': '''(?x) | ||
| ((@)borrows) \\s+ | ||
| ((?:[^@\\s*/]|\\*[^/])+) # <that namepath> | ||
| \\s++ (as) \\s+ # as |
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 forgot to remove the first possessive match on this line.
grammars/jsdoc.cson
Outdated
| } | ||
| { | ||
| 'name': 'entity.name.type.instance.jsdoc' | ||
| 'match': '(?:[^@\\s*/]|\\*[^/])++' |
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.
Possessive
grammars/jsdoc.cson
Outdated
| \\s+ | ||
| ( | ||
| [^@\\s<>*/] | ||
| (?:[^@<>*/]|\\*[^/])*+ |
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.
Possessive
grammars/jsdoc.cson
Outdated
| } | ||
| { | ||
| # Highlighted JavaScript example | ||
| 'match': '[^\\s@*](?:[^*]|\\*[^/])*+' |
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.
Possessive
grammars/jsdoc.cson
Outdated
| (?: | ||
| \\s* | ||
| (<) | ||
| ([^>\\s]++) |
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.
Possessive
|
Fixed. |
|
@50Wliu Urgh, I forgot to accommodate arrays when highlighting default values as JavaScript. Something like this will only be partially highlighted: /** @param {Object} [thing={a: [], b: [0, 2], c: "String"}] [Not Highlighted] [] [] [] */
^ Terminates hereCurrently working on a fix, although this is surprisingly tricky to get right... |
|
If it's too difficult/tricky to achieve just revert the embedded highlighting all together. |
|
No no, so far, so good... it's just that if users get too carried away with really convoluted complex values, they might get flaky-looking highlighting. Then again, if they're stuffing that much into a default value, what else do you expect? 😀 Heck, this might even discourage an anti-pattern, haha. |
|
Okay, fixed. Pleeeease don't chide me over the odd-looking way I've implemented this... :D Some repetition was necessary... |
Fixes #495.
Description of the Change
This PR separates the patterns for highlighting JSDoc tags from the main JavaScript grammar. The lookahead patterns currently responsible for this are inflicting severe performance issues in certain cases, which is to say nothing of the maintainability issues they've always imposed.
Additionally, I've also included inline JS highlighting for
@exampletags:Alternate Designs / Thoughts
@access \n privatereally didn't justify the added complexity.Benefits
Other than being much more readable and maintainable, I imagine this will boost the tokeniser's performance drastically. It might be interesting to benchmark.
Possible Drawbacks
In light of the countless intricacies of Closure Compiler, I've opted to match
{types}and@paramtags with an inclusive approach, rather than exclusive. Users will no longer be able to rely on what this grammar matches to indicate what syntax is valid. To be honest, I feel it's a fair trade-off... grammars shouldn't be responsible for validating input (at least beyond the scope of unclosed strings, etc).