diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java index 528f5ee42d6..019504e4354 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java @@ -81,6 +81,7 @@ import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isAnnotationOrJvmInter import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvm8InterfaceWithDefaultsMember; import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.METHOD_FOR_FUNCTION; import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION; +import static org.jetbrains.kotlin.descriptors.ModalityKt.isOverridable; import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.*; import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUtilKt.isEffectivelyInlineOnly; import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.getSourceFromDescriptor; @@ -203,7 +204,8 @@ public class FunctionCodegen { } boolean isOpenSuspendInClass = - functionDescriptor.isSuspend() && DescriptorUtilKt.isEffectivelyOpen(functionDescriptor) && + functionDescriptor.isSuspend() && + functionDescriptor.getModality() != Modality.ABSTRACT && isOverridable(functionDescriptor) && !isInterface(functionDescriptor.getContainingDeclaration()) && origin.getOriginKind() != JvmDeclarationOriginKind.CLASS_MEMBER_DELEGATION_TO_DEFAULT_IMPL; diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineCodegen.kt index 491714e4542..25043ec231e 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineCodegen.kt @@ -426,7 +426,7 @@ class CoroutineCodegenForNamedFunction private constructor( codegen.v.load(0, AsmTypes.OBJECT_TYPE) - if (suspendFunctionJvmView.isEffectivelyOpen() && !isInterfaceMethod && captureThisType != null) { + if (suspendFunctionJvmView.isOverridable && !isInterfaceMethod && captureThisType != null) { val owner = captureThisType.internalName val impl = callableMethod.getAsmMethod().getImplForOpenMethod(owner) codegen.v.invokestatic(owner, impl.name, impl.descriptor, false) diff --git a/compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/superCallAbstractClass.kt b/compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/superCallAbstractClass.kt new file mode 100644 index 00000000000..6763e99ab1f --- /dev/null +++ b/compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/superCallAbstractClass.kt @@ -0,0 +1,41 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import helpers.* +import kotlin.coroutines.experimental.* +import kotlin.coroutines.experimental.intrinsics.* + +abstract class A(val v: String) { + suspend abstract fun foo(v: String): String + + suspend fun suspendThere(v: String): String = suspendCoroutineOrReturn { x -> + x.resume(v) + COROUTINE_SUSPENDED + } + + open suspend fun suspendHere(): String = foo("O") + suspendThere(v) +} + +class B(v: String) : A(v) { + override suspend fun foo(v: String): String = suspendCoroutineOrReturn { x -> + x.resume(v) + COROUTINE_SUSPENDED + } + + override suspend fun suspendHere(): String = super.suspendHere() + suspendThere("56") +} + +fun builder(c: suspend A.() -> Unit) { + c.startCoroutine(B("K"), EmptyContinuation) +} + +fun box(): String { + var result = "" + + builder { + result = suspendHere() + } + + if (result != "OK56") return "fail 1: $result" + + return "OK" +} diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 26a0c6896ed..4a531d27771 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -5734,6 +5734,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("superCallAbstractClass.kt") + public void testSuperCallAbstractClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/superCallAbstractClass.kt"); + doTest(fileName); + } + @TestMetadata("superCallInterface.kt") public void testSuperCallInterface() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/superCallInterface.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 705f8d251e6..8026c64aeae 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -5734,6 +5734,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("superCallAbstractClass.kt") + public void testSuperCallAbstractClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/superCallAbstractClass.kt"); + doTest(fileName); + } + @TestMetadata("superCallInterface.kt") public void testSuperCallInterface() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/superCallInterface.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 90b9c45f846..25284e116f2 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -5734,6 +5734,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes doTest(fileName); } + @TestMetadata("superCallAbstractClass.kt") + public void testSuperCallAbstractClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/superCallAbstractClass.kt"); + doTest(fileName); + } + @TestMetadata("superCallInterface.kt") public void testSuperCallInterface() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/superCallInterface.kt"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/descriptorUtil.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/descriptorUtil.kt index 90e93804e5d..50f17d019c3 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/descriptorUtil.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/descriptorUtil.kt @@ -19,7 +19,6 @@ package org.jetbrains.kotlin.descriptors import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.DescriptorUtils -import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.sure fun ModuleDescriptor.resolveClassByFqName(fqName: FqName, lookupLocation: LookupLocation): ClassDescriptor? { @@ -38,6 +37,3 @@ fun ModuleDescriptor.findContinuationClassDescriptorOrNull(lookupLocation: Looku fun ModuleDescriptor.findContinuationClassDescriptor(lookupLocation: LookupLocation) = findContinuationClassDescriptorOrNull(lookupLocation).sure { "Continuation interface is not found" } - -fun FunctionDescriptor.isEffectivelyOpen() = - modality == Modality.OPEN && containingDeclaration.safeAs()?.modality == Modality.OPEN diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index e82e35ffacc..3cd906b0491 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -6424,6 +6424,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { doTest(fileName); } + @TestMetadata("superCallAbstractClass.kt") + public void testSuperCallAbstractClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/superCallAbstractClass.kt"); + doTest(fileName); + } + @TestMetadata("superCallInterface.kt") public void testSuperCallInterface() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine/superCallInterface.kt");