diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/jsAstUtils.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/jsAstUtils.kt index 7460d8502be..0f30cb1f3bf 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/jsAstUtils.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/jsAstUtils.kt @@ -19,6 +19,7 @@ import org.jetbrains.kotlin.ir.backend.js.utils.* import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol +import org.jetbrains.kotlin.ir.types.isSubtypeOfClass import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid @@ -200,7 +201,7 @@ fun translateCall( Pair(function, superQualifier.owner) } - if (expression.isSyntheticDelegatingReplacement || currentDispatchReceiver.canUseSuperRef(function, context, klass)) { + if (expression.isSyntheticDelegatingReplacement || currentDispatchReceiver.canUseSuperRef(context, klass)) { return JsInvocation(JsNameRef(context.getNameForMemberFunction(target), JsSuperRef()), arguments) } @@ -655,10 +656,10 @@ private val nameMappingOriginAllowList = setOf( JsLoweredDeclarationOrigin.JS_SHADOWED_DEFAULT_PARAMETER, ) -private fun IrClass?.canUseSuperRef(function: IrFunction, context: JsGenerationContext, superClass: IrClass): Boolean { +private fun IrClass?.canUseSuperRef(context: JsGenerationContext, superClass: IrClass): Boolean { + val currentFunction = context.currentFunction ?: return false return this != null && - function.origin != IrDeclarationOrigin.LOWERED_SUSPEND_FUNCTION && context.staticContext.backendContext.es6mode && - !superClass.isInterface && !isInner && !isLocal && - context.currentFunction?.isEs6ConstructorReplacement != true + !superClass.isInterface && + !isInner && !isLocal && !currentFunction.isEs6ConstructorReplacement && currentFunction.parentClassOrNull?.superClass?.symbol != context.staticContext.backendContext.coroutineSymbols.coroutineImpl } diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/BoxJsTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/BoxJsTestGenerated.java index d9afd7a1c6a..aa5965d6189 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/BoxJsTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/BoxJsTestGenerated.java @@ -620,6 +620,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { runTest("js/js.translator/testData/box/closure/recursiveFunctionWithSameNameDeclaration.kt"); } + @Test + @TestMetadata("superCallInsideLambda.kt") + public void testSuperCallInsideLambda() throws Exception { + runTest("js/js.translator/testData/box/closure/superCallInsideLambda.kt"); + } + @Test @TestMetadata("withManyClosuresInNestedFunctionsAndObjects.kt") public void testWithManyClosuresInNestedFunctionsAndObjects() throws Exception { @@ -867,6 +873,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { public void testSuspendFunctionalInterface() throws Exception { runTest("js/js.translator/testData/box/coroutines/suspendFunctionalInterface.kt"); } + + @Test + @TestMetadata("suspendMethodWithSuperCall.kt") + public void testSuspendMethodWithSuperCall() throws Exception { + runTest("js/js.translator/testData/box/coroutines/suspendMethodWithSuperCall.kt"); + } } @Nested @@ -9816,6 +9828,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { runTest("js/js.translator/testData/box/superCall/propertySuperAccess.kt"); } + @Test + @TestMetadata("superCallInPrivateMethod.kt") + public void testSuperCallInPrivateMethod() throws Exception { + runTest("js/js.translator/testData/box/superCall/superCallInPrivateMethod.kt"); + } + @Test @TestMetadata("traitSuperCall.kt") public void testTraitSuperCall() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsBoxTestGenerated.java index a61953489a2..22b8a00f64e 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsBoxTestGenerated.java @@ -620,6 +620,12 @@ public class FirJsBoxTestGenerated extends AbstractFirJsBoxTest { runTest("js/js.translator/testData/box/closure/recursiveFunctionWithSameNameDeclaration.kt"); } + @Test + @TestMetadata("superCallInsideLambda.kt") + public void testSuperCallInsideLambda() throws Exception { + runTest("js/js.translator/testData/box/closure/superCallInsideLambda.kt"); + } + @Test @TestMetadata("withManyClosuresInNestedFunctionsAndObjects.kt") public void testWithManyClosuresInNestedFunctionsAndObjects() throws Exception { @@ -931,6 +937,12 @@ public class FirJsBoxTestGenerated extends AbstractFirJsBoxTest { public void testSuspendFunctionalInterface() throws Exception { runTest("js/js.translator/testData/box/coroutines/suspendFunctionalInterface.kt"); } + + @Test + @TestMetadata("suspendMethodWithSuperCall.kt") + public void testSuspendMethodWithSuperCall() throws Exception { + runTest("js/js.translator/testData/box/coroutines/suspendMethodWithSuperCall.kt"); + } } @Nested @@ -10726,6 +10738,12 @@ public class FirJsBoxTestGenerated extends AbstractFirJsBoxTest { runTest("js/js.translator/testData/box/superCall/propertySuperAccess.kt"); } + @Test + @TestMetadata("superCallInPrivateMethod.kt") + public void testSuperCallInPrivateMethod() throws Exception { + runTest("js/js.translator/testData/box/superCall/superCallInPrivateMethod.kt"); + } + @Test @TestMetadata("traitSuperCall.kt") public void testTraitSuperCall() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsES6TestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsES6TestGenerated.java index ab69e93c6c0..1c8e25e6ae3 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsES6TestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsES6TestGenerated.java @@ -620,6 +620,12 @@ public class IrBoxJsES6TestGenerated extends AbstractIrBoxJsES6Test { runTest("js/js.translator/testData/box/closure/recursiveFunctionWithSameNameDeclaration.kt"); } + @Test + @TestMetadata("superCallInsideLambda.kt") + public void testSuperCallInsideLambda() throws Exception { + runTest("js/js.translator/testData/box/closure/superCallInsideLambda.kt"); + } + @Test @TestMetadata("withManyClosuresInNestedFunctionsAndObjects.kt") public void testWithManyClosuresInNestedFunctionsAndObjects() throws Exception { @@ -931,6 +937,12 @@ public class IrBoxJsES6TestGenerated extends AbstractIrBoxJsES6Test { public void testSuspendFunctionalInterface() throws Exception { runTest("js/js.translator/testData/box/coroutines/suspendFunctionalInterface.kt"); } + + @Test + @TestMetadata("suspendMethodWithSuperCall.kt") + public void testSuspendMethodWithSuperCall() throws Exception { + runTest("js/js.translator/testData/box/coroutines/suspendMethodWithSuperCall.kt"); + } } @Nested @@ -10832,6 +10844,12 @@ public class IrBoxJsES6TestGenerated extends AbstractIrBoxJsES6Test { runTest("js/js.translator/testData/box/superCall/propertySuperAccess.kt"); } + @Test + @TestMetadata("superCallInPrivateMethod.kt") + public void testSuperCallInPrivateMethod() throws Exception { + runTest("js/js.translator/testData/box/superCall/superCallInPrivateMethod.kt"); + } + @Test @TestMetadata("traitSuperCall.kt") public void testTraitSuperCall() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsTestGenerated.java index 4754d85ffd4..7a5926e3127 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsTestGenerated.java @@ -620,6 +620,12 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest { runTest("js/js.translator/testData/box/closure/recursiveFunctionWithSameNameDeclaration.kt"); } + @Test + @TestMetadata("superCallInsideLambda.kt") + public void testSuperCallInsideLambda() throws Exception { + runTest("js/js.translator/testData/box/closure/superCallInsideLambda.kt"); + } + @Test @TestMetadata("withManyClosuresInNestedFunctionsAndObjects.kt") public void testWithManyClosuresInNestedFunctionsAndObjects() throws Exception { @@ -931,6 +937,12 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest { public void testSuspendFunctionalInterface() throws Exception { runTest("js/js.translator/testData/box/coroutines/suspendFunctionalInterface.kt"); } + + @Test + @TestMetadata("suspendMethodWithSuperCall.kt") + public void testSuspendMethodWithSuperCall() throws Exception { + runTest("js/js.translator/testData/box/coroutines/suspendMethodWithSuperCall.kt"); + } } @Nested @@ -10726,6 +10738,12 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest { runTest("js/js.translator/testData/box/superCall/propertySuperAccess.kt"); } + @Test + @TestMetadata("superCallInPrivateMethod.kt") + public void testSuperCallInPrivateMethod() throws Exception { + runTest("js/js.translator/testData/box/superCall/superCallInPrivateMethod.kt"); + } + @Test @TestMetadata("traitSuperCall.kt") public void testTraitSuperCall() throws Exception { diff --git a/js/js.translator/testData/box/closure/superCallInsideLambda.kt b/js/js.translator/testData/box/closure/superCallInsideLambda.kt new file mode 100644 index 00000000000..6f5c3847ae2 --- /dev/null +++ b/js/js.translator/testData/box/closure/superCallInsideLambda.kt @@ -0,0 +1,25 @@ +// EXPECTED_REACHABLE_NODES: 1292 + +var result = "" + +fun call(lambda: () -> T): T { + return lambda() +} + +abstract class Parent { + val o = "O" + val k = "K" + protected fun getO() = o + protected fun getK() = k +} + +class Child : Parent() { + fun runTest() { + result += call { super.getO() + super.getK() } + } +} + +fun box(): String { + Child().runTest() + return result +} diff --git a/js/js.translator/testData/box/coroutines/suspendMethodWithSuperCall.kt b/js/js.translator/testData/box/coroutines/suspendMethodWithSuperCall.kt new file mode 100644 index 00000000000..8e6b5c26e73 --- /dev/null +++ b/js/js.translator/testData/box/coroutines/suspendMethodWithSuperCall.kt @@ -0,0 +1,40 @@ +// WITH_STDLIB +// EXPECTED_REACHABLE_NODES: 1292 + +import kotlin.coroutines.* +import kotlin.coroutines.intrinsics.* + +var result = "" + +fun builder(c: suspend () -> Unit) { + c.startCoroutine(object : Continuation { + override val context = EmptyCoroutineContext + override fun resumeWith(result: Result) {} + }) +} + +abstract class Parent { + val o = "O" + val k = "K" + protected fun getO() = o + protected fun getK() = k +} + + +class Child : Parent() { + suspend fun justSomeSuspendFunction() { + Unit + } + + suspend fun runTest() { + justSomeSuspendFunction() + result += super.getO() + super.getK() + } +} + +fun box(): String { + builder { + Child().runTest() + } + return result +} diff --git a/js/js.translator/testData/box/superCall/superCallInPrivateMethod.kt b/js/js.translator/testData/box/superCall/superCallInPrivateMethod.kt new file mode 100644 index 00000000000..f2d9e144a1f --- /dev/null +++ b/js/js.translator/testData/box/superCall/superCallInPrivateMethod.kt @@ -0,0 +1,23 @@ +// EXPECTED_REACHABLE_NODES: 1292 + +var result = "" +abstract class Parent { + val o = "O" + val k = "K" + protected fun getO() = o + protected fun getK() = k +} + +class Child : Parent() { + private fun calculateResult(): String { + return super.getO() + super.getK() + } + fun runTest() { + result += this.calculateResult() + } +} + +fun box(): String { + Child().runTest() + return result +}