Fix expect discrimination with actual typealias in deserialization
* For types encountered during deserialization, search for a classifier, not necessarily a class, across module dependencies (i.e. accept type aliases, returned when actual type alias discriminates an expect class). * When the referenced type is a type alias, expand it, so that when the descriptor is compared to the expansion in other places, they match. * Also, when resolving an abbreviation, don't expand the type aliases, as there are assumptions in the code base that an abbreviation is a type alias.
This commit is contained in:
+2
-2
@@ -318,8 +318,8 @@ class MemberDeserializer(private val c: DeserializationContext) {
|
||||
val local = c.childContext(typeAlias, proto.typeParameterList)
|
||||
typeAlias.initialize(
|
||||
local.typeDeserializer.ownTypeParameters,
|
||||
local.typeDeserializer.simpleType(proto.underlyingType(c.typeTable)),
|
||||
local.typeDeserializer.simpleType(proto.expandedType(c.typeTable)),
|
||||
local.typeDeserializer.simpleType(proto.underlyingType(c.typeTable), expandTypeAliases = false),
|
||||
local.typeDeserializer.simpleType(proto.expandedType(c.typeTable), expandTypeAliases = false),
|
||||
typeAlias.checkExperimentalCoroutine(local.typeDeserializer)
|
||||
)
|
||||
|
||||
|
||||
+20
-16
@@ -11,8 +11,6 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.deserialization.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedAnnotations
|
||||
@@ -30,9 +28,10 @@ class TypeDeserializer(
|
||||
private val containerPresentableName: String,
|
||||
var experimentalSuspendFunctionTypeEncountered: Boolean = false
|
||||
) {
|
||||
private val classDescriptors: (Int) -> ClassDescriptor? = c.storageManager.createMemoizedFunctionWithNullableValues { fqNameIndex ->
|
||||
computeClassDescriptor(fqNameIndex)
|
||||
}
|
||||
private val classifierDescriptors: (Int) -> ClassifierDescriptor? =
|
||||
c.storageManager.createMemoizedFunctionWithNullableValues { fqNameIndex ->
|
||||
computeClassifierDescriptor(fqNameIndex)
|
||||
}
|
||||
|
||||
private val typeAliasDescriptors: (Int) -> ClassifierDescriptor? =
|
||||
c.storageManager.createMemoizedFunctionWithNullableValues { fqNameIndex ->
|
||||
@@ -62,10 +61,10 @@ class TypeDeserializer(
|
||||
return c.components.flexibleTypeDeserializer.create(proto, id, lowerBound, upperBound)
|
||||
}
|
||||
|
||||
return simpleType(proto)
|
||||
return simpleType(proto, expandTypeAliases = true)
|
||||
}
|
||||
|
||||
fun simpleType(proto: ProtoBuf.Type): SimpleType {
|
||||
fun simpleType(proto: ProtoBuf.Type, expandTypeAliases: Boolean = true): SimpleType {
|
||||
val localClassifierType = when {
|
||||
proto.hasClassName() -> computeLocalClassifierReplacementType(proto.className)
|
||||
proto.hasTypeAliasName() -> computeLocalClassifierReplacementType(proto.typeAliasName)
|
||||
@@ -90,17 +89,22 @@ class TypeDeserializer(
|
||||
typeArgument(constructor.parameters.getOrNull(index), argumentProto)
|
||||
}.toList()
|
||||
|
||||
val simpleType = if (Flags.SUSPEND_TYPE.get(proto.flags)) {
|
||||
createSuspendFunctionType(annotations, constructor, arguments, proto.nullable)
|
||||
} else {
|
||||
KotlinTypeFactory.simpleType(annotations, constructor, arguments, proto.nullable)
|
||||
val declarationDescriptor = constructor.declarationDescriptor
|
||||
|
||||
val simpleType = when {
|
||||
expandTypeAliases && declarationDescriptor is TypeAliasDescriptor ->
|
||||
with(KotlinTypeFactory) { declarationDescriptor.computeExpandedType(arguments) }
|
||||
Flags.SUSPEND_TYPE.get(proto.flags) ->
|
||||
createSuspendFunctionType(annotations, constructor, arguments, proto.nullable)
|
||||
else ->
|
||||
KotlinTypeFactory.simpleType(annotations, constructor, arguments, proto.nullable)
|
||||
}
|
||||
|
||||
val computedType = proto.abbreviatedType(c.typeTable)?.let {
|
||||
simpleType.withAbbreviation(simpleType(it))
|
||||
// The abbreviation type is expected to be a typealias, and it should not get expanded, we need to keep it
|
||||
simpleType.withAbbreviation(simpleType(it, expandTypeAliases = false))
|
||||
} ?: simpleType
|
||||
|
||||
|
||||
if (proto.hasClassName()) {
|
||||
val classId = c.nameResolver.getClassId(proto.className)
|
||||
return c.components.platformDependentTypeTransformer.transformPlatformType(classId, computedType)
|
||||
@@ -121,7 +125,7 @@ class TypeDeserializer(
|
||||
}
|
||||
|
||||
return when {
|
||||
proto.hasClassName() -> (classDescriptors(proto.className) ?: notFoundClass(proto.className)).typeConstructor
|
||||
proto.hasClassName() -> (classifierDescriptors(proto.className) ?: notFoundClass(proto.className)).typeConstructor
|
||||
proto.hasTypeParameter() ->
|
||||
typeParameterTypeConstructor(proto.typeParameter)
|
||||
?: ErrorUtils.createErrorTypeConstructor(
|
||||
@@ -223,13 +227,13 @@ class TypeDeserializer(
|
||||
private fun typeParameterTypeConstructor(typeParameterId: Int): TypeConstructor? =
|
||||
typeParameterDescriptors[typeParameterId]?.typeConstructor ?: parent?.typeParameterTypeConstructor(typeParameterId)
|
||||
|
||||
private fun computeClassDescriptor(fqNameIndex: Int): ClassDescriptor? {
|
||||
private fun computeClassifierDescriptor(fqNameIndex: Int): ClassifierDescriptor? {
|
||||
val id = c.nameResolver.getClassId(fqNameIndex)
|
||||
if (id.isLocal) {
|
||||
// Local classes can't be found in scopes
|
||||
return c.components.deserializeClass(id)
|
||||
}
|
||||
return c.components.moduleDescriptor.findClassAcrossModuleDependencies(id)
|
||||
return c.components.moduleDescriptor.findClassifierAcrossModuleDependencies(id)
|
||||
}
|
||||
|
||||
private fun computeLocalClassifierReplacementType(className: Int): SimpleType? {
|
||||
|
||||
Reference in New Issue
Block a user