Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
fix parsing of leading union/intersection operator (#31265)
* fix parsing of leading union/intersection operator

Fixes: #30995

* test declaration emit
  • Loading branch information
ajafff authored and rbuckton committed May 8, 2019
1 parent a2c1fea commit 0c9db71
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 5 deletions.
9 changes: 5 additions & 4 deletions src/compiler/parser.ts
Expand Up @@ -3124,15 +3124,16 @@ namespace ts {
}

function parseUnionOrIntersectionType(kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, parseConstituentType: () => TypeNode, operator: SyntaxKind.BarToken | SyntaxKind.AmpersandToken): TypeNode {
parseOptional(operator);
const start = scanner.getStartPos();
const hasLeadingOperator = parseOptional(operator);
let type = parseConstituentType();
if (token() === operator) {
if (token() === operator || hasLeadingOperator) {
const types = [type];
while (parseOptional(operator)) {
types.push(parseConstituentType());
}
const node = <UnionOrIntersectionTypeNode>createNode(kind, type.pos);
node.types = createNodeArray(types, type.pos);
const node = <UnionOrIntersectionTypeNode>createNode(kind, start);
node.types = createNodeArray(types, start);
type = finishNode(node);
}
return type;
Expand Down
2 changes: 2 additions & 0 deletions src/testRunner/unittests/jsDocParsing.ts
Expand Up @@ -37,6 +37,8 @@ namespace ts {
parsesCorrectly("callSignatureInRecordType", "{{(): number}}");
parsesCorrectly("methodInRecordType", "{{foo(): number}}");
parsesCorrectly("unionType", "{(number|string)}");
parsesCorrectly("unionTypeWithLeadingOperator", "{( | number | string )}");
parsesCorrectly("unionTypeWithOneElementAndLeadingOperator", "{( | number )}");
parsesCorrectly("topLevelNoParenUnionType", "{number|string}");
parsesCorrectly("functionType1", "{function()}");
parsesCorrectly("functionType2", "{function(string, boolean)}");
Expand Down
@@ -0,0 +1,37 @@
{
"kind": "ParenthesizedType",
"pos": 1,
"end": 22,
"flags": "JSDoc",
"modifierFlagsCache": 0,
"transformFlags": 0,
"type": {
"kind": "UnionType",
"pos": 2,
"end": 20,
"flags": "JSDoc",
"modifierFlagsCache": 0,
"transformFlags": 0,
"types": {
"0": {
"kind": "NumberKeyword",
"pos": 4,
"end": 11,
"flags": "JSDoc",
"modifierFlagsCache": 0,
"transformFlags": 0
},
"1": {
"kind": "StringKeyword",
"pos": 13,
"end": 20,
"flags": "JSDoc",
"modifierFlagsCache": 0,
"transformFlags": 0
},
"length": 2,
"pos": 2,
"end": 20
}
}
}
@@ -0,0 +1,29 @@
{
"kind": "ParenthesizedType",
"pos": 1,
"end": 13,
"flags": "JSDoc",
"modifierFlagsCache": 0,
"transformFlags": 0,
"type": {
"kind": "UnionType",
"pos": 2,
"end": 11,
"flags": "JSDoc",
"modifierFlagsCache": 0,
"transformFlags": 0,
"types": {
"0": {
"kind": "NumberKeyword",
"pos": 4,
"end": 11,
"flags": "JSDoc",
"modifierFlagsCache": 0,
"transformFlags": 0
},
"length": 1,
"pos": 2,
"end": 11
}
}
}
12 changes: 11 additions & 1 deletion tests/baselines/reference/unionTypeWithLeadingOperator.js
Expand Up @@ -5,6 +5,16 @@ type B =
| { type: "DECREMENT" };

type C = [| 0 | 1, | "foo" | "bar"];


export type D =
/*leading0*/
| /*leading1*/ 1 /*trailing1*/
| /*leading2*/ 2 /*trailing2*/;

//// [unionTypeWithLeadingOperator.js]
"use strict";
exports.__esModule = true;


//// [unionTypeWithLeadingOperator.d.ts]
export declare type D = /*leading1*/ 1 | /*leading2*/ 2;
Expand Up @@ -14,3 +14,9 @@ type B =
type C = [| 0 | 1, | "foo" | "bar"];
>C : Symbol(C, Decl(unionTypeWithLeadingOperator.ts, 3, 26))

export type D =
>D : Symbol(D, Decl(unionTypeWithLeadingOperator.ts, 5, 36))

/*leading0*/
| /*leading1*/ 1 /*trailing1*/
| /*leading2*/ 2 /*trailing2*/;
6 changes: 6 additions & 0 deletions tests/baselines/reference/unionTypeWithLeadingOperator.types
Expand Up @@ -14,3 +14,9 @@ type B =
type C = [| 0 | 1, | "foo" | "bar"];
>C : [0 | 1, "foo" | "bar"]

export type D =
>D : D

/*leading0*/
| /*leading1*/ 1 /*trailing1*/
| /*leading2*/ 2 /*trailing2*/;
6 changes: 6 additions & 0 deletions tests/cases/compiler/unionTypeWithLeadingOperator.ts
@@ -1,6 +1,12 @@
// @declaration: true
type A = | string;
type B =
| { type: "INCREMENT" }
| { type: "DECREMENT" };

type C = [| 0 | 1, | "foo" | "bar"];

export type D =
/*leading0*/
| /*leading1*/ 1 /*trailing1*/
| /*leading2*/ 2 /*trailing2*/;

0 comments on commit 0c9db71

Please sign in to comment.