diff --git a/src/com/google/javascript/jscomp/RewriteAsyncFunctions.java b/src/com/google/javascript/jscomp/RewriteAsyncFunctions.java index 55980d38851..5ad0759acd7 100644 --- a/src/com/google/javascript/jscomp/RewriteAsyncFunctions.java +++ b/src/com/google/javascript/jscomp/RewriteAsyncFunctions.java @@ -243,10 +243,33 @@ private void convertAsyncFunction(NodeTraversal t, LexicalContext functionContex newBody.addChildToBack(IR.constNode(IR.name(ASYNC_ARGUMENTS), IR.name("arguments"))); NodeUtil.addFeatureToScript(t.getCurrentFile(), Feature.CONST_DECLARATIONS); } + boolean needsSuperTranspilation = compiler.getOptions().needsTranspilationFrom(FeatureSet.ES6); for (String replacedMethodName : functionContext.replacedSuperProperties) { + // MS Edge 17 cannot properly capture references to "super" in an arrow function. + // If we are not transpiling classes, switch to using Object.getPrototypeOf(this.constructor) + // as a replacement for super. + // If we are transpiling classes, the super reference will be handled elsewhere. + Node superReference; + if (needsSuperTranspilation) { + superReference = IR.superNode(); + } else { + // instance super: Object.getPrototypeOf(this.constructor).prototype + // static super: Object.getPrototypeOf(this.constructor) + superReference = + IR.call( + IR.getprop(IR.name("Object"), IR.string("getPrototypeOf")), + IR.getprop(IR.thisNode(), IR.string("constructor"))); + if (!originalFunction.getParent().isStaticMember()) { + superReference = IR.getprop(superReference, IR.string("prototype")); + } + } + // const super$get$x = () => super.x; - Node arrowFunction = IR.arrowFunction( - IR.name(""), IR.paramList(), IR.getprop(IR.superNode(), IR.string(replacedMethodName))); + Node arrowFunction = + IR.arrowFunction( + IR.name(""), + IR.paramList(), + IR.getprop(superReference, IR.string(replacedMethodName))); compiler.reportChangeToChangeScope(arrowFunction); NodeUtil.addFeatureToScript(t.getCurrentFile(), Feature.ARROW_FUNCTIONS); diff --git a/test/com/google/javascript/jscomp/RewriteAsyncFunctionsTest.java b/test/com/google/javascript/jscomp/RewriteAsyncFunctionsTest.java index 5394c8d5232..437874f9899 100644 --- a/test/com/google/javascript/jscomp/RewriteAsyncFunctionsTest.java +++ b/test/com/google/javascript/jscomp/RewriteAsyncFunctionsTest.java @@ -142,6 +142,74 @@ public void testInnerSuperReference() { "}")); } + @Test + public void testInnerSuperCallEs2015Out() { + setLanguageOut(LanguageMode.ECMASCRIPT_2015); + test( + lines( + "class A {", + " m() {", + " return this;", + " }", + "}", + "class X extends A {", + " async m() {", + " return super.m();", + " }", + "}"), + lines( + "class A {", + " m() {", + " return this;", + " }", + "}", + "class X extends A {", + " m() {", + " const $jscomp$async$this = this;", + " const $jscomp$async$super$get$m =", + " () => Object.getPrototypeOf(this.constructor).prototype.m;", + " return $jscomp.asyncExecutePromiseGeneratorFunction(", + " function* () {", + " return $jscomp$async$super$get$m().call($jscomp$async$this);", + " });", + " }", + "}")); + } + + @Test + public void testInnerSuperCallStaticEs2015Out() { + setLanguageOut(LanguageMode.ECMASCRIPT_2015); + test( + lines( + "class A {", + " static m() {", + " return this;", + " }", + "}", + "class X extends A {", + " static async m() {", + " return super.m();", + " }", + "}"), + lines( + "class A {", + " static m() {", + " return this;", + " }", + "}", + "class X extends A {", + " static m() {", + " const $jscomp$async$this = this;", + " const $jscomp$async$super$get$m =", + " () => Object.getPrototypeOf(this.constructor).m;", + " return $jscomp.asyncExecutePromiseGeneratorFunction(", + " function* () {", + " return $jscomp$async$super$get$m().call($jscomp$async$this);", + " });", + " }", + "}")); + } + @Test public void testNestedArrowFunctionUsingThis() { test(