Skip to content

Commit e4497b8

Browse files
authored
Merge pull request #1 from dragomirtitian/nullish-coalescing-operator
Nullish coalescing operator
2 parents fb0d3c9 + 65b2008 commit e4497b8

11 files changed

+369
-4
lines changed

src/compiler/transformers/esnext.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
/*@internal*/
22
namespace ts {
33
export function transformESNext(context: TransformationContext) {
4+
const {
5+
hoistVariableDeclaration,
6+
} = context;
7+
48
return chainBundle(transformSourceFile);
59

610
function transformSourceFile(node: SourceFile) {
@@ -40,7 +44,7 @@ namespace ts {
4044
const expressions: Expression[] = [];
4145
let left = visitNode(node.left, visitor, isExpression);
4246
if (!isIdentifier(left)) {
43-
const temp = createTempVariable(/*recordTempVariable*/ undefined);
47+
const temp = createTempVariable(hoistVariableDeclaration);
4448
expressions.push(createAssignment(temp, left));
4549
left = temp;
4650
}

tests/baselines/reference/nullishCoalescingOperator3.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ const aa1 = a1 ?? a2 ?? a3 ?? a4 ?? a5 ?? a6 ?? 'whatever'
1111

1212

1313
//// [nullishCoalescingOperator3.js]
14+
var _a, _b, _c, _d, _e;
1415
"use strict";
15-
var aa1 = (_a = (_b = (_c = (_d = (_e = typeof a1 !== "undefined" && a1 !== null ? a1 : a2, _e !== void 0 && _e !== null ? _e : a3), _d !== void 0 && _d !== null ? _d : a4), _c !== void 0 && _c !== null ? _c : a5), _b !== void 0 && _b !== null ? _b : a6), _a !== void 0 && _a !== null ? _a : 'whatever');
16+
var aa1 = (_e = (_d = (_c = (_b = (_a = typeof a1 !== "undefined" && a1 !== null ? a1 : a2, _a !== void 0 && _a !== null ? _a : a3), _b !== void 0 && _b !== null ? _b : a4), _c !== void 0 && _c !== null ? _c : a5), _d !== void 0 && _d !== null ? _d : a6), _e !== void 0 && _e !== null ? _e : 'whatever');

tests/baselines/reference/nullishCoalescingOperator5.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ a && (b ?? c);
4141

4242

4343
//// [nullishCoalescingOperator5.js]
44+
var _a, _b, _c, _d;
4445
"use strict";
4546
// should be a syntax error
4647
typeof a !== "undefined" && a !== null ? a : b || c;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//// [nullishCoalescingOperator8.ts]
2+
declare const a: { p: string | undefined, m(): string | undefined };
3+
declare const b: { p: string | undefined, m(): string | undefined };
4+
5+
const n1 = a.p ?? "default";
6+
const n2 = a.m() ?? "default";
7+
const n3 = a.m() ?? b.p ?? b.m() ?? "default";;
8+
9+
10+
//// [nullishCoalescingOperator8.js]
11+
var _a, _b, _c, _d, _e;
12+
"use strict";
13+
var n1 = (_a = a.p, _a !== void 0 && _a !== null ? _a : "default");
14+
var n2 = (_b = a.m(), _b !== void 0 && _b !== null ? _b : "default");
15+
var n3 = (_e = (_d = (_c = a.m(), _c !== void 0 && _c !== null ? _c : b.p), _d !== void 0 && _d !== null ? _d : b.m()), _e !== void 0 && _e !== null ? _e : "default");
16+
;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
=== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator8.ts ===
2+
declare const a: { p: string | undefined, m(): string | undefined };
3+
>a : Symbol(a, Decl(nullishCoalescingOperator8.ts, 0, 13))
4+
>p : Symbol(p, Decl(nullishCoalescingOperator8.ts, 0, 18))
5+
>m : Symbol(m, Decl(nullishCoalescingOperator8.ts, 0, 41))
6+
7+
declare const b: { p: string | undefined, m(): string | undefined };
8+
>b : Symbol(b, Decl(nullishCoalescingOperator8.ts, 1, 13))
9+
>p : Symbol(p, Decl(nullishCoalescingOperator8.ts, 1, 18))
10+
>m : Symbol(m, Decl(nullishCoalescingOperator8.ts, 1, 41))
11+
12+
const n1 = a.p ?? "default";
13+
>n1 : Symbol(n1, Decl(nullishCoalescingOperator8.ts, 3, 5))
14+
>a.p : Symbol(p, Decl(nullishCoalescingOperator8.ts, 0, 18))
15+
>a : Symbol(a, Decl(nullishCoalescingOperator8.ts, 0, 13))
16+
>p : Symbol(p, Decl(nullishCoalescingOperator8.ts, 0, 18))
17+
18+
const n2 = a.m() ?? "default";
19+
>n2 : Symbol(n2, Decl(nullishCoalescingOperator8.ts, 4, 5))
20+
>a.m : Symbol(m, Decl(nullishCoalescingOperator8.ts, 0, 41))
21+
>a : Symbol(a, Decl(nullishCoalescingOperator8.ts, 0, 13))
22+
>m : Symbol(m, Decl(nullishCoalescingOperator8.ts, 0, 41))
23+
24+
const n3 = a.m() ?? b.p ?? b.m() ?? "default";;
25+
>n3 : Symbol(n3, Decl(nullishCoalescingOperator8.ts, 5, 5))
26+
>a.m : Symbol(m, Decl(nullishCoalescingOperator8.ts, 0, 41))
27+
>a : Symbol(a, Decl(nullishCoalescingOperator8.ts, 0, 13))
28+
>m : Symbol(m, Decl(nullishCoalescingOperator8.ts, 0, 41))
29+
>b.p : Symbol(p, Decl(nullishCoalescingOperator8.ts, 1, 18))
30+
>b : Symbol(b, Decl(nullishCoalescingOperator8.ts, 1, 13))
31+
>p : Symbol(p, Decl(nullishCoalescingOperator8.ts, 1, 18))
32+
>b.m : Symbol(m, Decl(nullishCoalescingOperator8.ts, 1, 41))
33+
>b : Symbol(b, Decl(nullishCoalescingOperator8.ts, 1, 13))
34+
>m : Symbol(m, Decl(nullishCoalescingOperator8.ts, 1, 41))
35+
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
=== tests/cases/conformance/expressions/nullishCoalescingOperator/nullishCoalescingOperator8.ts ===
2+
declare const a: { p: string | undefined, m(): string | undefined };
3+
>a : { p: string | undefined; m(): string | undefined; }
4+
>p : string | undefined
5+
>m : () => string | undefined
6+
7+
declare const b: { p: string | undefined, m(): string | undefined };
8+
>b : { p: string | undefined; m(): string | undefined; }
9+
>p : string | undefined
10+
>m : () => string | undefined
11+
12+
const n1 = a.p ?? "default";
13+
>n1 : string
14+
>a.p ?? "default" : string
15+
>a.p : string | undefined
16+
>a : { p: string | undefined; m(): string | undefined; }
17+
>p : string | undefined
18+
>"default" : "default"
19+
20+
const n2 = a.m() ?? "default";
21+
>n2 : string
22+
>a.m() ?? "default" : string
23+
>a.m() : string | undefined
24+
>a.m : () => string | undefined
25+
>a : { p: string | undefined; m(): string | undefined; }
26+
>m : () => string | undefined
27+
>"default" : "default"
28+
29+
const n3 = a.m() ?? b.p ?? b.m() ?? "default";;
30+
>n3 : string
31+
>a.m() ?? b.p ?? b.m() ?? "default" : string
32+
>a.m() ?? b.p ?? b.m() : string | undefined
33+
>a.m() ?? b.p : string | undefined
34+
>a.m() : string | undefined
35+
>a.m : () => string | undefined
36+
>a : { p: string | undefined; m(): string | undefined; }
37+
>m : () => string | undefined
38+
>b.p : string | undefined
39+
>b : { p: string | undefined; m(): string | undefined; }
40+
>p : string | undefined
41+
>b.m() : string | undefined
42+
>b.m : () => string | undefined
43+
>b : { p: string | undefined; m(): string | undefined; }
44+
>m : () => string | undefined
45+
>"default" : "default"
46+

tests/baselines/reference/nullishCoalescingOperator_esnext.js

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,24 @@ const aa5 = a5 ?? 'whatever'
1818
const aa6 = a6 ?? 'whatever'
1919
const aa7 = a7 ?? 'whatever'
2020
const aa8 = a8 ?? 'whatever'
21-
const aa9 = a9 ?? 'whatever'
21+
const aa9 = a9 ?? 'whatever'
22+
23+
24+
declare let a: any, b: any, c: any;
25+
26+
let x1 = (a ?? b as any) || c;
27+
let x2 = c || (a ?? b as any);
28+
let x3 = ((a ?? b) as any) || c;
29+
let x4 = c || ((a ?? b) as any);
30+
let x5 = (a ?? b) as any || c;
31+
let x6 = c || (a ?? b) as any;
32+
33+
let y1 = (a ?? b as any) && c;
34+
let y2 = c && (a ?? b as any);
35+
let y3 = ((a ?? b) as any) && c;
36+
let y4 = c && ((a ?? b) as any);
37+
let y5 = (a ?? b) as any && c;
38+
let y6 = c && (a ?? b) as any;
2239

2340
//// [nullishCoalescingOperator_esnext.js]
2441
"use strict";
@@ -31,3 +48,15 @@ const aa6 = a6 ?? 'whatever';
3148
const aa7 = a7 ?? 'whatever';
3249
const aa8 = a8 ?? 'whatever';
3350
const aa9 = a9 ?? 'whatever';
51+
let x1 = (a ?? b) || c;
52+
let x2 = c || (a ?? b);
53+
let x3 = (a ?? b) || c;
54+
let x4 = c || (a ?? b);
55+
let x5 = (a ?? b) || c;
56+
let x6 = c || (a ?? b);
57+
let y1 = (a ?? b) && c;
58+
let y2 = c && (a ?? b);
59+
let y3 = (a ?? b) && c;
60+
let y4 = c && (a ?? b);
61+
let y5 = (a ?? b) && c;
62+
let y6 = c && (a ?? b);

tests/baselines/reference/nullishCoalescingOperator_esnext.symbols

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,81 @@ const aa9 = a9 ?? 'whatever'
6363
>aa9 : Symbol(aa9, Decl(nullishCoalescingOperator_esnext.ts, 19, 5))
6464
>a9 : Symbol(a9, Decl(nullishCoalescingOperator_esnext.ts, 8, 13))
6565

66+
67+
declare let a: any, b: any, c: any;
68+
>a : Symbol(a, Decl(nullishCoalescingOperator_esnext.ts, 22, 11))
69+
>b : Symbol(b, Decl(nullishCoalescingOperator_esnext.ts, 22, 19))
70+
>c : Symbol(c, Decl(nullishCoalescingOperator_esnext.ts, 22, 27))
71+
72+
let x1 = (a ?? b as any) || c;
73+
>x1 : Symbol(x1, Decl(nullishCoalescingOperator_esnext.ts, 24, 3))
74+
>a : Symbol(a, Decl(nullishCoalescingOperator_esnext.ts, 22, 11))
75+
>b : Symbol(b, Decl(nullishCoalescingOperator_esnext.ts, 22, 19))
76+
>c : Symbol(c, Decl(nullishCoalescingOperator_esnext.ts, 22, 27))
77+
78+
let x2 = c || (a ?? b as any);
79+
>x2 : Symbol(x2, Decl(nullishCoalescingOperator_esnext.ts, 25, 3))
80+
>c : Symbol(c, Decl(nullishCoalescingOperator_esnext.ts, 22, 27))
81+
>a : Symbol(a, Decl(nullishCoalescingOperator_esnext.ts, 22, 11))
82+
>b : Symbol(b, Decl(nullishCoalescingOperator_esnext.ts, 22, 19))
83+
84+
let x3 = ((a ?? b) as any) || c;
85+
>x3 : Symbol(x3, Decl(nullishCoalescingOperator_esnext.ts, 26, 3))
86+
>a : Symbol(a, Decl(nullishCoalescingOperator_esnext.ts, 22, 11))
87+
>b : Symbol(b, Decl(nullishCoalescingOperator_esnext.ts, 22, 19))
88+
>c : Symbol(c, Decl(nullishCoalescingOperator_esnext.ts, 22, 27))
89+
90+
let x4 = c || ((a ?? b) as any);
91+
>x4 : Symbol(x4, Decl(nullishCoalescingOperator_esnext.ts, 27, 3))
92+
>c : Symbol(c, Decl(nullishCoalescingOperator_esnext.ts, 22, 27))
93+
>a : Symbol(a, Decl(nullishCoalescingOperator_esnext.ts, 22, 11))
94+
>b : Symbol(b, Decl(nullishCoalescingOperator_esnext.ts, 22, 19))
95+
96+
let x5 = (a ?? b) as any || c;
97+
>x5 : Symbol(x5, Decl(nullishCoalescingOperator_esnext.ts, 28, 3))
98+
>a : Symbol(a, Decl(nullishCoalescingOperator_esnext.ts, 22, 11))
99+
>b : Symbol(b, Decl(nullishCoalescingOperator_esnext.ts, 22, 19))
100+
>c : Symbol(c, Decl(nullishCoalescingOperator_esnext.ts, 22, 27))
101+
102+
let x6 = c || (a ?? b) as any;
103+
>x6 : Symbol(x6, Decl(nullishCoalescingOperator_esnext.ts, 29, 3))
104+
>c : Symbol(c, Decl(nullishCoalescingOperator_esnext.ts, 22, 27))
105+
>a : Symbol(a, Decl(nullishCoalescingOperator_esnext.ts, 22, 11))
106+
>b : Symbol(b, Decl(nullishCoalescingOperator_esnext.ts, 22, 19))
107+
108+
let y1 = (a ?? b as any) && c;
109+
>y1 : Symbol(y1, Decl(nullishCoalescingOperator_esnext.ts, 31, 3))
110+
>a : Symbol(a, Decl(nullishCoalescingOperator_esnext.ts, 22, 11))
111+
>b : Symbol(b, Decl(nullishCoalescingOperator_esnext.ts, 22, 19))
112+
>c : Symbol(c, Decl(nullishCoalescingOperator_esnext.ts, 22, 27))
113+
114+
let y2 = c && (a ?? b as any);
115+
>y2 : Symbol(y2, Decl(nullishCoalescingOperator_esnext.ts, 32, 3))
116+
>c : Symbol(c, Decl(nullishCoalescingOperator_esnext.ts, 22, 27))
117+
>a : Symbol(a, Decl(nullishCoalescingOperator_esnext.ts, 22, 11))
118+
>b : Symbol(b, Decl(nullishCoalescingOperator_esnext.ts, 22, 19))
119+
120+
let y3 = ((a ?? b) as any) && c;
121+
>y3 : Symbol(y3, Decl(nullishCoalescingOperator_esnext.ts, 33, 3))
122+
>a : Symbol(a, Decl(nullishCoalescingOperator_esnext.ts, 22, 11))
123+
>b : Symbol(b, Decl(nullishCoalescingOperator_esnext.ts, 22, 19))
124+
>c : Symbol(c, Decl(nullishCoalescingOperator_esnext.ts, 22, 27))
125+
126+
let y4 = c && ((a ?? b) as any);
127+
>y4 : Symbol(y4, Decl(nullishCoalescingOperator_esnext.ts, 34, 3))
128+
>c : Symbol(c, Decl(nullishCoalescingOperator_esnext.ts, 22, 27))
129+
>a : Symbol(a, Decl(nullishCoalescingOperator_esnext.ts, 22, 11))
130+
>b : Symbol(b, Decl(nullishCoalescingOperator_esnext.ts, 22, 19))
131+
132+
let y5 = (a ?? b) as any && c;
133+
>y5 : Symbol(y5, Decl(nullishCoalescingOperator_esnext.ts, 35, 3))
134+
>a : Symbol(a, Decl(nullishCoalescingOperator_esnext.ts, 22, 11))
135+
>b : Symbol(b, Decl(nullishCoalescingOperator_esnext.ts, 22, 19))
136+
>c : Symbol(c, Decl(nullishCoalescingOperator_esnext.ts, 22, 27))
137+
138+
let y6 = c && (a ?? b) as any;
139+
>y6 : Symbol(y6, Decl(nullishCoalescingOperator_esnext.ts, 36, 3))
140+
>c : Symbol(c, Decl(nullishCoalescingOperator_esnext.ts, 22, 27))
141+
>a : Symbol(a, Decl(nullishCoalescingOperator_esnext.ts, 22, 11))
142+
>b : Symbol(b, Decl(nullishCoalescingOperator_esnext.ts, 22, 19))
143+

tests/baselines/reference/nullishCoalescingOperator_esnext.types

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,133 @@ const aa9 = a9 ?? 'whatever'
9292
>a9 : any
9393
>'whatever' : "whatever"
9494

95+
96+
declare let a: any, b: any, c: any;
97+
>a : any
98+
>b : any
99+
>c : any
100+
101+
let x1 = (a ?? b as any) || c;
102+
>x1 : any
103+
>(a ?? b as any) || c : any
104+
>(a ?? b as any) : any
105+
>a ?? b as any : any
106+
>a : any
107+
>b as any : any
108+
>b : any
109+
>c : any
110+
111+
let x2 = c || (a ?? b as any);
112+
>x2 : any
113+
>c || (a ?? b as any) : any
114+
>c : any
115+
>(a ?? b as any) : any
116+
>a ?? b as any : any
117+
>a : any
118+
>b as any : any
119+
>b : any
120+
121+
let x3 = ((a ?? b) as any) || c;
122+
>x3 : any
123+
>((a ?? b) as any) || c : any
124+
>((a ?? b) as any) : any
125+
>(a ?? b) as any : any
126+
>(a ?? b) : any
127+
>a ?? b : any
128+
>a : any
129+
>b : any
130+
>c : any
131+
132+
let x4 = c || ((a ?? b) as any);
133+
>x4 : any
134+
>c || ((a ?? b) as any) : any
135+
>c : any
136+
>((a ?? b) as any) : any
137+
>(a ?? b) as any : any
138+
>(a ?? b) : any
139+
>a ?? b : any
140+
>a : any
141+
>b : any
142+
143+
let x5 = (a ?? b) as any || c;
144+
>x5 : any
145+
>(a ?? b) as any || c : any
146+
>(a ?? b) as any : any
147+
>(a ?? b) : any
148+
>a ?? b : any
149+
>a : any
150+
>b : any
151+
>c : any
152+
153+
let x6 = c || (a ?? b) as any;
154+
>x6 : any
155+
>c || (a ?? b) as any : any
156+
>c : any
157+
>(a ?? b) as any : any
158+
>(a ?? b) : any
159+
>a ?? b : any
160+
>a : any
161+
>b : any
162+
163+
let y1 = (a ?? b as any) && c;
164+
>y1 : any
165+
>(a ?? b as any) && c : any
166+
>(a ?? b as any) : any
167+
>a ?? b as any : any
168+
>a : any
169+
>b as any : any
170+
>b : any
171+
>c : any
172+
173+
let y2 = c && (a ?? b as any);
174+
>y2 : any
175+
>c && (a ?? b as any) : any
176+
>c : any
177+
>(a ?? b as any) : any
178+
>a ?? b as any : any
179+
>a : any
180+
>b as any : any
181+
>b : any
182+
183+
let y3 = ((a ?? b) as any) && c;
184+
>y3 : any
185+
>((a ?? b) as any) && c : any
186+
>((a ?? b) as any) : any
187+
>(a ?? b) as any : any
188+
>(a ?? b) : any
189+
>a ?? b : any
190+
>a : any
191+
>b : any
192+
>c : any
193+
194+
let y4 = c && ((a ?? b) as any);
195+
>y4 : any
196+
>c && ((a ?? b) as any) : any
197+
>c : any
198+
>((a ?? b) as any) : any
199+
>(a ?? b) as any : any
200+
>(a ?? b) : any
201+
>a ?? b : any
202+
>a : any
203+
>b : any
204+
205+
let y5 = (a ?? b) as any && c;
206+
>y5 : any
207+
>(a ?? b) as any && c : any
208+
>(a ?? b) as any : any
209+
>(a ?? b) : any
210+
>a ?? b : any
211+
>a : any
212+
>b : any
213+
>c : any
214+
215+
let y6 = c && (a ?? b) as any;
216+
>y6 : any
217+
>c && (a ?? b) as any : any
218+
>c : any
219+
>(a ?? b) as any : any
220+
>(a ?? b) : any
221+
>a ?? b : any
222+
>a : any
223+
>b : any
224+

0 commit comments

Comments
 (0)