-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Handle namepaths inside JSDoc type expressions a bit better #32563
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
Conversation
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.
Couple of changes.
src/compiler/parser.ts
Outdated
while (token() !== SyntaxKind.CloseBraceToken && token() !== SyntaxKind.EndOfFileToken) { | ||
nextTokenJSDoc(); | ||
} | ||
type = finishNode(moduleTag); |
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 whole thing should actually come first and be a completely separate code path. Here we call parseTypeOrTypePredicate
(and allow prefix ...
) in the namepath case, which is wrong.
type = finishNode(moduleTag); | |
return finishNode(moduleTag); |
src/compiler/parser.ts
Outdated
let type = parseTypeOrTypePredicate(); | ||
scanner.setInJSDocType(false); | ||
if (moduleSpecifier) { | ||
const moduleTag = createNode(SyntaxKind.JSDocNamepathType, moduleSpecifier.pos) as JSDocNamepathType; | ||
while (token() !== SyntaxKind.CloseBraceToken && token() !== SyntaxKind.EndOfFileToken) { |
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.
I realised that parseJSDocType is also called from parseJSDocParameter, not just single type expressions. That means its right terminators include ,
and )
See the ParsingContext.JSDocParameters
entry in isListTerminator
.
That also means that we need tests for jsdoc-style functions:
/** @type {function(module:xxxx, module:xxxx): module:xxxxx} */
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.
I'm not sure whether jsdoc.app mentions whether namepaths can be used in function types, but I think we should support it even if it does not.
|
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.
I would prefer a switch over an array created on each call to parseJSDocType.
src/compiler/parser.ts
Outdated
const moduleSpecifier = parseOptionalToken(SyntaxKind.ModuleKeyword); | ||
if (moduleSpecifier) { | ||
const moduleTag = createNode(SyntaxKind.JSDocNamepathType, moduleSpecifier.pos) as JSDocNamepathType; | ||
const terminators = [SyntaxKind.CloseBraceToken, SyntaxKind.EndOfFileToken, SyntaxKind.CommaToken, SyntaxKind.CloseParenToken, SyntaxKind.WhitespaceTrivia]; |
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 new array+member approach feels like it creates unnecessary garbage in a path that may happen a lot.
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.
Makes sense! Good point.
src/compiler/parser.ts
Outdated
if (moduleSpecifier) { | ||
const moduleTag = createNode(SyntaxKind.JSDocNamepathType, moduleSpecifier.pos) as JSDocNamepathType; | ||
const terminators = [SyntaxKind.CloseBraceToken, SyntaxKind.EndOfFileToken, SyntaxKind.CommaToken, SyntaxKind.CloseParenToken, SyntaxKind.WhitespaceTrivia]; | ||
while (terminators.indexOf(token()) < 0) { |
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.
while (terminators.indexOf(token()) < 0) { | |
terminate: while (true) { | |
switch(token()) { | |
case SyntaxKind.CloseBraceToken: // etc | |
break terminate; | |
} |
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.
I love it, this is the only project I've ever had PR suggestions where people recommend goto
.
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.
Gotta go fast!
Will fix that up tomorrow 👍 |
Fixes #31298
Adds a way for the parser to move the scanner through a namepath inside JSDoc so that it can continue to parse the rest of the statement correctly and show up right in an editor.