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) {
|
function parseTag(indent: number) {
|
||||||
Debug.assert(token() === SyntaxKind.AtToken);
|
Debug.assert(token() === SyntaxKind.AtToken);
|
||||||
const atToken = <AtToken>createNode(SyntaxKind.AtToken, scanner.getTokenPos());
|
const atToken = <AtToken>createNode(SyntaxKind.AtToken, scanner.getTokenPos());
|
||||||
|
@ -6514,7 +6533,7 @@ namespace ts {
|
||||||
nextJSDocToken();
|
nextJSDocToken();
|
||||||
|
|
||||||
const tagName = parseJSDocIdentifierName();
|
const tagName = parseJSDocIdentifierName();
|
||||||
skipWhitespace();
|
skipWhitespaceOrAsterisk();
|
||||||
|
|
||||||
let tag: JSDocTag | undefined;
|
let tag: JSDocTag | undefined;
|
||||||
switch (tagName.escapedText) {
|
switch (tagName.escapedText) {
|
||||||
|
@ -6658,7 +6677,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function tryParseTypeExpression(): JSDocTypeExpression | undefined {
|
function tryParseTypeExpression(): JSDocTypeExpression | undefined {
|
||||||
skipWhitespace();
|
skipWhitespaceOrAsterisk();
|
||||||
return token() === SyntaxKind.OpenBraceToken ? parseJSDocTypeExpression() : undefined;
|
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 {
|
function parseParameterOrPropertyTag(atToken: AtToken, tagName: Identifier, target: PropertyLikeParse, indent: number | undefined): JSDocParameterTag | JSDocPropertyTag {
|
||||||
let typeExpression = tryParseTypeExpression();
|
let typeExpression = tryParseTypeExpression();
|
||||||
let isNameFirst = !typeExpression;
|
let isNameFirst = !typeExpression;
|
||||||
skipWhitespace();
|
skipWhitespaceOrAsterisk();
|
||||||
|
|
||||||
const { name, isBracketed } = parseBracketNameInPropertyAndParamTag();
|
const { name, isBracketed } = parseBracketNameInPropertyAndParamTag();
|
||||||
skipWhitespace();
|
skipWhitespace();
|
||||||
|
|
|
@ -1933,6 +1933,7 @@ namespace ts {
|
||||||
|
|
||||||
function scanJSDocToken(): JsDocSyntaxKind {
|
function scanJSDocToken(): JsDocSyntaxKind {
|
||||||
startPos = tokenPos = pos;
|
startPos = tokenPos = pos;
|
||||||
|
tokenFlags = 0;
|
||||||
if (pos >= end) {
|
if (pos >= end) {
|
||||||
return token = SyntaxKind.EndOfFileToken;
|
return token = SyntaxKind.EndOfFileToken;
|
||||||
}
|
}
|
||||||
|
@ -1952,6 +1953,7 @@ namespace ts {
|
||||||
return token = SyntaxKind.AtToken;
|
return token = SyntaxKind.AtToken;
|
||||||
case CharacterCodes.lineFeed:
|
case CharacterCodes.lineFeed:
|
||||||
case CharacterCodes.carriageReturn:
|
case CharacterCodes.carriageReturn:
|
||||||
|
tokenFlags |= TokenFlags.PrecedingLineBreak;
|
||||||
return token = SyntaxKind.NewLineTrivia;
|
return token = SyntaxKind.NewLineTrivia;
|
||||||
case CharacterCodes.asterisk:
|
case CharacterCodes.asterisk:
|
||||||
return token = SyntaxKind.AsteriskToken;
|
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