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(),
|
erasedInterfaceFunction.getValueParameters(), erasedInterfaceFunction.getReturnType(),
|
||||||
Modality.OPEN, erasedInterfaceFunction.getVisibility());
|
Modality.OPEN, erasedInterfaceFunction.getVisibility());
|
||||||
|
|
||||||
|
descriptorForBridges.setSuspend(descriptor.isSuspend());
|
||||||
|
|
||||||
DescriptorUtilsKt.setSingleOverridden(descriptorForBridges, erasedInterfaceFunction);
|
DescriptorUtilsKt.setSingleOverridden(descriptorForBridges, erasedInterfaceFunction);
|
||||||
codegen.generateBridges(descriptorForBridges);
|
codegen.generateBridges(descriptorForBridges);
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.codegen.coroutines
|
|||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import org.jetbrains.kotlin.backend.common.COROUTINE_SUSPENDED_NAME
|
import org.jetbrains.kotlin.backend.common.COROUTINE_SUSPENDED_NAME
|
||||||
import org.jetbrains.kotlin.backend.common.isBuiltInSuspendCoroutineUninterceptedOrReturn
|
import org.jetbrains.kotlin.backend.common.isBuiltInSuspendCoroutineUninterceptedOrReturn
|
||||||
|
import org.jetbrains.kotlin.builtins.isBuiltinFunctionalClassDescriptor
|
||||||
import org.jetbrains.kotlin.builtins.isBuiltinFunctionalType
|
import org.jetbrains.kotlin.builtins.isBuiltinFunctionalType
|
||||||
import org.jetbrains.kotlin.codegen.*
|
import org.jetbrains.kotlin.codegen.*
|
||||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||||
@@ -263,7 +264,7 @@ fun <D : FunctionDescriptor> getOrCreateJvmSuspendFunctionView(
|
|||||||
annotations = Annotations.EMPTY,
|
annotations = Annotations.EMPTY,
|
||||||
name = CONTINUATION_PARAMETER_NAME,
|
name = CONTINUATION_PARAMETER_NAME,
|
||||||
// Add j.l.Object to invoke(), because that is the type of parameters we have in FunctionN+1
|
// 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
|
function.builtIns.nullableAnyType
|
||||||
else
|
else
|
||||||
function.getContinuationParameterTypeOfSuspendFunction(isReleaseCoroutines),
|
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 {
|
public void testReceiverEvaluatedOnce() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/funInterface/receiverEvaluatedOnce.kt");
|
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")
|
@TestMetadata("compiler/testData/codegen/box/functions")
|
||||||
|
|||||||
+5
@@ -11656,6 +11656,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
public void testReceiverEvaluatedOnce() throws Exception {
|
public void testReceiverEvaluatedOnce() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/funInterface/receiverEvaluatedOnce.kt");
|
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")
|
@TestMetadata("compiler/testData/codegen/box/functions")
|
||||||
|
|||||||
+5
@@ -10506,6 +10506,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
public void testReceiverEvaluatedOnce() throws Exception {
|
public void testReceiverEvaluatedOnce() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/funInterface/receiverEvaluatedOnce.kt");
|
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")
|
@TestMetadata("compiler/testData/codegen/box/functions")
|
||||||
|
|||||||
+5
@@ -10506,6 +10506,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
public void testReceiverEvaluatedOnce() throws Exception {
|
public void testReceiverEvaluatedOnce() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/funInterface/receiverEvaluatedOnce.kt");
|
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")
|
@TestMetadata("compiler/testData/codegen/box/functions")
|
||||||
|
|||||||
@@ -65,10 +65,13 @@ val KotlinType.isFunctionOrSuspendFunctionType: Boolean
|
|||||||
get() = isFunctionType || isSuspendFunctionType
|
get() = isFunctionType || isSuspendFunctionType
|
||||||
|
|
||||||
val KotlinType.isBuiltinFunctionalType: Boolean
|
val KotlinType.isBuiltinFunctionalType: Boolean
|
||||||
|
get() = constructor.declarationDescriptor?.isBuiltinFunctionalClassDescriptor == true
|
||||||
|
|
||||||
|
val DeclarationDescriptor.isBuiltinFunctionalClassDescriptor: Boolean
|
||||||
get() {
|
get() {
|
||||||
val kind = constructor.declarationDescriptor?.getFunctionalClassKind()
|
val functionalClassKind = getFunctionalClassKind()
|
||||||
return kind == FunctionClassDescriptor.Kind.Function ||
|
return functionalClassKind == FunctionClassDescriptor.Kind.Function ||
|
||||||
kind == FunctionClassDescriptor.Kind.SuspendFunction
|
functionalClassKind == FunctionClassDescriptor.Kind.SuspendFunction
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isBuiltinFunctionClass(classId: ClassId): Boolean {
|
fun isBuiltinFunctionClass(classId: ClassId): Boolean {
|
||||||
|
|||||||
Reference in New Issue
Block a user