FIC: support suspend conversions in jvm codegen
This commit is contained in:
@@ -230,6 +230,8 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
||||
erasedInterfaceFunction.getValueParameters(), erasedInterfaceFunction.getReturnType(),
|
||||
Modality.OPEN, erasedInterfaceFunction.getVisibility());
|
||||
|
||||
descriptorForBridges.setSuspend(descriptor.isSuspend());
|
||||
|
||||
DescriptorUtilsKt.setSingleOverridden(descriptorForBridges, erasedInterfaceFunction);
|
||||
codegen.generateBridges(descriptorForBridges);
|
||||
}
|
||||
|
||||
+2
-1
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.codegen.coroutines
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.backend.common.COROUTINE_SUSPENDED_NAME
|
||||
import org.jetbrains.kotlin.backend.common.isBuiltInSuspendCoroutineUninterceptedOrReturn
|
||||
import org.jetbrains.kotlin.builtins.isBuiltinFunctionalClassDescriptor
|
||||
import org.jetbrains.kotlin.builtins.isBuiltinFunctionalType
|
||||
import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||
@@ -263,7 +264,7 @@ fun <D : FunctionDescriptor> getOrCreateJvmSuspendFunctionView(
|
||||
annotations = Annotations.EMPTY,
|
||||
name = CONTINUATION_PARAMETER_NAME,
|
||||
// Add j.l.Object to invoke(), because that is the type of parameters we have in FunctionN+1
|
||||
outType = if (function.containingDeclaration.safeAs<ClassDescriptor>()?.defaultType?.isBuiltinFunctionalType == true)
|
||||
outType = if (function.containingDeclaration.safeAs<ClassDescriptor>()?.isBuiltinFunctionalClassDescriptor == true)
|
||||
function.builtIns.nullableAnyType
|
||||
else
|
||||
function.getContinuationParameterTypeOfSuspendFunction(isReleaseCoroutines),
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
// !LANGUAGE: +NewInference +FunctionInterfaceConversion +SamConversionPerArgument +SamConversionForKotlinFunctions
|
||||
// WITH_COROUTINES
|
||||
// WITH_RUNTIME
|
||||
|
||||
import helpers.*
|
||||
import kotlin.coroutines.startCoroutine
|
||||
|
||||
fun interface SuspendRunnable {
|
||||
suspend fun invoke()
|
||||
}
|
||||
|
||||
fun run(r: SuspendRunnable) {
|
||||
r::invoke.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
var result = "initial"
|
||||
|
||||
suspend fun bar() {
|
||||
result = "OK"
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
run(::bar)
|
||||
return result
|
||||
}
|
||||
+5
@@ -11656,6 +11656,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
public void testReceiverEvaluatedOnce() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/receiverEvaluatedOnce.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("suspendFunInterfaceConversionCodegen.kt")
|
||||
public void testSuspendFunInterfaceConversionCodegen() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/suspendFunInterfaceConversionCodegen.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/functions")
|
||||
|
||||
+5
@@ -11656,6 +11656,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
public void testReceiverEvaluatedOnce() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/receiverEvaluatedOnce.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("suspendFunInterfaceConversionCodegen.kt")
|
||||
public void testSuspendFunInterfaceConversionCodegen() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/suspendFunInterfaceConversionCodegen.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/functions")
|
||||
|
||||
+5
@@ -10506,6 +10506,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
public void testReceiverEvaluatedOnce() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/receiverEvaluatedOnce.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("suspendFunInterfaceConversionCodegen.kt")
|
||||
public void testSuspendFunInterfaceConversionCodegen() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/suspendFunInterfaceConversionCodegen.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/functions")
|
||||
|
||||
+5
@@ -10506,6 +10506,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
public void testReceiverEvaluatedOnce() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/receiverEvaluatedOnce.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("suspendFunInterfaceConversionCodegen.kt")
|
||||
public void testSuspendFunInterfaceConversionCodegen() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/suspendFunInterfaceConversionCodegen.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/functions")
|
||||
|
||||
@@ -65,10 +65,13 @@ val KotlinType.isFunctionOrSuspendFunctionType: Boolean
|
||||
get() = isFunctionType || isSuspendFunctionType
|
||||
|
||||
val KotlinType.isBuiltinFunctionalType: Boolean
|
||||
get() = constructor.declarationDescriptor?.isBuiltinFunctionalClassDescriptor == true
|
||||
|
||||
val DeclarationDescriptor.isBuiltinFunctionalClassDescriptor: Boolean
|
||||
get() {
|
||||
val kind = constructor.declarationDescriptor?.getFunctionalClassKind()
|
||||
return kind == FunctionClassDescriptor.Kind.Function ||
|
||||
kind == FunctionClassDescriptor.Kind.SuspendFunction
|
||||
val functionalClassKind = getFunctionalClassKind()
|
||||
return functionalClassKind == FunctionClassDescriptor.Kind.Function ||
|
||||
functionalClassKind == FunctionClassDescriptor.Kind.SuspendFunction
|
||||
}
|
||||
|
||||
fun isBuiltinFunctionClass(classId: ClassId): Boolean {
|
||||
|
||||
Reference in New Issue
Block a user