Fix infinite loop in jsdoc parsing (#17420)

* Test case

* Move parameter fix to apply to jsdoc (and all lists)

* Inline function, generalize comment
This commit is contained in:
Wesley Wigham 2017-07-26 10:12:59 -07:00 committed by GitHub
parent a59db13004
commit 5b77ef8b4d
3 changed files with 30 additions and 9 deletions

View File

@ -1865,9 +1865,12 @@ namespace ts {
let commaStart = -1; // Meaning the previous token was not a comma
while (true) {
if (isListElement(kind, /*inErrorRecovery*/ false)) {
const startPos = scanner.getStartPos();
result.push(parseListElement(kind, parseElement));
commaStart = scanner.getTokenPos();
if (parseOptional(SyntaxKind.CommaToken)) {
// No need to check for a zero length node since we know we parsed a comma
continue;
}
@ -1888,6 +1891,13 @@ namespace ts {
if (considerSemicolonAsDelimiter && token() === SyntaxKind.SemicolonToken && !scanner.hasPrecedingLineBreak()) {
nextToken();
}
if (startPos === scanner.getStartPos()) {
// What we're parsing isn't actually remotely recognizable as a element and we've consumed no tokens whatsoever
// Consume a token to advance the parser in some way and avoid an infinite loop
// This can happen when we're speculatively parsing parenthesized expressions which we think may be arrow functions,
// or when a modifier keyword which is disallowed as a parameter name (ie, `static` in strict mode) is supplied
nextToken();
}
continue;
}
@ -2221,7 +2231,6 @@ namespace ts {
return finishNode(node);
}
const startPos = scanner.getStartPos();
node.decorators = parseDecorators();
node.modifiers = parseModifiers();
node.dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken);
@ -2245,14 +2254,6 @@ namespace ts {
node.type = parseParameterType();
node.initializer = parseBindingElementInitializer(/*inParameter*/ true);
if (startPos === scanner.getStartPos()) {
// What we're parsing isn't actually remotely recognizable as a parameter and we've consumed no tokens whatsoever
// Consume a token to advance the parser in some way and avoid an infinite loop in `parseDelimitedList`
// This can happen when we're speculatively parsing parenthesized expressions which we think may be arrow functions,
// or when a modifier keyword which is disallowed as a parameter name (ie, `static` in strict mode) is supplied
nextToken();
}
return addJSDocComment(finishNode(node));
}

View File

@ -0,0 +1,11 @@
tests/cases/compiler/example.js(3,20): error TS1003: Identifier expected.
==== tests/cases/compiler/example.js (1 errors) ====
// @ts-check
/**
* @type {function(@foo)}
~
!!! error TS1003: Identifier expected.
*/
let x;

View File

@ -0,0 +1,9 @@
// @filename: example.js
// @checkJs: true
// @allowJs: true
// @noEmit: true
// @ts-check
/**
* @type {function(@foo)}
*/
let x;