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)
|
val local = c.childContext(typeAlias, proto.typeParameterList)
|
||||||
typeAlias.initialize(
|
typeAlias.initialize(
|
||||||
local.typeDeserializer.ownTypeParameters,
|
local.typeDeserializer.ownTypeParameters,
|
||||||
local.typeDeserializer.simpleType(proto.underlyingType(c.typeTable)),
|
local.typeDeserializer.simpleType(proto.underlyingType(c.typeTable), expandTypeAliases = false),
|
||||||
local.typeDeserializer.simpleType(proto.expandedType(c.typeTable)),
|
local.typeDeserializer.simpleType(proto.expandedType(c.typeTable), expandTypeAliases = false),
|
||||||
typeAlias.checkExperimentalCoroutine(local.typeDeserializer)
|
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.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.name.FqName
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
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.resolve.descriptorUtil.fqNameSafe
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedAnnotations
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedAnnotations
|
||||||
@@ -30,9 +28,10 @@ class TypeDeserializer(
|
|||||||
private val containerPresentableName: String,
|
private val containerPresentableName: String,
|
||||||
var experimentalSuspendFunctionTypeEncountered: Boolean = false
|
var experimentalSuspendFunctionTypeEncountered: Boolean = false
|
||||||
) {
|
) {
|
||||||
private val classDescriptors: (Int) -> ClassDescriptor? = c.storageManager.createMemoizedFunctionWithNullableValues { fqNameIndex ->
|
private val classifierDescriptors: (Int) -> ClassifierDescriptor? =
|
||||||
computeClassDescriptor(fqNameIndex)
|
c.storageManager.createMemoizedFunctionWithNullableValues { fqNameIndex ->
|
||||||
}
|
computeClassifierDescriptor(fqNameIndex)
|
||||||
|
}
|
||||||
|
|
||||||
private val typeAliasDescriptors: (Int) -> ClassifierDescriptor? =
|
private val typeAliasDescriptors: (Int) -> ClassifierDescriptor? =
|
||||||
c.storageManager.createMemoizedFunctionWithNullableValues { fqNameIndex ->
|
c.storageManager.createMemoizedFunctionWithNullableValues { fqNameIndex ->
|
||||||
@@ -62,10 +61,10 @@ class TypeDeserializer(
|
|||||||
return c.components.flexibleTypeDeserializer.create(proto, id, lowerBound, upperBound)
|
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 {
|
val localClassifierType = when {
|
||||||
proto.hasClassName() -> computeLocalClassifierReplacementType(proto.className)
|
proto.hasClassName() -> computeLocalClassifierReplacementType(proto.className)
|
||||||
proto.hasTypeAliasName() -> computeLocalClassifierReplacementType(proto.typeAliasName)
|
proto.hasTypeAliasName() -> computeLocalClassifierReplacementType(proto.typeAliasName)
|
||||||
@@ -90,17 +89,22 @@ class TypeDeserializer(
|
|||||||
typeArgument(constructor.parameters.getOrNull(index), argumentProto)
|
typeArgument(constructor.parameters.getOrNull(index), argumentProto)
|
||||||
}.toList()
|
}.toList()
|
||||||
|
|
||||||
val simpleType = if (Flags.SUSPEND_TYPE.get(proto.flags)) {
|
val declarationDescriptor = constructor.declarationDescriptor
|
||||||
createSuspendFunctionType(annotations, constructor, arguments, proto.nullable)
|
|
||||||
} else {
|
val simpleType = when {
|
||||||
KotlinTypeFactory.simpleType(annotations, constructor, arguments, proto.nullable)
|
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 {
|
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
|
} ?: simpleType
|
||||||
|
|
||||||
|
|
||||||
if (proto.hasClassName()) {
|
if (proto.hasClassName()) {
|
||||||
val classId = c.nameResolver.getClassId(proto.className)
|
val classId = c.nameResolver.getClassId(proto.className)
|
||||||
return c.components.platformDependentTypeTransformer.transformPlatformType(classId, computedType)
|
return c.components.platformDependentTypeTransformer.transformPlatformType(classId, computedType)
|
||||||
@@ -121,7 +125,7 @@ class TypeDeserializer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return when {
|
return when {
|
||||||
proto.hasClassName() -> (classDescriptors(proto.className) ?: notFoundClass(proto.className)).typeConstructor
|
proto.hasClassName() -> (classifierDescriptors(proto.className) ?: notFoundClass(proto.className)).typeConstructor
|
||||||
proto.hasTypeParameter() ->
|
proto.hasTypeParameter() ->
|
||||||
typeParameterTypeConstructor(proto.typeParameter)
|
typeParameterTypeConstructor(proto.typeParameter)
|
||||||
?: ErrorUtils.createErrorTypeConstructor(
|
?: ErrorUtils.createErrorTypeConstructor(
|
||||||
@@ -223,13 +227,13 @@ class TypeDeserializer(
|
|||||||
private fun typeParameterTypeConstructor(typeParameterId: Int): TypeConstructor? =
|
private fun typeParameterTypeConstructor(typeParameterId: Int): TypeConstructor? =
|
||||||
typeParameterDescriptors[typeParameterId]?.typeConstructor ?: parent?.typeParameterTypeConstructor(typeParameterId)
|
typeParameterDescriptors[typeParameterId]?.typeConstructor ?: parent?.typeParameterTypeConstructor(typeParameterId)
|
||||||
|
|
||||||
private fun computeClassDescriptor(fqNameIndex: Int): ClassDescriptor? {
|
private fun computeClassifierDescriptor(fqNameIndex: Int): ClassifierDescriptor? {
|
||||||
val id = c.nameResolver.getClassId(fqNameIndex)
|
val id = c.nameResolver.getClassId(fqNameIndex)
|
||||||
if (id.isLocal) {
|
if (id.isLocal) {
|
||||||
// Local classes can't be found in scopes
|
// Local classes can't be found in scopes
|
||||||
return c.components.deserializeClass(id)
|
return c.components.deserializeClass(id)
|
||||||
}
|
}
|
||||||
return c.components.moduleDescriptor.findClassAcrossModuleDependencies(id)
|
return c.components.moduleDescriptor.findClassifierAcrossModuleDependencies(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun computeLocalClassifierReplacementType(className: Int): SimpleType? {
|
private fun computeLocalClassifierReplacementType(className: Int): SimpleType? {
|
||||||
|
|||||||
Reference in New Issue
Block a user