Skip to content

Commit 0c9db71

Browse files
ajafffrbuckton
authored andcommitted
fix parsing of leading union/intersection operator (microsoft#31265)
* fix parsing of leading union/intersection operator Fixes: microsoft#30995 * test declaration emit
1 parent a2c1fea commit 0c9db71

8 files changed

+102
-5
lines changed

src/compiler/parser.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3124,15 +3124,16 @@ namespace ts {
31243124
}
31253125

31263126
function parseUnionOrIntersectionType(kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, parseConstituentType: () => TypeNode, operator: SyntaxKind.BarToken | SyntaxKind.AmpersandToken): TypeNode {
3127-
parseOptional(operator);
3127+
const start = scanner.getStartPos();
3128+
const hasLeadingOperator = parseOptional(operator);
31283129
let type = parseConstituentType();
3129-
if (token() === operator) {
3130+
if (token() === operator || hasLeadingOperator) {
31303131
const types = [type];
31313132
while (parseOptional(operator)) {
31323133
types.push(parseConstituentType());
31333134
}
3134-
const node = <UnionOrIntersectionTypeNode>createNode(kind, type.pos);
3135-
node.types = createNodeArray(types, type.pos);
3135+
const node = <UnionOrIntersectionTypeNode>createNode(kind, start);
3136+
node.types = createNodeArray(types, start);
31363137
type = finishNode(node);
31373138
}
31383139
return type;

src/testRunner/unittests/jsDocParsing.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ namespace ts {
3737
parsesCorrectly("callSignatureInRecordType", "{{(): number}}");
3838
parsesCorrectly("methodInRecordType", "{{foo(): number}}");
3939
parsesCorrectly("unionType", "{(number|string)}");
40+
parsesCorrectly("unionTypeWithLeadingOperator", "{( | number | string )}");
41+
parsesCorrectly("unionTypeWithOneElementAndLeadingOperator", "{( | number )}");
4042
parsesCorrectly("topLevelNoParenUnionType", "{number|string}");
4143
parsesCorrectly("functionType1", "{function()}");
4244
parsesCorrectly("functionType2", "{function(string, boolean)}");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"kind": "ParenthesizedType",
3+
"pos": 1,
4+
"end": 22,
5+
"flags": "JSDoc",
6+
"modifierFlagsCache": 0,
7+
"transformFlags": 0,
8+
"type": {
9+
"kind": "UnionType",
10+
"pos": 2,
11+
"end": 20,
12+
"flags": "JSDoc",
13+
"modifierFlagsCache": 0,
14+
"transformFlags": 0,
15+
"types": {
16+
"0": {
17+
"kind": "NumberKeyword",
18+
"pos": 4,
19+
"end": 11,
20+
"flags": "JSDoc",
21+
"modifierFlagsCache": 0,
22+
"transformFlags": 0
23+
},
24+
"1": {
25+
"kind": "StringKeyword",
26+
"pos": 13,
27+
"end": 20,
28+
"flags": "JSDoc",
29+
"modifierFlagsCache": 0,
30+
"transformFlags": 0
31+
},
32+
"length": 2,
33+
"pos": 2,
34+
"end": 20
35+
}
36+
}
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"kind": "ParenthesizedType",
3+
"pos": 1,
4+
"end": 13,
5+
"flags": "JSDoc",
6+
"modifierFlagsCache": 0,
7+
"transformFlags": 0,
8+
"type": {
9+
"kind": "UnionType",
10+
"pos": 2,
11+
"end": 11,
12+
"flags": "JSDoc",
13+
"modifierFlagsCache": 0,
14+
"transformFlags": 0,
15+
"types": {
16+
"0": {
17+
"kind": "NumberKeyword",
18+
"pos": 4,
19+
"end": 11,
20+
"flags": "JSDoc",
21+
"modifierFlagsCache": 0,
22+
"transformFlags": 0
23+
},
24+
"length": 1,
25+
"pos": 2,
26+
"end": 11
27+
}
28+
}
29+
}

tests/baselines/reference/unionTypeWithLeadingOperator.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,16 @@ type B =
55
| { type: "DECREMENT" };
66

77
type C = [| 0 | 1, | "foo" | "bar"];
8-
8+
9+
export type D =
10+
/*leading0*/
11+
| /*leading1*/ 1 /*trailing1*/
12+
| /*leading2*/ 2 /*trailing2*/;
913

1014
//// [unionTypeWithLeadingOperator.js]
15+
"use strict";
16+
exports.__esModule = true;
17+
18+
19+
//// [unionTypeWithLeadingOperator.d.ts]
20+
export declare type D = /*leading1*/ 1 | /*leading2*/ 2;

tests/baselines/reference/unionTypeWithLeadingOperator.symbols

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,9 @@ type B =
1414
type C = [| 0 | 1, | "foo" | "bar"];
1515
>C : Symbol(C, Decl(unionTypeWithLeadingOperator.ts, 3, 26))
1616

17+
export type D =
18+
>D : Symbol(D, Decl(unionTypeWithLeadingOperator.ts, 5, 36))
19+
20+
/*leading0*/
21+
| /*leading1*/ 1 /*trailing1*/
22+
| /*leading2*/ 2 /*trailing2*/;

tests/baselines/reference/unionTypeWithLeadingOperator.types

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,9 @@ type B =
1414
type C = [| 0 | 1, | "foo" | "bar"];
1515
>C : [0 | 1, "foo" | "bar"]
1616

17+
export type D =
18+
>D : D
19+
20+
/*leading0*/
21+
| /*leading1*/ 1 /*trailing1*/
22+
| /*leading2*/ 2 /*trailing2*/;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1+
// @declaration: true
12
type A = | string;
23
type B =
34
| { type: "INCREMENT" }
45
| { type: "DECREMENT" };
56

67
type C = [| 0 | 1, | "foo" | "bar"];
8+
9+
export type D =
10+
/*leading0*/
11+
| /*leading1*/ 1 /*trailing1*/
12+
| /*leading2*/ 2 /*trailing2*/;

0 commit comments

Comments
 (0)