Refactoring. Move transformRuntimeFunctionTypeToSuspendFunction to TypeDeserializer
This commit is contained in:
@@ -79,37 +79,6 @@ fun transformSuspendFunctionToRuntimeFunctionType(suspendFunType: KotlinType, is
|
|||||||
).makeNullableAsSpecified(suspendFunType.isMarkedNullable)
|
).makeNullableAsSpecified(suspendFunType.isMarkedNullable)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun transformRuntimeFunctionTypeToSuspendFunction(funType: KotlinType, isReleaseCoroutines: Boolean): Pair<SimpleType?, Boolean> {
|
|
||||||
assert(funType.isFunctionType) {
|
|
||||||
"This type should be function type: $funType"
|
|
||||||
}
|
|
||||||
|
|
||||||
val continuationArgumentType = funType.getValueParameterTypesFromFunctionType().lastOrNull()?.type ?: return null to false
|
|
||||||
val continuationArgumentFqName = continuationArgumentType.constructor.declarationDescriptor?.fqNameSafe
|
|
||||||
if (continuationArgumentType.arguments.size != 1 ||
|
|
||||||
(!isContinuation(continuationArgumentFqName, isReleaseCoroutines) &&
|
|
||||||
(!isReleaseCoroutines || !isContinuation(continuationArgumentFqName, !isReleaseCoroutines)))
|
|
||||||
) {
|
|
||||||
return funType as? SimpleType to false
|
|
||||||
}
|
|
||||||
|
|
||||||
val suspendReturnType = continuationArgumentType.arguments.single().type
|
|
||||||
|
|
||||||
// Load experimental suspend function type as suspend function type
|
|
||||||
|
|
||||||
return createFunctionType(
|
|
||||||
funType.builtIns,
|
|
||||||
funType.annotations,
|
|
||||||
funType.getReceiverTypeFromFunctionType(),
|
|
||||||
funType.getValueParameterTypesFromFunctionType().dropLast(1).map(TypeProjection::getType),
|
|
||||||
// TODO: names
|
|
||||||
null,
|
|
||||||
suspendReturnType,
|
|
||||||
suspendFunction = true
|
|
||||||
).makeNullableAsSpecified(funType.isMarkedNullable) to
|
|
||||||
(isReleaseCoroutines && isContinuation(continuationArgumentFqName, !isReleaseCoroutines))
|
|
||||||
}
|
|
||||||
|
|
||||||
fun isContinuation(name: FqName?, isReleaseCoroutines: Boolean): Boolean {
|
fun isContinuation(name: FqName?, isReleaseCoroutines: Boolean): Boolean {
|
||||||
return if (isReleaseCoroutines) name == DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME_RELEASE
|
return if (isReleaseCoroutines) name == DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME_RELEASE
|
||||||
else name == DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME_EXPERIMENTAL
|
else name == DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME_EXPERIMENTAL
|
||||||
|
|||||||
+40
-12
@@ -13,9 +13,11 @@ import org.jetbrains.kotlin.metadata.ProtoBuf
|
|||||||
import org.jetbrains.kotlin.metadata.deserialization.*
|
import org.jetbrains.kotlin.metadata.deserialization.*
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedAnnotationsWithPossibleTargets
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedAnnotationsWithPossibleTargets
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedTypeParameterDescriptor
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedTypeParameterDescriptor
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
|
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@@ -163,23 +165,49 @@ class TypeDeserializer(
|
|||||||
nullable: Boolean
|
nullable: Boolean
|
||||||
): SimpleType? {
|
): SimpleType? {
|
||||||
val functionType = KotlinTypeFactory.simpleType(annotations, functionTypeConstructor, arguments, nullable)
|
val functionType = KotlinTypeFactory.simpleType(annotations, functionTypeConstructor, arguments, nullable)
|
||||||
if (!functionType.isFunctionType) return null
|
return if (!functionType.isFunctionType) null
|
||||||
|
else transformRuntimeFunctionTypeToSuspendFunction(functionType)
|
||||||
|
}
|
||||||
|
|
||||||
// kotlin.suspend is still built with LV=1.2, thus it references old Continuation
|
private fun transformRuntimeFunctionTypeToSuspendFunction(funType: KotlinType): SimpleType? {
|
||||||
// And otherwise, once stdlib is compiled with 1.3 one may want to stay at LV=1.2
|
val isReleaseCoroutines = c.components.configuration.releaseCoroutines
|
||||||
if (c.containingDeclaration.safeAs<CallableDescriptor>()?.fqNameOrNull() == KOTLIN_SUSPEND_BUILT_IN_FUNCTION_FQ_NAME) {
|
|
||||||
val (suspendFun, experimental) = transformRuntimeFunctionTypeToSuspendFunction(functionType, true)
|
val continuationArgumentType = funType.getValueParameterTypesFromFunctionType().lastOrNull()?.type ?: return null
|
||||||
if (experimental)
|
val continuationArgumentFqName = continuationArgumentType.constructor.declarationDescriptor?.fqNameSafe
|
||||||
transformRuntimeFunctionTypeToSuspendFunction(functionType, false).first?.let { return it }
|
if (continuationArgumentType.arguments.size != 1 || !(isContinuation(continuationArgumentFqName, true) ||
|
||||||
else
|
isContinuation(continuationArgumentFqName, false))
|
||||||
return suspendFun
|
) {
|
||||||
|
return funType as SimpleType?
|
||||||
}
|
}
|
||||||
|
|
||||||
val (type, experimental) = transformRuntimeFunctionTypeToSuspendFunction(functionType, c.components.configuration.releaseCoroutines)
|
val suspendReturnType = continuationArgumentType.arguments.single().type
|
||||||
|
|
||||||
experimentalSuspendFunctionTypeEncountered = experimental || experimentalSuspendFunctionTypeEncountered
|
// Load kotlin.suspend as accepting and returning suspend function type independent of its version requirement
|
||||||
|
if (c.containingDeclaration.safeAs<CallableDescriptor>()?.fqNameOrNull() == KOTLIN_SUSPEND_BUILT_IN_FUNCTION_FQ_NAME) {
|
||||||
|
return createSimpleSuspendFunctionType(funType, suspendReturnType)
|
||||||
|
}
|
||||||
|
|
||||||
return type
|
// Load experimental suspend function type as suspend function type
|
||||||
|
experimentalSuspendFunctionTypeEncountered = experimentalSuspendFunctionTypeEncountered ||
|
||||||
|
(isReleaseCoroutines && isContinuation(continuationArgumentFqName, !isReleaseCoroutines))
|
||||||
|
|
||||||
|
return createSimpleSuspendFunctionType(funType, suspendReturnType)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createSimpleSuspendFunctionType(
|
||||||
|
funType: KotlinType,
|
||||||
|
suspendReturnType: KotlinType
|
||||||
|
): SimpleType {
|
||||||
|
return createFunctionType(
|
||||||
|
funType.builtIns,
|
||||||
|
funType.annotations,
|
||||||
|
funType.getReceiverTypeFromFunctionType(),
|
||||||
|
funType.getValueParameterTypesFromFunctionType().dropLast(1).map(TypeProjection::getType),
|
||||||
|
// TODO: names
|
||||||
|
null,
|
||||||
|
suspendReturnType,
|
||||||
|
suspendFunction = true
|
||||||
|
).makeNullableAsSpecified(funType.isMarkedNullable)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun typeParameterTypeConstructor(typeParameterId: Int): TypeConstructor? =
|
private fun typeParameterTypeConstructor(typeParameterId: Int): TypeConstructor? =
|
||||||
|
|||||||
Reference in New Issue
Block a user