Fix super calls to suspend functions in abstract classes

This commit is contained in:
Denis Zharkov
2017-05-26 17:34:58 +03:00
parent 26ef954507
commit 2c98bd053a
8 changed files with 69 additions and 6 deletions
@@ -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;
@@ -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)
@@ -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"
}
@@ -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");
@@ -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");
@@ -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");