Handle namepaths inside JSDoc type expressions a bit better #32563
Conversation
| while (token() !== SyntaxKind.CloseBraceToken && token() !== SyntaxKind.EndOfFileToken) { | ||
| nextTokenJSDoc(); | ||
| } | ||
| type = finishNode(moduleTag); |
There was a problem hiding this comment.
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); |
| 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.
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.
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.
|
|
sandersn
left a comment
There was a problem hiding this comment.
I would prefer a switch over an array created on each call to parseJSDocType.
| 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.
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.
Makes sense! Good point.
| 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.
| while (terminators.indexOf(token()) < 0) { | |
| terminate: while (true) { | |
| switch(token()) { | |
| case SyntaxKind.CloseBraceToken: // etc | |
| break terminate; | |
| } |
There was a problem hiding this comment.
I love it, this is the only project I've ever had PR suggestions where people recommend goto.
|
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.