Skip to content

Commit ef49982

Browse files
Update async await transpilation to avoid captures of super when using ES2015 output.
MS Edge 17 does not properly capture references to `super` in an arrow function. Closes #3101
1 parent 826b0fc commit ef49982

File tree

2 files changed

+93
-2
lines changed

2 files changed

+93
-2
lines changed

src/com/google/javascript/jscomp/RewriteAsyncFunctions.java

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,10 +243,33 @@ private void convertAsyncFunction(NodeTraversal t, LexicalContext functionContex
243243
newBody.addChildToBack(IR.constNode(IR.name(ASYNC_ARGUMENTS), IR.name("arguments")));
244244
NodeUtil.addFeatureToScript(t.getCurrentFile(), Feature.CONST_DECLARATIONS);
245245
}
246+
boolean needsSuperTranspilation = compiler.getOptions().needsTranspilationFrom(FeatureSet.ES6);
246247
for (String replacedMethodName : functionContext.replacedSuperProperties) {
248+
// MS Edge 17 cannot properly capture references to "super" in an arrow function.
249+
// If we are not transpiling classes, switch to using Object.getPrototypeOf(this.constructor)
250+
// as a replacement for super.
251+
// If we are transpiling classes, the super reference will be handled elsewhere.
252+
Node superReference;
253+
if (needsSuperTranspilation) {
254+
superReference = IR.superNode();
255+
} else {
256+
// instance super: Object.getPrototypeOf(this.constructor).prototype
257+
// static super: Object.getPrototypeOf(this.constructor)
258+
superReference =
259+
IR.call(
260+
IR.getprop(IR.name("Object"), IR.string("getPrototypeOf")),
261+
IR.getprop(IR.thisNode(), IR.string("constructor")));
262+
if (!originalFunction.getParent().isStaticMember()) {
263+
superReference = IR.getprop(superReference, IR.string("prototype"));
264+
}
265+
}
266+
247267
// const super$get$x = () => super.x;
248-
Node arrowFunction = IR.arrowFunction(
249-
IR.name(""), IR.paramList(), IR.getprop(IR.superNode(), IR.string(replacedMethodName)));
268+
Node arrowFunction =
269+
IR.arrowFunction(
270+
IR.name(""),
271+
IR.paramList(),
272+
IR.getprop(superReference, IR.string(replacedMethodName)));
250273
compiler.reportChangeToChangeScope(arrowFunction);
251274
NodeUtil.addFeatureToScript(t.getCurrentFile(), Feature.ARROW_FUNCTIONS);
252275

test/com/google/javascript/jscomp/RewriteAsyncFunctionsTest.java

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,74 @@ public void testInnerSuperReference() {
142142
"}"));
143143
}
144144

145+
@Test
146+
public void testInnerSuperCallEs2015Out() {
147+
setLanguageOut(LanguageMode.ECMASCRIPT_2015);
148+
test(
149+
lines(
150+
"class A {",
151+
" m() {",
152+
" return this;",
153+
" }",
154+
"}",
155+
"class X extends A {",
156+
" async m() {",
157+
" return super.m();",
158+
" }",
159+
"}"),
160+
lines(
161+
"class A {",
162+
" m() {",
163+
" return this;",
164+
" }",
165+
"}",
166+
"class X extends A {",
167+
" m() {",
168+
" const $jscomp$async$this = this;",
169+
" const $jscomp$async$super$get$m =",
170+
" () => Object.getPrototypeOf(this.constructor).prototype.m;",
171+
" return $jscomp.asyncExecutePromiseGeneratorFunction(",
172+
" function* () {",
173+
" return $jscomp$async$super$get$m().call($jscomp$async$this);",
174+
" });",
175+
" }",
176+
"}"));
177+
}
178+
179+
@Test
180+
public void testInnerSuperCallStaticEs2015Out() {
181+
setLanguageOut(LanguageMode.ECMASCRIPT_2015);
182+
test(
183+
lines(
184+
"class A {",
185+
" static m() {",
186+
" return this;",
187+
" }",
188+
"}",
189+
"class X extends A {",
190+
" static async m() {",
191+
" return super.m();",
192+
" }",
193+
"}"),
194+
lines(
195+
"class A {",
196+
" static m() {",
197+
" return this;",
198+
" }",
199+
"}",
200+
"class X extends A {",
201+
" static m() {",
202+
" const $jscomp$async$this = this;",
203+
" const $jscomp$async$super$get$m =",
204+
" () => Object.getPrototypeOf(this.constructor).m;",
205+
" return $jscomp.asyncExecutePromiseGeneratorFunction(",
206+
" function* () {",
207+
" return $jscomp$async$super$get$m().call($jscomp$async$this);",
208+
" });",
209+
" }",
210+
"}"));
211+
}
212+
145213
@Test
146214
public void testNestedArrowFunctionUsingThis() {
147215
test(

0 commit comments

Comments
 (0)