Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 0f8c1f7

Browse filesBrowse files
committed
Fix emit for optional chain with non-null assertion
1 parent ad8feb5 commit 0f8c1f7
Copy full SHA for 0f8c1f7

File tree

Expand file treeCollapse file tree

14 files changed

+108
-11
lines changed
Filter options
Expand file treeCollapse file tree

14 files changed

+108
-11
lines changed

‎src/compiler/parser.ts

Copy file name to clipboardExpand all lines: src/compiler/parser.ts
+12-4Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4685,12 +4685,20 @@ namespace ts {
46854685
&& lookAhead(nextTokenIsIdentifierOrKeywordOrOpenBracketOrTemplate);
46864686
}
46874687

4688+
function hasOptionalChain(node: Node) {
4689+
while (true) {
4690+
if (node.flags & NodeFlags.OptionalChain) return true;
4691+
if (!isNonNullExpression(node)) return false;
4692+
node = node.expression;
4693+
}
4694+
}
4695+
46884696
function parsePropertyAccessExpressionRest(expression: LeftHandSideExpression, questionDotToken: QuestionDotToken | undefined) {
46894697
const propertyAccess = <PropertyAccessExpression>createNode(SyntaxKind.PropertyAccessExpression, expression.pos);
46904698
propertyAccess.expression = expression;
46914699
propertyAccess.questionDotToken = questionDotToken;
46924700
propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ true);
4693-
if (questionDotToken || expression.flags & NodeFlags.OptionalChain) {
4701+
if (questionDotToken || hasOptionalChain(expression)) {
46944702
propertyAccess.flags |= NodeFlags.OptionalChain;
46954703
if (isPrivateIdentifier(propertyAccess.name)) {
46964704
parseErrorAtRange(propertyAccess.name, Diagnostics.An_optional_chain_cannot_contain_private_identifiers);
@@ -4716,7 +4724,7 @@ namespace ts {
47164724
}
47174725

47184726
parseExpected(SyntaxKind.CloseBracketToken);
4719-
if (questionDotToken || expression.flags & NodeFlags.OptionalChain) {
4727+
if (questionDotToken || hasOptionalChain(expression)) {
47204728
indexedAccess.flags |= NodeFlags.OptionalChain;
47214729
}
47224730
return finishNode(indexedAccess);
@@ -4803,7 +4811,7 @@ namespace ts {
48034811
callExpr.questionDotToken = questionDotToken;
48044812
callExpr.typeArguments = typeArguments;
48054813
callExpr.arguments = parseArgumentList();
4806-
if (questionDotToken || expression.flags & NodeFlags.OptionalChain) {
4814+
if (questionDotToken || hasOptionalChain(expression)) {
48074815
callExpr.flags |= NodeFlags.OptionalChain;
48084816
}
48094817
expression = finishNode(callExpr);
@@ -4815,7 +4823,7 @@ namespace ts {
48154823
callExpr.expression = expression;
48164824
callExpr.questionDotToken = questionDotToken;
48174825
callExpr.arguments = parseArgumentList();
4818-
if (questionDotToken || expression.flags & NodeFlags.OptionalChain) {
4826+
if (questionDotToken || hasOptionalChain(expression)) {
48194827
callExpr.flags |= NodeFlags.OptionalChain;
48204828
}
48214829
expression = finishNode(callExpr);

‎src/compiler/transformers/es2020.ts

Copy file name to clipboardExpand all lines: src/compiler/transformers/es2020.ts
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ namespace ts {
4444
function flattenChain(chain: OptionalChain) {
4545
const links: OptionalChain[] = [chain];
4646
while (!chain.questionDotToken && !isTaggedTemplateExpression(chain)) {
47-
chain = cast(chain.expression, isOptionalChain);
47+
chain = cast(skipPartiallyEmittedExpressions(chain.expression), isOptionalChain);
4848
links.unshift(chain);
4949
}
5050
return { expression: chain.expression, chain: links };

‎tests/baselines/reference/callChain.js

Copy file name to clipboardExpand all lines: tests/baselines/reference/callChain.js
+6-1Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,10 @@ const v: number | undefined = o4?.(incr);
3535

3636
// GH#33744
3737
declare const o5: <T>() => undefined | (() => void);
38-
o5<number>()?.();
38+
o5<number>()?.();
39+
40+
// GH#36031
41+
o2?.b()!.toString
3942

4043
//// [callChain.js]
4144
"use strict";
@@ -73,3 +76,5 @@ o2 === null || o2 === void 0 ? void 0 : o2["b"].apply(o2, __spreadArrays([1], [2
7376
(_m = o3["b"]) === null || _m === void 0 ? void 0 : _m.call.apply(_m, __spreadArrays([o3, 1], [2, 3], [4])).c;
7477
var v = o4 === null || o4 === void 0 ? void 0 : o4(incr);
7578
(_o = o5()) === null || _o === void 0 ? void 0 : _o();
79+
// GH#36031
80+
o2 === null || o2 === void 0 ? void 0 : o2.b().toString;

‎tests/baselines/reference/callChain.symbols

Copy file name to clipboardExpand all lines: tests/baselines/reference/callChain.symbols
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,3 +156,11 @@ declare const o5: <T>() => undefined | (() => void);
156156
o5<number>()?.();
157157
>o5 : Symbol(o5, Decl(callChain.ts, 35, 13))
158158

159+
// GH#36031
160+
o2?.b()!.toString
161+
>o2?.b()!.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
162+
>o2?.b : Symbol(b, Decl(callChain.ts, 6, 31))
163+
>o2 : Symbol(o2, Decl(callChain.ts, 6, 13))
164+
>b : Symbol(b, Decl(callChain.ts, 6, 31))
165+
>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
166+

‎tests/baselines/reference/callChain.types

Copy file name to clipboardExpand all lines: tests/baselines/reference/callChain.types
+10Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,3 +264,13 @@ o5<number>()?.();
264264
>o5<number>() : (() => void) | undefined
265265
>o5 : <T>() => (() => void) | undefined
266266

267+
// GH#36031
268+
o2?.b()!.toString
269+
>o2?.b()!.toString : (radix?: number | undefined) => string
270+
>o2?.b()! : number
271+
>o2?.b() : number | undefined
272+
>o2?.b : ((...args: any[]) => number) | undefined
273+
>o2 : { b: (...args: any[]) => number; } | undefined
274+
>b : ((...args: any[]) => number) | undefined
275+
>toString : (radix?: number | undefined) => string
276+

‎tests/baselines/reference/elementAccessChain.js

Copy file name to clipboardExpand all lines: tests/baselines/reference/elementAccessChain.js
+8-1Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@ o5["b"]?.()["c"].d?.["e"];
2222

2323
// GH#33744
2424
declare const o6: <T>() => undefined | ({ x: number });
25-
o6<number>()?.["x"];
25+
o6<number>()?.["x"];
26+
27+
// GH#36031
28+
o2?.["b"]!.c
29+
o2?.["b"]!["c"]
2630

2731
//// [elementAccessChain.js]
2832
"use strict";
@@ -39,3 +43,6 @@ o2 === null || o2 === void 0 ? void 0 : o2.b["c"];
3943
(_m = (_l = o5["b"]) === null || _l === void 0 ? void 0 : _l.call(o5)["c"].d) === null || _m === void 0 ? void 0 : _m.e;
4044
(_p = (_o = o5["b"]) === null || _o === void 0 ? void 0 : _o.call(o5)["c"].d) === null || _p === void 0 ? void 0 : _p["e"];
4145
(_q = o6()) === null || _q === void 0 ? void 0 : _q["x"];
46+
// GH#36031
47+
o2 === null || o2 === void 0 ? void 0 : o2["b"].c;
48+
o2 === null || o2 === void 0 ? void 0 : o2["b"]["c"];

‎tests/baselines/reference/elementAccessChain.symbols

Copy file name to clipboardExpand all lines: tests/baselines/reference/elementAccessChain.symbols
+10Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,13 @@ declare const o6: <T>() => undefined | ({ x: number });
106106
o6<number>()?.["x"];
107107
>o6 : Symbol(o6, Decl(elementAccessChain.ts, 22, 13))
108108

109+
// GH#36031
110+
o2?.["b"]!.c
111+
>o2?.["b"]!.c : Symbol(c, Decl(elementAccessChain.ts, 3, 36))
112+
>o2 : Symbol(o2, Decl(elementAccessChain.ts, 3, 13))
113+
>c : Symbol(c, Decl(elementAccessChain.ts, 3, 36))
114+
115+
o2?.["b"]!["c"]
116+
>o2 : Symbol(o2, Decl(elementAccessChain.ts, 3, 13))
117+
>"c" : Symbol(c, Decl(elementAccessChain.ts, 3, 36))
118+

‎tests/baselines/reference/elementAccessChain.types

Copy file name to clipboardExpand all lines: tests/baselines/reference/elementAccessChain.types
+17Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,3 +141,20 @@ o6<number>()?.["x"];
141141
>o6 : <T>() => { x: number; } | undefined
142142
>"x" : "x"
143143

144+
// GH#36031
145+
o2?.["b"]!.c
146+
>o2?.["b"]!.c : string
147+
>o2?.["b"]! : { c: string; }
148+
>o2?.["b"] : { c: string; } | undefined
149+
>o2 : { b: { c: string; }; } | undefined
150+
>"b" : "b"
151+
>c : string
152+
153+
o2?.["b"]!["c"]
154+
>o2?.["b"]!["c"] : string
155+
>o2?.["b"]! : { c: string; }
156+
>o2?.["b"] : { c: string; } | undefined
157+
>o2 : { b: { c: string; }; } | undefined
158+
>"b" : "b"
159+
>"c" : "c"
160+

‎tests/baselines/reference/propertyAccessChain.js

Copy file name to clipboardExpand all lines: tests/baselines/reference/propertyAccessChain.js
+6-1Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ declare const o6: <T>() => undefined | ({ x: number });
1919
o6<number>()?.x;
2020

2121
// GH#34109
22-
o1?.b ? 1 : 0;
22+
o1?.b ? 1 : 0;
23+
24+
// GH#36031
25+
o2?.b!.c
2326

2427
//// [propertyAccessChain.js]
2528
"use strict";
@@ -32,3 +35,5 @@ o2 === null || o2 === void 0 ? void 0 : o2.b.c;
3235
(_f = o6()) === null || _f === void 0 ? void 0 : _f.x;
3336
// GH#34109
3437
(o1 === null || o1 === void 0 ? void 0 : o1.b) ? 1 : 0;
38+
// GH#36031
39+
o2 === null || o2 === void 0 ? void 0 : o2.b.c;

‎tests/baselines/reference/propertyAccessChain.symbols

Copy file name to clipboardExpand all lines: tests/baselines/reference/propertyAccessChain.symbols
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,11 @@ o1?.b ? 1 : 0;
8585
>o1 : Symbol(o1, Decl(propertyAccessChain.ts, 0, 13))
8686
>b : Symbol(b, Decl(propertyAccessChain.ts, 0, 31))
8787

88+
// GH#36031
89+
o2?.b!.c
90+
>o2?.b!.c : Symbol(c, Decl(propertyAccessChain.ts, 3, 36))
91+
>o2?.b : Symbol(b, Decl(propertyAccessChain.ts, 3, 31))
92+
>o2 : Symbol(o2, Decl(propertyAccessChain.ts, 3, 13))
93+
>b : Symbol(b, Decl(propertyAccessChain.ts, 3, 31))
94+
>c : Symbol(c, Decl(propertyAccessChain.ts, 3, 36))
95+

‎tests/baselines/reference/propertyAccessChain.types

Copy file name to clipboardExpand all lines: tests/baselines/reference/propertyAccessChain.types
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,12 @@ o1?.b ? 1 : 0;
8989
>1 : 1
9090
>0 : 0
9191

92+
// GH#36031
93+
o2?.b!.c
94+
>o2?.b!.c : string
95+
>o2?.b! : { c: string; }
96+
>o2?.b : { c: string; } | undefined
97+
>o2 : { b: { c: string; }; } | undefined
98+
>b : { c: string; } | undefined
99+
>c : string
100+

‎tests/cases/conformance/expressions/optionalChaining/callChain/callChain.ts

Copy file name to clipboardExpand all lines: tests/cases/conformance/expressions/optionalChaining/callChain/callChain.ts
+4-1Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,7 @@ const v: number | undefined = o4?.(incr);
3636

3737
// GH#33744
3838
declare const o5: <T>() => undefined | (() => void);
39-
o5<number>()?.();
39+
o5<number>()?.();
40+
41+
// GH#36031
42+
o2?.b()!.toString

‎tests/cases/conformance/expressions/optionalChaining/elementAccessChain/elementAccessChain.ts

Copy file name to clipboardExpand all lines: tests/cases/conformance/expressions/optionalChaining/elementAccessChain/elementAccessChain.ts
+5-1Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,8 @@ o5["b"]?.()["c"].d?.["e"];
2323

2424
// GH#33744
2525
declare const o6: <T>() => undefined | ({ x: number });
26-
o6<number>()?.["x"];
26+
o6<number>()?.["x"];
27+
28+
// GH#36031
29+
o2?.["b"]!.c
30+
o2?.["b"]!["c"]

‎tests/cases/conformance/expressions/optionalChaining/propertyAccessChain/propertyAccessChain.ts

Copy file name to clipboardExpand all lines: tests/cases/conformance/expressions/optionalChaining/propertyAccessChain/propertyAccessChain.ts
+4-1Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,7 @@ declare const o6: <T>() => undefined | ({ x: number });
2020
o6<number>()?.x;
2121

2222
// GH#34109
23-
o1?.b ? 1 : 0;
23+
o1?.b ? 1 : 0;
24+
25+
// GH#36031
26+
o2?.b!.c

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.