FIR: fix suspend type serialization
This commit is contained in:
+6
@@ -13711,6 +13711,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
public void testExtensionAlias() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/fir/ExtensionAlias.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("SuspendExtension.kt")
|
||||
public void testSuspendExtension() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/fir/SuspendExtension.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+4
-20
@@ -5,7 +5,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.serialization
|
||||
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
@@ -28,6 +27,7 @@ import org.jetbrains.kotlin.fir.resolve.calls.varargElementType
|
||||
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.isSuspendFunctionType
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.suspendFunctionTypeToFunctionTypeWithContinuation
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.sealedInheritors
|
||||
import org.jetbrains.kotlin.fir.serialization.constant.EnumValue
|
||||
@@ -35,7 +35,6 @@ import org.jetbrains.kotlin.fir.serialization.constant.IntValue
|
||||
import org.jetbrains.kotlin.fir.serialization.constant.StringValue
|
||||
import org.jetbrains.kotlin.fir.serialization.constant.toConstantValue
|
||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitNullableAnyTypeRef
|
||||
@@ -579,7 +578,9 @@ class FirElementSerializer private constructor(
|
||||
}
|
||||
is ConeClassLikeType -> {
|
||||
if (type.isSuspendFunctionType(session)) {
|
||||
val runtimeFunctionType = transformSuspendFunctionToRuntimeFunctionType(type)
|
||||
val runtimeFunctionType = type.suspendFunctionTypeToFunctionTypeWithContinuation(
|
||||
session, CONTINUATION_INTERFACE_CLASS_ID
|
||||
)
|
||||
val functionType = typeProto(runtimeFunctionType)
|
||||
functionType.flags = Flags.getTypeFlags(true)
|
||||
return functionType
|
||||
@@ -658,23 +659,6 @@ class FirElementSerializer private constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun transformSuspendFunctionToRuntimeFunctionType(type: ConeClassLikeType): ConeClassLikeType {
|
||||
val suspendClassId = type.classId!!
|
||||
val relativeClassName = suspendClassId.relativeClassName.asString()
|
||||
val kind =
|
||||
if (relativeClassName.startsWith("K")) FunctionClassKind.KFunction
|
||||
else FunctionClassKind.Function
|
||||
val runtimeClassId = ClassId(kind.packageFqName, Name.identifier(relativeClassName.replaceFirst("Suspend", "")))
|
||||
val continuationClassId = CONTINUATION_INTERFACE_CLASS_ID
|
||||
return ConeClassLikeLookupTagImpl(runtimeClassId).constructClassType(
|
||||
(type.typeArguments.toList() + ConeClassLikeLookupTagImpl(continuationClassId).constructClassType(
|
||||
arrayOf(type.typeArguments.last()),
|
||||
isNullable = false
|
||||
)).toTypedArray(),
|
||||
type.isNullable
|
||||
)
|
||||
}
|
||||
|
||||
private fun fillFromPossiblyInnerType(builder: ProtoBuf.Type.Builder, type: ConeClassLikeType) {
|
||||
val classifierSymbol = type.lookupTag.toSymbol(session)
|
||||
if (classifierSymbol != null) {
|
||||
|
||||
+18
-1
@@ -89,7 +89,24 @@ fun ConeKotlinType.suspendFunctionTypeToFunctionType(session: FirSession): ConeC
|
||||
if (isKFunctionType(session)) FunctionClassKind.KFunction
|
||||
else FunctionClassKind.Function
|
||||
val functionalTypeId = ClassId(kind.packageFqName, kind.numberedClassName(typeArguments.size - 1))
|
||||
return ConeClassLikeTypeImpl(ConeClassLikeLookupTagImpl(functionalTypeId), typeArguments, isNullable = false)
|
||||
return ConeClassLikeTypeImpl(ConeClassLikeLookupTagImpl(functionalTypeId), typeArguments, isNullable = false, attributes = attributes)
|
||||
}
|
||||
|
||||
fun ConeKotlinType.suspendFunctionTypeToFunctionTypeWithContinuation(session: FirSession, continuationClassId: ClassId): ConeClassLikeType {
|
||||
require(this.isSuspendFunctionType(session))
|
||||
val kind =
|
||||
if (isKFunctionType(session)) FunctionClassKind.KFunction
|
||||
else FunctionClassKind.Function
|
||||
val functionalTypeId = ClassId(kind.packageFqName, kind.numberedClassName(typeArguments.size))
|
||||
return ConeClassLikeTypeImpl(
|
||||
ConeClassLikeLookupTagImpl(functionalTypeId),
|
||||
typeArguments = (type.typeArguments.dropLast(1) + ConeClassLikeLookupTagImpl(continuationClassId).constructClassType(
|
||||
arrayOf(type.typeArguments.last()),
|
||||
isNullable = false
|
||||
) + type.typeArguments.last()).toTypedArray(),
|
||||
isNullable = false,
|
||||
attributes = attributes
|
||||
)
|
||||
}
|
||||
|
||||
fun ConeKotlinType.isSubtypeOfFunctionalType(session: FirSession, expectedFunctionalType: ConeClassLikeType): Boolean {
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_BACKEND: JVM
|
||||
// MODULE: lib
|
||||
// FILE: A.kt
|
||||
|
||||
class CoroutineScope
|
||||
|
||||
suspend fun <T> runWithTimeout(
|
||||
block: suspend CoroutineScope.() -> T
|
||||
): T? = null
|
||||
|
||||
// MODULE: main(lib)
|
||||
// FILE: B.kt
|
||||
|
||||
suspend fun foo(): Boolean = runWithTimeout {
|
||||
false
|
||||
} ?: true
|
||||
|
||||
fun box(): String = "OK"
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// FILE: A.kt
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
|
||||
+6
@@ -13711,6 +13711,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
public void testExtensionAlias() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/fir/ExtensionAlias.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("SuspendExtension.kt")
|
||||
public void testSuspendExtension() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/fir/SuspendExtension.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+6
@@ -13711,6 +13711,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
public void testExtensionAlias() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/fir/ExtensionAlias.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("SuspendExtension.kt")
|
||||
public void testSuspendExtension() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/fir/SuspendExtension.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+5
@@ -12034,6 +12034,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Fir extends AbstractLightAnalysisModeTest {
|
||||
@TestMetadata("SuspendExtension.kt")
|
||||
public void ignoreSuspendExtension() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/fir/SuspendExtension.kt");
|
||||
}
|
||||
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user