Skip whitespace or asterisk in JSDoc param type and name (#26067)
This commit is contained in:
parent
746e39e9e9
commit
6fd725f3ea
|
@ -6507,6 +6507,25 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function skipWhitespaceOrAsterisk(): void {
|
||||
if (token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) {
|
||||
if (lookAhead(isNextNonwhitespaceTokenEndOfFile)) {
|
||||
return; // Don't skip whitespace prior to EoF (or end of comment) - that shouldn't be included in any node's range
|
||||
}
|
||||
}
|
||||
|
||||
let precedingLineBreak = scanner.hasPrecedingLineBreak();
|
||||
while ((precedingLineBreak && token() === SyntaxKind.AsteriskToken) || token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) {
|
||||
if (token() === SyntaxKind.NewLineTrivia) {
|
||||
precedingLineBreak = true;
|
||||
}
|
||||
else if (token() === SyntaxKind.AsteriskToken) {
|
||||
precedingLineBreak = false;
|
||||
}
|
||||
nextJSDocToken();
|
||||
}
|
||||
}
|
||||
|
||||
function parseTag(indent: number) {
|
||||
Debug.assert(token() === SyntaxKind.AtToken);
|
||||
const atToken = <AtToken>createNode(SyntaxKind.AtToken, scanner.getTokenPos());
|
||||
|
@ -6514,7 +6533,7 @@ namespace ts {
|
|||
nextJSDocToken();
|
||||
|
||||
const tagName = parseJSDocIdentifierName();
|
||||
skipWhitespace();
|
||||
skipWhitespaceOrAsterisk();
|
||||
|
||||
let tag: JSDocTag | undefined;
|
||||
switch (tagName.escapedText) {
|
||||
|
@ -6658,7 +6677,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function tryParseTypeExpression(): JSDocTypeExpression | undefined {
|
||||
skipWhitespace();
|
||||
skipWhitespaceOrAsterisk();
|
||||
return token() === SyntaxKind.OpenBraceToken ? parseJSDocTypeExpression() : undefined;
|
||||
}
|
||||
|
||||
|
@ -6698,7 +6717,7 @@ namespace ts {
|
|||
function parseParameterOrPropertyTag(atToken: AtToken, tagName: Identifier, target: PropertyLikeParse, indent: number | undefined): JSDocParameterTag | JSDocPropertyTag {
|
||||
let typeExpression = tryParseTypeExpression();
|
||||
let isNameFirst = !typeExpression;
|
||||
skipWhitespace();
|
||||
skipWhitespaceOrAsterisk();
|
||||
|
||||
const { name, isBracketed } = parseBracketNameInPropertyAndParamTag();
|
||||
skipWhitespace();
|
||||
|
|
|
@ -1933,6 +1933,7 @@ namespace ts {
|
|||
|
||||
function scanJSDocToken(): JsDocSyntaxKind {
|
||||
startPos = tokenPos = pos;
|
||||
tokenFlags = 0;
|
||||
if (pos >= end) {
|
||||
return token = SyntaxKind.EndOfFileToken;
|
||||
}
|
||||
|
@ -1952,6 +1953,7 @@ namespace ts {
|
|||
return token = SyntaxKind.AtToken;
|
||||
case CharacterCodes.lineFeed:
|
||||
case CharacterCodes.carriageReturn:
|
||||
tokenFlags |= TokenFlags.PrecedingLineBreak;
|
||||
return token = SyntaxKind.NewLineTrivia;
|
||||
case CharacterCodes.asterisk:
|
||||
return token = SyntaxKind.AsteriskToken;
|
||||
|
|
58
tests/baselines/reference/paramTagWrapping.errors.txt
Normal file
58
tests/baselines/reference/paramTagWrapping.errors.txt
Normal file
|
@ -0,0 +1,58 @@
|
|||
tests/cases/conformance/jsdoc/bad.js(2,11): error TS1003: Identifier expected.
|
||||
tests/cases/conformance/jsdoc/bad.js(2,11): error TS8024: JSDoc '@param' tag has name '', but there is no parameter with that name.
|
||||
tests/cases/conformance/jsdoc/bad.js(5,4): error TS1003: Identifier expected.
|
||||
tests/cases/conformance/jsdoc/bad.js(5,4): error TS8024: JSDoc '@param' tag has name '', but there is no parameter with that name.
|
||||
tests/cases/conformance/jsdoc/bad.js(6,19): error TS1003: Identifier expected.
|
||||
tests/cases/conformance/jsdoc/bad.js(6,19): error TS8024: JSDoc '@param' tag has name '', but there is no parameter with that name.
|
||||
tests/cases/conformance/jsdoc/bad.js(9,14): error TS7006: Parameter 'x' implicitly has an 'any' type.
|
||||
tests/cases/conformance/jsdoc/bad.js(9,17): error TS7006: Parameter 'y' implicitly has an 'any' type.
|
||||
tests/cases/conformance/jsdoc/bad.js(9,20): error TS7006: Parameter 'z' implicitly has an 'any' type.
|
||||
|
||||
|
||||
==== tests/cases/conformance/jsdoc/good.js (0 errors) ====
|
||||
/**
|
||||
* @param
|
||||
* {number} x Arg x.
|
||||
* @param {number}
|
||||
* y Arg y.
|
||||
* @param {number} z
|
||||
* Arg z.
|
||||
*/
|
||||
function good(x, y, z) {
|
||||
}
|
||||
|
||||
good(1, 2, 3)
|
||||
|
||||
|
||||
==== tests/cases/conformance/jsdoc/bad.js (9 errors) ====
|
||||
/**
|
||||
* @param *
|
||||
|
||||
!!! error TS1003: Identifier expected.
|
||||
|
||||
!!! error TS8024: JSDoc '@param' tag has name '', but there is no parameter with that name.
|
||||
* {number} x Arg x.
|
||||
* @param {number}
|
||||
* * y Arg y.
|
||||
|
||||
!!! error TS1003: Identifier expected.
|
||||
|
||||
!!! error TS8024: JSDoc '@param' tag has name '', but there is no parameter with that name.
|
||||
* @param {number} * z
|
||||
|
||||
!!! error TS1003: Identifier expected.
|
||||
|
||||
!!! error TS8024: JSDoc '@param' tag has name '', but there is no parameter with that name.
|
||||
* Arg z.
|
||||
*/
|
||||
function bad(x, y, z) {
|
||||
~
|
||||
!!! error TS7006: Parameter 'x' implicitly has an 'any' type.
|
||||
~
|
||||
!!! error TS7006: Parameter 'y' implicitly has an 'any' type.
|
||||
~
|
||||
!!! error TS7006: Parameter 'z' implicitly has an 'any' type.
|
||||
}
|
||||
|
||||
bad(1, 2, 3)
|
||||
|
39
tests/baselines/reference/paramTagWrapping.symbols
Normal file
39
tests/baselines/reference/paramTagWrapping.symbols
Normal file
|
@ -0,0 +1,39 @@
|
|||
=== tests/cases/conformance/jsdoc/good.js ===
|
||||
/**
|
||||
* @param
|
||||
* {number} x Arg x.
|
||||
* @param {number}
|
||||
* y Arg y.
|
||||
* @param {number} z
|
||||
* Arg z.
|
||||
*/
|
||||
function good(x, y, z) {
|
||||
>good : Symbol(good, Decl(good.js, 0, 0))
|
||||
>x : Symbol(x, Decl(good.js, 8, 14))
|
||||
>y : Symbol(y, Decl(good.js, 8, 16))
|
||||
>z : Symbol(z, Decl(good.js, 8, 19))
|
||||
}
|
||||
|
||||
good(1, 2, 3)
|
||||
>good : Symbol(good, Decl(good.js, 0, 0))
|
||||
|
||||
|
||||
=== tests/cases/conformance/jsdoc/bad.js ===
|
||||
/**
|
||||
* @param *
|
||||
* {number} x Arg x.
|
||||
* @param {number}
|
||||
* * y Arg y.
|
||||
* @param {number} * z
|
||||
* Arg z.
|
||||
*/
|
||||
function bad(x, y, z) {
|
||||
>bad : Symbol(bad, Decl(bad.js, 0, 0))
|
||||
>x : Symbol(x, Decl(bad.js, 8, 13))
|
||||
>y : Symbol(y, Decl(bad.js, 8, 15))
|
||||
>z : Symbol(z, Decl(bad.js, 8, 18))
|
||||
}
|
||||
|
||||
bad(1, 2, 3)
|
||||
>bad : Symbol(bad, Decl(bad.js, 0, 0))
|
||||
|
47
tests/baselines/reference/paramTagWrapping.types
Normal file
47
tests/baselines/reference/paramTagWrapping.types
Normal file
|
@ -0,0 +1,47 @@
|
|||
=== tests/cases/conformance/jsdoc/good.js ===
|
||||
/**
|
||||
* @param
|
||||
* {number} x Arg x.
|
||||
* @param {number}
|
||||
* y Arg y.
|
||||
* @param {number} z
|
||||
* Arg z.
|
||||
*/
|
||||
function good(x, y, z) {
|
||||
>good : (x: number, y: number, z: number) => void
|
||||
>x : number
|
||||
>y : number
|
||||
>z : number
|
||||
}
|
||||
|
||||
good(1, 2, 3)
|
||||
>good(1, 2, 3) : void
|
||||
>good : (x: number, y: number, z: number) => void
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
>3 : 3
|
||||
|
||||
|
||||
=== tests/cases/conformance/jsdoc/bad.js ===
|
||||
/**
|
||||
* @param *
|
||||
* {number} x Arg x.
|
||||
* @param {number}
|
||||
* * y Arg y.
|
||||
* @param {number} * z
|
||||
* Arg z.
|
||||
*/
|
||||
function bad(x, y, z) {
|
||||
>bad : (x: any, y: any, z: any) => void
|
||||
>x : any
|
||||
>y : any
|
||||
>z : any
|
||||
}
|
||||
|
||||
bad(1, 2, 3)
|
||||
>bad(1, 2, 3) : void
|
||||
>bad : (x: any, y: any, z: any) => void
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
>3 : 3
|
||||
|
35
tests/cases/conformance/jsdoc/paramTagWrapping.ts
Normal file
35
tests/cases/conformance/jsdoc/paramTagWrapping.ts
Normal file
|
@ -0,0 +1,35 @@
|
|||
// @noEmit: true
|
||||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @strict: true
|
||||
|
||||
// @Filename: good.js
|
||||
|
||||
/**
|
||||
* @param
|
||||
* {number} x Arg x.
|
||||
* @param {number}
|
||||
* y Arg y.
|
||||
* @param {number} z
|
||||
* Arg z.
|
||||
*/
|
||||
function good(x, y, z) {
|
||||
}
|
||||
|
||||
good(1, 2, 3)
|
||||
|
||||
|
||||
// @Filename: bad.js
|
||||
|
||||
/**
|
||||
* @param *
|
||||
* {number} x Arg x.
|
||||
* @param {number}
|
||||
* * y Arg y.
|
||||
* @param {number} * z
|
||||
* Arg z.
|
||||
*/
|
||||
function bad(x, y, z) {
|
||||
}
|
||||
|
||||
bad(1, 2, 3)
|
Loading…
Reference in a new issue