Skip to content

Commit 9a65658

Browse files
authored
Parse *= separately in types (microsoft#39457)
* Parse *= separately in types Previously, when the scanner produced `*=` as a single token, the type parser ran special-case code to produce an "optional all type", which only makes sense when the `=` really should be attached to the `*`. This is often not the case. The correct solution, which I missed when I first wrote this code, is to have the scanner go back and produce a separate `=` token, which is what this PR does. * add test from microsoft#38551 * we ❤️ semicolons
1 parent c12d431 commit 9a65658

File tree

7 files changed

+39
-17
lines changed

7 files changed

+39
-17
lines changed

src/compiler/parser.ts

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2701,19 +2701,10 @@ namespace ts {
27012701
return finishNode(factory.createThisTypeNode(), pos);
27022702
}
27032703

2704-
function parseJSDocAllType(postFixEquals: boolean): JSDocAllType | JSDocOptionalType {
2704+
function parseJSDocAllType(): JSDocAllType | JSDocOptionalType {
27052705
const pos = getNodePos();
27062706
nextToken();
2707-
2708-
const node = factory.createJSDocAllType();
2709-
if (postFixEquals) {
2710-
// Trim the trailing `=` from the `*=` token
2711-
const end = Math.max(getNodePos() - 1, pos);
2712-
return finishNode(factory.createJSDocOptionalType(finishNode(node, pos, end)), pos);
2713-
}
2714-
else {
2715-
return finishNode(node, pos);
2716-
}
2707+
return finishNode(factory.createJSDocAllType(), pos);
27172708
}
27182709

27192710
function parseJSDocNonNullableType(): TypeNode {
@@ -3396,12 +3387,14 @@ namespace ts {
33963387
case SyntaxKind.ObjectKeyword:
33973388
// If these are followed by a dot, then parse these out as a dotted type reference instead.
33983389
return tryParse(parseKeywordAndNoDot) || parseTypeReference();
3399-
case SyntaxKind.AsteriskToken:
3400-
return parseJSDocAllType(/*postfixEquals*/ false);
34013390
case SyntaxKind.AsteriskEqualsToken:
3402-
return parseJSDocAllType(/*postfixEquals*/ true);
3391+
// If there is '*=', treat it as * followed by postfix =
3392+
scanner.reScanAsteriskEqualsToken();
3393+
// falls through
3394+
case SyntaxKind.AsteriskToken:
3395+
return parseJSDocAllType();
34033396
case SyntaxKind.QuestionQuestionToken:
3404-
// If there is '??', consider that is prefix '?' in JSDoc type.
3397+
// If there is '??', treat it as prefix-'?' in JSDoc type.
34053398
scanner.reScanQuestionToken();
34063399
// falls through
34073400
case SyntaxKind.QuestionToken:

src/compiler/scanner.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ namespace ts {
3434
getTokenFlags(): TokenFlags;
3535
reScanGreaterToken(): SyntaxKind;
3636
reScanSlashToken(): SyntaxKind;
37+
reScanAsteriskEqualsToken(): SyntaxKind;
3738
reScanTemplateToken(isTaggedTemplate: boolean): SyntaxKind;
3839
reScanTemplateHeadOrNoSubstitutionTemplate(): SyntaxKind;
3940
scanJsxIdentifier(): SyntaxKind;
@@ -954,6 +955,7 @@ namespace ts {
954955
getNumericLiteralFlags: () => tokenFlags & TokenFlags.NumericLiteralFlags,
955956
getTokenFlags: () => tokenFlags,
956957
reScanGreaterToken,
958+
reScanAsteriskEqualsToken,
957959
reScanSlashToken,
958960
reScanTemplateToken,
959961
reScanTemplateHeadOrNoSubstitutionTemplate,
@@ -2086,6 +2088,12 @@ namespace ts {
20862088
return token;
20872089
}
20882090

2091+
function reScanAsteriskEqualsToken(): SyntaxKind {
2092+
Debug.assert(token === SyntaxKind.AsteriskEqualsToken, "'reScanAsteriskEqualsToken' should only be called on a '*='");
2093+
pos = tokenPos + 1;
2094+
return token = SyntaxKind.EqualsToken;
2095+
}
2096+
20892097
function reScanSlashToken(): SyntaxKind {
20902098
if (token === SyntaxKind.SlashToken || token === SyntaxKind.SlashEqualsToken) {
20912099
let p = tokenPos + 1;

tests/baselines/reference/api/tsserverlibrary.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3902,6 +3902,7 @@ declare namespace ts {
39023902
isUnterminated(): boolean;
39033903
reScanGreaterToken(): SyntaxKind;
39043904
reScanSlashToken(): SyntaxKind;
3905+
reScanAsteriskEqualsToken(): SyntaxKind;
39053906
reScanTemplateToken(isTaggedTemplate: boolean): SyntaxKind;
39063907
reScanTemplateHeadOrNoSubstitutionTemplate(): SyntaxKind;
39073908
scanJsxIdentifier(): SyntaxKind;

tests/baselines/reference/api/typescript.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3902,6 +3902,7 @@ declare namespace ts {
39023902
isUnterminated(): boolean;
39033903
reScanGreaterToken(): SyntaxKind;
39043904
reScanSlashToken(): SyntaxKind;
3905+
reScanAsteriskEqualsToken(): SyntaxKind;
39053906
reScanTemplateToken(isTaggedTemplate: boolean): SyntaxKind;
39063907
reScanTemplateHeadOrNoSubstitutionTemplate(): SyntaxKind;
39073908
scanJsxIdentifier(): SyntaxKind;

tests/baselines/reference/jsdocParseStarEquals.symbols

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,10 @@ function f(...args) {
1212
var x;
1313
>x : Symbol(x, Decl(a.js, 7, 3))
1414

15+
16+
/** @param {function():*=} f */
17+
function cbf(f) {
18+
>cbf : Symbol(cbf, Decl(a.js, 7, 6))
19+
>f : Symbol(f, Decl(a.js, 11, 13))
20+
}
21+

tests/baselines/reference/jsdocParseStarEquals.types

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
/** @param {...*=} args
33
@return {*=} */
44
function f(...args) {
5-
>f : (...args: (any | undefined)[]) => any | undefined
6-
>args : any[]
5+
>f : (...args?: any[] | undefined) => any | undefined
6+
>args : any
77

88
return null
99
>null : null
@@ -13,3 +13,10 @@ function f(...args) {
1313
var x;
1414
>x : any
1515

16+
17+
/** @param {function():*=} f */
18+
function cbf(f) {
19+
>cbf : (f?: (() => any) | undefined) => void
20+
>f : (() => any) | undefined
21+
}
22+

tests/cases/conformance/jsdoc/jsdocParseStarEquals.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,8 @@ function f(...args) {
1212

1313
/** @type *= */
1414
var x;
15+
16+
17+
/** @param {function():*=} f */
18+
function cbf(f) {
19+
}

0 commit comments

Comments
 (0)