diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 38a341eaa5a..c6dd6a769eb 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -886,7 +886,7 @@ namespace ts { /** Invokes the provided callback then unconditionally restores the parser to the state it * was in immediately prior to invoking the callback. The result of invoking the callback - * is returned from this function. + * is returned from this function. */ function lookAhead(callback: () => T): T { return speculationHelper(callback, /*isLookAhead*/ true); @@ -4988,7 +4988,7 @@ namespace ts { if (token === SyntaxKind.ConstKeyword && permitInvalidConstAsModifier) { // We need to ensure that any subsequent modifiers appear on the same line - // so that when 'const' is a standalone declaration, we don't issue an error. + // so that when 'const' is a standalone declaration, we don't issue an error. if (!tryParse(nextTokenIsOnSameLineAndCanFollowModifier)) { break; } @@ -5251,7 +5251,7 @@ namespace ts { node.decorators = decorators; setModifiers(node, modifiers); if (token === SyntaxKind.GlobalKeyword) { - // parse 'global' as name of global scope augmentation + // parse 'global' as name of global scope augmentation node.name = parseIdentifier(); node.flags |= NodeFlags.GlobalAugmentation; } @@ -6087,7 +6087,7 @@ namespace ts { atToken.end = scanner.getTextPos(); nextJSDocToken(); - const tagName = parseJSDocIdentifier(); + const tagName = parseJSDocIdentifierName(); if (!tagName) { return; } @@ -6150,7 +6150,7 @@ namespace ts { let isBracketed: boolean; // Looking for something like '[foo]' or 'foo' if (parseOptionalToken(SyntaxKind.OpenBracketToken)) { - name = parseJSDocIdentifier(); + name = parseJSDocIdentifierName(); isBracketed = true; // May have an optional default, e.g. '[foo = 42]' @@ -6160,8 +6160,8 @@ namespace ts { parseExpected(SyntaxKind.CloseBracketToken); } - else if (token === SyntaxKind.Identifier) { - name = parseJSDocIdentifier(); + else if (tokenIsIdentifierOrKeyword(token)) { + name = parseJSDocIdentifierName(); } if (!name) { @@ -6225,7 +6225,7 @@ namespace ts { typeParameters.pos = scanner.getStartPos(); while (true) { - const name = parseJSDocIdentifier(); + const name = parseJSDocIdentifierName(); if (!name) { parseErrorAtPosition(scanner.getStartPos(), 0, Diagnostics.Identifier_expected); return undefined; @@ -6258,8 +6258,12 @@ namespace ts { return token = scanner.scanJSDocToken(); } - function parseJSDocIdentifier(): Identifier { - if (token !== SyntaxKind.Identifier) { + function parseJSDocIdentifierName(): Identifier { + return createJSDocIdentifier(tokenIsIdentifierOrKeyword(token)); + } + + function createJSDocIdentifier(isIdentifier: boolean): Identifier { + if (!isIdentifier) { parseErrorAtCurrentToken(Diagnostics.Identifier_expected); return undefined; } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index b97ad70a74a..db906c57067 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -435,7 +435,7 @@ namespace ts { const { line: startLine } = getLineAndCharacterOfPosition(sourceFile, node.body.pos); const { line: endLine } = getLineAndCharacterOfPosition(sourceFile, node.body.end); if (startLine < endLine) { - // The arrow function spans multiple lines, + // The arrow function spans multiple lines, // make the error span be the first line, inclusive. return createTextSpan(pos, getEndLinePosition(startLine, sourceFile) - pos + 1); } @@ -1301,10 +1301,10 @@ namespace ts { if (node.jsDocComment) { return node.jsDocComment; } - // Try to recognize this pattern when node is initializer of variable declaration and JSDoc comments are on containing variable statement. - // /** + // Try to recognize this pattern when node is initializer of variable declaration and JSDoc comments are on containing variable statement. + // /** // * @param {number} name - // * @returns {number} + // * @returns {number} // */ // var x = function(name) { return name.length; } if (checkParentVariableStatement) { diff --git a/tests/cases/fourslash/server/jsdocParamTagSpecialKeywords.ts b/tests/cases/fourslash/server/jsdocParamTagSpecialKeywords.ts new file mode 100644 index 00000000000..be7ca5f0dff --- /dev/null +++ b/tests/cases/fourslash/server/jsdocParamTagSpecialKeywords.ts @@ -0,0 +1,14 @@ +/// + +// @allowNonTsExtensions: true +// @Filename: test.js +//// /** +//// * @param {string} type +//// */ +//// function test(type) { +//// type./**/ +//// } + + +goTo.marker(); +verify.completionListContains("charAt"); \ No newline at end of file