Skip to content

Commit 299ea40

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 google#3101
1 parent 826b0fc commit 299ea40

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

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

+15-1
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ void recordAsyncArgumentsReplacementWasDone() {
124124
private final AbstractCompiler compiler;
125125
private static final FeatureSet transpiledFeatures =
126126
FeatureSet.BARE_MINIMUM.with(Feature.ASYNC_FUNCTIONS);
127+
private boolean needsSuperTranspilation = false;
127128

128129
public RewriteAsyncFunctions(AbstractCompiler compiler) {
129130
checkNotNull(compiler);
@@ -134,6 +135,7 @@ public RewriteAsyncFunctions(AbstractCompiler compiler) {
134135

135136
@Override
136137
public void process(Node externs, Node root) {
138+
needsSuperTranspilation = compiler.getOptions().needsTranspilationFrom(FeatureSet.ES6);
137139
TranspilationPasses.processTranspile(compiler, externs, transpiledFeatures, this);
138140
TranspilationPasses.processTranspile(compiler, root, transpiledFeatures, this);
139141
TranspilationPasses.maybeMarkFeaturesAsTranspiledAway(compiler, transpiledFeatures);
@@ -244,9 +246,21 @@ private void convertAsyncFunction(NodeTraversal t, LexicalContext functionContex
244246
NodeUtil.addFeatureToScript(t.getCurrentFile(), Feature.CONST_DECLARATIONS);
245247
}
246248
for (String replacedMethodName : functionContext.replacedSuperProperties) {
249+
// MS Edge 17 cannot properly capture references to "super" in an arrow function.
250+
// If we are not transpiling classes, switch to using Object.getPrototypeOf(this)
251+
// as a replacement for super.
252+
// If we are transpiling classes, the super reference will be handled elsewhere.
253+
Node superReference;
254+
if (needsSuperTranspilation) {
255+
superReference = IR.superNode();
256+
} else {
257+
superReference = IR.call(
258+
IR.getprop(IR.name("Object"), IR.string("getPrototypeOf")), IR.thisNode());
259+
}
260+
247261
// const super$get$x = () => super.x;
248262
Node arrowFunction = IR.arrowFunction(
249-
IR.name(""), IR.paramList(), IR.getprop(IR.superNode(), IR.string(replacedMethodName)));
263+
IR.name(""), IR.paramList(), IR.getprop(superReference, IR.string(replacedMethodName)));
250264
compiler.reportChangeToChangeScope(arrowFunction);
251265
NodeUtil.addFeatureToScript(t.getCurrentFile(), Feature.ARROW_FUNCTIONS);
252266

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

+33
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,39 @@ 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 = () => Object.getPrototypeOf(this).m;",
170+
" return $jscomp.asyncExecutePromiseGeneratorFunction(",
171+
" function* () {",
172+
" return $jscomp$async$super$get$m().call($jscomp$async$this);",
173+
" });",
174+
" }",
175+
"}"));
176+
}
177+
145178
@Test
146179
public void testNestedArrowFunctionUsingThis() {
147180
test(

0 commit comments

Comments
 (0)