Skip to content

Commit 972eaf6

Browse files
authored
Merge pull request #30479 from Microsoft/fix30066
Fix _superIndex emit when super access captured in async arrow
2 parents 105acf7 + 4fed542 commit 972eaf6

File tree

5 files changed

+574
-7
lines changed

5 files changed

+574
-7
lines changed

src/compiler/transformers/es2017.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -420,8 +420,10 @@ namespace ts {
420420

421421
const savedCapturedSuperProperties = capturedSuperProperties;
422422
const savedHasSuperElementAccess = hasSuperElementAccess;
423-
capturedSuperProperties = createUnderscoreEscapedMap<true>();
424-
hasSuperElementAccess = false;
423+
if (!isArrowFunction) {
424+
capturedSuperProperties = createUnderscoreEscapedMap<true>();
425+
hasSuperElementAccess = false;
426+
}
425427

426428
let result: ConciseBody;
427429
if (!isArrowFunction) {
@@ -446,9 +448,11 @@ namespace ts {
446448

447449
if (emitSuperHelpers) {
448450
enableSubstitutionForAsyncMethodsWithSuper();
449-
const variableStatement = createSuperAccessVariableStatement(resolver, node, capturedSuperProperties);
450-
substitutedSuperAccessors[getNodeId(variableStatement)] = true;
451-
insertStatementsAfterStandardPrologue(statements, [variableStatement]);
451+
if (hasEntries(capturedSuperProperties)) {
452+
const variableStatement = createSuperAccessVariableStatement(resolver, node, capturedSuperProperties);
453+
substitutedSuperAccessors[getNodeId(variableStatement)] = true;
454+
insertStatementsAfterStandardPrologue(statements, [variableStatement]);
455+
}
452456
}
453457

454458
const block = createBlock(statements, /*multiLine*/ true);
@@ -485,8 +489,10 @@ namespace ts {
485489
}
486490

487491
enclosingFunctionParameterNames = savedEnclosingFunctionParameterNames;
488-
capturedSuperProperties = savedCapturedSuperProperties;
489-
hasSuperElementAccess = savedHasSuperElementAccess;
492+
if (!isArrowFunction) {
493+
capturedSuperProperties = savedCapturedSuperProperties;
494+
hasSuperElementAccess = savedHasSuperElementAccess;
495+
}
490496
return result;
491497
}
492498

tests/baselines/reference/asyncMethodWithSuper_es6.js

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,78 @@ class B extends A {
5151

5252
// destructuring assign with element access
5353
({ f: super["x"] } = { f });
54+
55+
// property access in arrow
56+
(() => super.x());
57+
58+
// element access in arrow
59+
(() => super["x"]());
60+
61+
// property access in async arrow
62+
(async () => super.x());
63+
64+
// element access in async arrow
65+
(async () => super["x"]());
66+
}
67+
68+
async property_access_only_read_only() {
69+
// call with property access
70+
super.x();
71+
72+
// property access (read)
73+
const a = super.x;
74+
75+
// property access in arrow
76+
(() => super.x());
77+
78+
// property access in async arrow
79+
(async () => super.x());
80+
}
81+
82+
async property_access_only_write_only() {
83+
const f = () => {};
84+
85+
// property access (assign)
86+
super.x = f;
87+
88+
// destructuring assign with property access
89+
({ f: super.x } = { f });
90+
91+
// property access (assign) in arrow
92+
(() => super.x = f);
93+
94+
// property access (assign) in async arrow
95+
(async () => super.x = f);
96+
}
97+
98+
async element_access_only_read_only() {
99+
// call with element access
100+
super["x"]();
101+
102+
// element access (read)
103+
const a = super["x"];
104+
105+
// element access in arrow
106+
(() => super["x"]());
107+
108+
// element access in async arrow
109+
(async () => super["x"]());
110+
}
111+
112+
async element_access_only_write_only() {
113+
const f = () => {};
114+
115+
// element access (assign)
116+
super["x"] = f;
117+
118+
// destructuring assign with element access
119+
({ f: super["x"] } = { f });
120+
121+
// element access (assign) in arrow
122+
(() => super["x"] = f);
123+
124+
// element access (assign) in async arrow
125+
(async () => super["x"] = f);
54126
}
55127
}
56128

@@ -110,6 +182,75 @@ class B extends A {
110182
({ f: _super.x } = { f });
111183
// destructuring assign with element access
112184
({ f: _superIndex("x").value } = { f });
185+
// property access in arrow
186+
(() => _super.x.call(this));
187+
// element access in arrow
188+
(() => _superIndex("x").value.call(this));
189+
// property access in async arrow
190+
(() => __awaiter(this, void 0, void 0, function* () { return _super.x.call(this); }));
191+
// element access in async arrow
192+
(() => __awaiter(this, void 0, void 0, function* () { return _superIndex("x").value.call(this); }));
193+
});
194+
}
195+
property_access_only_read_only() {
196+
const _super = Object.create(null, {
197+
x: { get: () => super.x }
198+
});
199+
return __awaiter(this, void 0, void 0, function* () {
200+
// call with property access
201+
_super.x.call(this);
202+
// property access (read)
203+
const a = _super.x;
204+
// property access in arrow
205+
(() => _super.x.call(this));
206+
// property access in async arrow
207+
(() => __awaiter(this, void 0, void 0, function* () { return _super.x.call(this); }));
208+
});
209+
}
210+
property_access_only_write_only() {
211+
const _super = Object.create(null, {
212+
x: { get: () => super.x, set: v => super.x = v }
213+
});
214+
return __awaiter(this, void 0, void 0, function* () {
215+
const f = () => { };
216+
// property access (assign)
217+
_super.x = f;
218+
// destructuring assign with property access
219+
({ f: _super.x } = { f });
220+
// property access (assign) in arrow
221+
(() => _super.x = f);
222+
// property access (assign) in async arrow
223+
(() => __awaiter(this, void 0, void 0, function* () { return _super.x = f; }));
224+
});
225+
}
226+
element_access_only_read_only() {
227+
const _superIndex = name => super[name];
228+
return __awaiter(this, void 0, void 0, function* () {
229+
// call with element access
230+
_superIndex("x").call(this);
231+
// element access (read)
232+
const a = _superIndex("x");
233+
// element access in arrow
234+
(() => _superIndex("x").call(this));
235+
// element access in async arrow
236+
(() => __awaiter(this, void 0, void 0, function* () { return _superIndex("x").call(this); }));
237+
});
238+
}
239+
element_access_only_write_only() {
240+
const _superIndex = (function (geti, seti) {
241+
const cache = Object.create(null);
242+
return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } });
243+
})(name => super[name], (name, value) => super[name] = value);
244+
return __awaiter(this, void 0, void 0, function* () {
245+
const f = () => { };
246+
// element access (assign)
247+
_superIndex("x").value = f;
248+
// destructuring assign with element access
249+
({ f: _superIndex("x").value } = { f });
250+
// element access (assign) in arrow
251+
(() => _superIndex("x").value = f);
252+
// element access (assign) in async arrow
253+
(() => __awaiter(this, void 0, void 0, function* () { return _superIndex("x").value = f; }));
113254
});
114255
}
115256
}

tests/baselines/reference/asyncMethodWithSuper_es6.symbols

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,150 @@ class B extends A {
107107
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
108108
>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
109109
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 51, 30))
110+
111+
// property access in arrow
112+
(() => super.x());
113+
>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
114+
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
115+
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
116+
117+
// element access in arrow
118+
(() => super["x"]());
119+
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
120+
>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
121+
122+
// property access in async arrow
123+
(async () => super.x());
124+
>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
125+
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
126+
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
127+
128+
// element access in async arrow
129+
(async () => super["x"]());
130+
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
131+
>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
132+
}
133+
134+
async property_access_only_read_only() {
135+
>property_access_only_read_only : Symbol(B.property_access_only_read_only, Decl(asyncMethodWithSuper_es6.ts, 64, 5))
136+
137+
// call with property access
138+
super.x();
139+
>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
140+
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
141+
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
142+
143+
// property access (read)
144+
const a = super.x;
145+
>a : Symbol(a, Decl(asyncMethodWithSuper_es6.ts, 71, 13))
146+
>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
147+
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
148+
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
149+
150+
// property access in arrow
151+
(() => super.x());
152+
>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
153+
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
154+
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
155+
156+
// property access in async arrow
157+
(async () => super.x());
158+
>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
159+
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
160+
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
161+
}
162+
163+
async property_access_only_write_only() {
164+
>property_access_only_write_only : Symbol(B.property_access_only_write_only, Decl(asyncMethodWithSuper_es6.ts, 78, 5))
165+
166+
const f = () => {};
167+
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 81, 13))
168+
169+
// property access (assign)
170+
super.x = f;
171+
>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
172+
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
173+
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
174+
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 81, 13))
175+
176+
// destructuring assign with property access
177+
({ f: super.x } = { f });
178+
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 87, 10))
179+
>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
180+
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
181+
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
182+
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 87, 27))
183+
184+
// property access (assign) in arrow
185+
(() => super.x = f);
186+
>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
187+
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
188+
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
189+
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 81, 13))
190+
191+
// property access (assign) in async arrow
192+
(async () => super.x = f);
193+
>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
194+
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
195+
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
196+
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 81, 13))
197+
}
198+
199+
async element_access_only_read_only() {
200+
>element_access_only_read_only : Symbol(B.element_access_only_read_only, Decl(asyncMethodWithSuper_es6.ts, 94, 5))
201+
202+
// call with element access
203+
super["x"]();
204+
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
205+
>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
206+
207+
// element access (read)
208+
const a = super["x"];
209+
>a : Symbol(a, Decl(asyncMethodWithSuper_es6.ts, 101, 13))
210+
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
211+
>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
212+
213+
// element access in arrow
214+
(() => super["x"]());
215+
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
216+
>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
217+
218+
// element access in async arrow
219+
(async () => super["x"]());
220+
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
221+
>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
222+
}
223+
224+
async element_access_only_write_only() {
225+
>element_access_only_write_only : Symbol(B.element_access_only_write_only, Decl(asyncMethodWithSuper_es6.ts, 108, 5))
226+
227+
const f = () => {};
228+
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 111, 13))
229+
230+
// element access (assign)
231+
super["x"] = f;
232+
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
233+
>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
234+
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 111, 13))
235+
236+
// destructuring assign with element access
237+
({ f: super["x"] } = { f });
238+
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 117, 10))
239+
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
240+
>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
241+
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 117, 30))
242+
243+
// element access (assign) in arrow
244+
(() => super["x"] = f);
245+
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
246+
>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
247+
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 111, 13))
248+
249+
// element access (assign) in async arrow
250+
(async () => super["x"] = f);
251+
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
252+
>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
253+
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 111, 13))
110254
}
111255
}
112256

0 commit comments

Comments
 (0)