diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/NotFoundClasses.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/NotFoundClasses.kt index 9ceec20919d..1999305cdcc 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/NotFoundClasses.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/NotFoundClasses.kt @@ -18,22 +18,16 @@ package org.jetbrains.kotlin.serialization.deserialization import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotations -import org.jetbrains.kotlin.descriptors.impl.AbstractTypeAliasDescriptor import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorBase import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns -import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.storage.StorageManager -import org.jetbrains.kotlin.storage.getValue import org.jetbrains.kotlin.types.ClassTypeConstructorImpl -import org.jetbrains.kotlin.types.SimpleType -import org.jetbrains.kotlin.types.TypeSubstitutor import org.jetbrains.kotlin.types.Variance class NotFoundClasses(private val storageManager: StorageManager, private val module: ModuleDescriptor) { @@ -46,28 +40,7 @@ class NotFoundClasses(private val storageManager: StorageManager, private val mo EmptyPackageFragmentDescriptor(module, fqName) } - private val classes = storageManager.createMemoizedFunction { request -> - computeClassifier(request, { - owner, name, isInner, numberOfTypeParametersCount -> - MockClassDescriptor(storageManager, owner, name, isInner, numberOfTypeParametersCount) - }) - } - - private val typeAliases = storageManager.createMemoizedFunction { request -> - computeClassifier(request, { - owner, name, isInner, numberOfTypeParametersCount -> - MockTypeAliasDescriptor(storageManager, owner, name, isInner, numberOfTypeParametersCount) - }) - } - - // TODO: Uncomment this when KT-12871 is fixed - // private typealias ConstructorFunction = (DeclarationDescriptor, Name, isInner: Boolean, numberOfTypeParametersCount: Int) -> D - private fun computeClassifier( - request: ClassRequest, - constructor: (DeclarationDescriptor, Name, isInner: Boolean, numberOfTypeParametersCount: Int) -> D - ): D { - val (classId, typeParametersCount) = request - + private val classes = storageManager.createMemoizedFunction { (classId, typeParametersCount) -> if (classId.isLocal) { throw UnsupportedOperationException("Unresolved local class: $classId") } @@ -79,7 +52,7 @@ class NotFoundClasses(private val storageManager: StorageManager, private val mo // Treat a class with a nested ClassId as inner for simplicity, otherwise the outer type cannot have generic arguments val isInner = classId.isNestedClass - return constructor(container, classId.shortClassName, isInner, typeParametersCount.firstOrNull() ?: 0) + MockClassDescriptor(storageManager, container, classId.shortClassName, isInner, typeParametersCount.firstOrNull() ?: 0) } class MockClassDescriptor internal constructor( @@ -89,7 +62,11 @@ class NotFoundClasses(private val storageManager: StorageManager, private val mo private val isInner: Boolean, numberOfDeclaredTypeParameters: Int ) : ClassDescriptorBase(storageManager, container, name, SourceElement.NO_SOURCE, /* isExternal = */ false) { - private val typeParameters = createTypeParameters(this, numberOfDeclaredTypeParameters) + private val typeParameters = (1..numberOfDeclaredTypeParameters).map { index -> + TypeParameterDescriptorImpl.createWithDefaultBound( + this, Annotations.EMPTY, false, Variance.INVARIANT, Name.identifier("T$index"), index + ) + } private val typeConstructor = ClassTypeConstructorImpl(this, /* isFinal = */ true, typeParameters, setOf(module.builtIns.anyType)) @@ -117,39 +94,6 @@ class NotFoundClasses(private val storageManager: StorageManager, private val mo override fun toString() = "class $name (not found)" } - private class MockTypeAliasDescriptor( - storageManager: StorageManager, - containingDeclaration: DeclarationDescriptor, - name: Name, - private val isInner: Boolean, - numberOfDeclaredTypeParameters: Int - ) : AbstractTypeAliasDescriptor(containingDeclaration, Annotations.EMPTY, name, SourceElement.NO_SOURCE, Visibilities.PUBLIC) { - init { - initialize(createTypeParameters(this, numberOfDeclaredTypeParameters)) - } - - private val constructorTypeParameters by storageManager.createLazyValue { computeConstructorTypeParameters() } - - override fun getTypeConstructorTypeParameters() = constructorTypeParameters - - // We don't have enough information about underlying type, so just take nullable Any? - // Anyway it should not used extensively, because not found type aliases are only used for type abbreviations - override val underlyingType: SimpleType - get() = builtIns.nullableAnyType - override val expandedType: SimpleType - get() = builtIns.nullableAnyType - override fun getDefaultType(): SimpleType = - builtIns.nullableAnyType - override val classDescriptor: ClassDescriptor? - get() = expandedType.constructor.declarationDescriptor as? ClassDescriptor - - override fun isInner(): Boolean = isInner - - override fun substitute(substitutor: TypeSubstitutor) = this - - override fun toString() = "MockTypeAliasDescriptor[$fqNameUnsafe]" - } - // We create different ClassDescriptor instances for types with the same ClassId but different number of type arguments. // (This may happen when a class with the same FQ name is instantiated with different type arguments in different modules.) // It's better than creating just one descriptor because otherwise would fail in multiple places where it's asserted that @@ -157,17 +101,4 @@ class NotFoundClasses(private val storageManager: StorageManager, private val mo fun getClass(classId: ClassId, typeParametersCount: List): ClassDescriptor { return classes(ClassRequest(classId, typeParametersCount)) } - - fun getTypeAlias(classId: ClassId, typeParametersCount: List): TypeAliasDescriptor { - return typeAliases(ClassRequest(classId, typeParametersCount)) - } -} - -private fun createTypeParameters( - classifierDescriptor: ClassifierDescriptor, - numberOfDeclaredTypeParameters: Int -) = (1..numberOfDeclaredTypeParameters).map { index -> - TypeParameterDescriptorImpl.createWithDefaultBound( - classifierDescriptor, Annotations.EMPTY, false, Variance.INVARIANT, Name.identifier("T$index"), index - ) } diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/TypeDeserializer.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/TypeDeserializer.kt index 24fd6d265f4..6588724e940 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/TypeDeserializer.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/TypeDeserializer.kt @@ -112,39 +112,31 @@ class TypeDeserializer( return simpleType.withAbbreviation(simpleType(abbreviatedTypeProto, additionalAnnotations)) } - private fun typeConstructor(proto: ProtoBuf.Type): TypeConstructor = - when { - proto.hasClassName() -> { - classDescriptors(proto.className)?.typeConstructor - ?: c.nameResolver.getClassId(proto.className).let { classId -> - c.components.notFoundClasses.getClass(classId, computeTypeParametersCount(classId, proto, c.typeTable)).typeConstructor - } - } - proto.hasTypeParameter() -> - typeParameterTypeConstructor(proto.typeParameter) - ?: ErrorUtils.createErrorTypeConstructor("Unknown type parameter ${proto.typeParameter}") - proto.hasTypeParameterName() -> { - val container = c.containingDeclaration - val name = c.nameResolver.getString(proto.typeParameterName) - val parameter = ownTypeParameters.find { it.name.asString() == name } - parameter?.typeConstructor ?: ErrorUtils.createErrorTypeConstructor("Deserialized type parameter $name in $container") - } - proto.hasTypeAliasName() -> { - typeAliasDescriptors(proto.typeAliasName)?.typeConstructor - ?: c.nameResolver.getClassId(proto.typeAliasName).let { classId -> - c.components.notFoundClasses.getTypeAlias(classId, computeTypeParametersCount(classId, proto, c.typeTable)).typeConstructor - } - } - else -> ErrorUtils.createErrorTypeConstructor("Unknown type") + private fun typeConstructor(proto: ProtoBuf.Type): TypeConstructor { + fun notFoundClass(classIdIndex: Int): ClassDescriptor { + val classId = c.nameResolver.getClassId(classIdIndex) + val typeParametersCount = generateSequence(proto) { it.outerType(c.typeTable) }.map { it.argumentCount }.toMutableList() + val classNestingLevel = generateSequence(classId, ClassId::getOuterClassId).count() + while (typeParametersCount.size < classNestingLevel) { + typeParametersCount.add(0) } - - private fun computeTypeParametersCount(classId: ClassId, proto: ProtoBuf.Type, typeTable: TypeTable): List { - val typeParametersCount = generateSequence(proto) { it.outerType(typeTable) }.map { it.argumentCount }.toMutableList() - val classNestingLevel = generateSequence(classId, ClassId::getOuterClassId).count() - while (typeParametersCount.size < classNestingLevel) { - typeParametersCount.add(0) + return c.components.notFoundClasses.getClass(classId, typeParametersCount) + } + + return when { + proto.hasClassName() -> (classDescriptors(proto.className) ?: notFoundClass(proto.className)).typeConstructor + proto.hasTypeParameter() -> + typeParameterTypeConstructor(proto.typeParameter) + ?: ErrorUtils.createErrorTypeConstructor("Unknown type parameter ${proto.typeParameter}") + proto.hasTypeParameterName() -> { + val container = c.containingDeclaration + val name = c.nameResolver.getString(proto.typeParameterName) + val parameter = ownTypeParameters.find { it.name.asString() == name } + parameter?.typeConstructor ?: ErrorUtils.createErrorTypeConstructor("Deserialized type parameter $name in $container") + } + proto.hasTypeAliasName() -> (typeAliasDescriptors(proto.typeAliasName) ?: notFoundClass(proto.typeAliasName)).typeConstructor + else -> ErrorUtils.createErrorTypeConstructor("Unknown type") } - return typeParametersCount } private fun createSuspendFunctionType(