diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt index bdaba11ad06..8b99075c07b 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt @@ -50,6 +50,8 @@ class DeserializedClassDescriptor( outerContext.storageManager, nameResolver.getClassId(classProto.fqName).shortClassName ) { + private val classId = nameResolver.getClassId(classProto.fqName) + private val modality = Deserialization.modality(Flags.MODALITY.get(classProto.flags)) private val visibility = Deserialization.visibility(Flags.VISIBILITY.get(classProto.flags)) private val kind = Deserialization.classKind(Flags.CLASS_KIND.get(classProto.flags)) @@ -59,7 +61,6 @@ class DeserializedClassDescriptor( private val staticScope = if (kind == ClassKind.ENUM_CLASS) StaticScopeForKotlinEnum(c.storageManager, this) else MemberScope.Empty private val typeConstructor = DeserializedClassTypeConstructor() private val memberScope = DeserializedClassMemberScope() - private val nestedClasses = if (classProto.nestedClassNameCount > 0) NestedClassDescriptors() else null private val enumEntries = if (kind == ClassKind.ENUM_CLASS) EnumEntryClassDescriptors() else null private val containingDeclaration = outerContext.containingDeclaration @@ -134,9 +135,8 @@ class DeserializedClassDescriptor( override fun getCompanionObjectDescriptor(): ClassDescriptor? = companionObjectDescriptor() - internal fun hasNestedClass(name: Name): Boolean { - return nestedClasses != null && name in nestedClasses.nestedClassNames - } + internal fun hasNestedClass(name: Name): Boolean = + name in memberScope.classNames override fun toString() = "deserialized class $name" // not using descriptor render to preserve laziness @@ -186,9 +186,11 @@ class DeserializedClassDescriptor( } private inner class DeserializedClassMemberScope : DeserializedMemberScope( - c, classProto.functionList, classProto.propertyList, classProto.typeAliasList + c, classProto.functionList, classProto.propertyList, classProto.typeAliasList, + classProto.nestedClassNameList.map(c.nameResolver::getName).let { { it } } // workaround KT-13454 ) { private val classDescriptor: DeserializedClassDescriptor get() = this@DeserializedClassDescriptor + private val allDescriptors = c.storageManager.createLazyValue { computeDescriptors(DescriptorKindFilter.ALL, MemberScope.ALL_NAME_FILTER, NoLookupLocation.WHEN_GET_ALL_DESCRIPTORS) } @@ -259,14 +261,11 @@ class DeserializedClassDescriptor( override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? { recordLookup(name, location) - return classDescriptor.enumEntries?.findEnumEntry(name) ?: - classDescriptor.nestedClasses?.findNestedClass(name) ?: - getTypeAlias(name) + classDescriptor.enumEntries?.findEnumEntry(name)?.let { return it } + return super.getContributedClassifier(name, location) } - override fun addClassifierDescriptors(result: MutableCollection, nameFilter: (Name) -> Boolean) { - result.addAll(classDescriptor.nestedClasses?.all().orEmpty()) - } + override fun createClassId(name: Name) = classId.createNestedClassId(name) override fun addEnumEntryDescriptors(result: MutableCollection, nameFilter: (Name) -> Boolean) { result.addAll(classDescriptor.enumEntries?.all().orEmpty()) @@ -277,24 +276,6 @@ class DeserializedClassDescriptor( } } - private inner class NestedClassDescriptors { - private val classId = c.nameResolver.getClassId(classProto.fqName) - - internal val nestedClassNames = classProto.nestedClassNameList.map { c.nameResolver.getName(it) }.toSet() - - private fun getClassDescriptor(name: Name): ClassDescriptor? = - c.components.deserializeClass(classId.createNestedClassId(name)) - - fun findNestedClass(name: Name): ClassDescriptor? = - if (name in nestedClassNames) { - getClassDescriptor(name) - } - else null - - fun all(): Collection = - nestedClassNames.mapNotNull(this::getClassDescriptor) - } - private inner class EnumEntryClassDescriptors { private val enumEntryProtos = classProto.enumEntryList.associateBy { c.nameResolver.getName(it.name) } diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedMemberScope.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedMemberScope.kt index f3726e2a798..ba654a2fc21 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedMemberScope.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedMemberScope.kt @@ -16,11 +16,9 @@ package org.jetbrains.kotlin.serialization.deserialization.descriptors -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.descriptors.PropertyDescriptor -import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor -import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor +import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.incremental.components.LookupLocation +import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.protobuf.MessageLite import org.jetbrains.kotlin.resolve.MemberComparator @@ -38,7 +36,8 @@ abstract class DeserializedMemberScope protected constructor( protected val c: DeserializationContext, functionList: Collection, propertyList: Collection, - typeAliasList: Collection + typeAliasList: Collection, + classNames: () -> Collection ) : MemberScopeImpl() { private val functionProtos by @@ -73,6 +72,8 @@ abstract class DeserializedMemberScope protected constructor( private val typeAliasNames: Set get() = typeAliasProtos.keys + internal val classNames by c.storageManager.createLazyValue { classNames().toSet() } + override fun getFunctionNames() = functionNamesLazy override fun getVariableNames() = variableNamesLazy @@ -131,13 +132,6 @@ abstract class DeserializedMemberScope protected constructor( return properties(name) } - protected fun getTypeAlias(name: Name): TypeAliasDescriptor? { - if (name !in typeAliasNames) return null - return typeAliasByName(name) - } - - protected abstract fun addClassifierDescriptors(result: MutableCollection, nameFilter: (Name) -> Boolean) - protected fun computeDescriptors( kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean, @@ -154,13 +148,17 @@ abstract class DeserializedMemberScope protected constructor( addFunctionsAndProperties(result, kindFilter, nameFilter, location) if (kindFilter.acceptsKinds(DescriptorKindFilter.CLASSIFIERS_MASK)) { - addClassifierDescriptors(result, nameFilter) + for (className in classNames) { + if (nameFilter(className)) { + result.addIfNotNull(deserializeClass(className)) + } + } } if (kindFilter.acceptsKinds(DescriptorKindFilter.TYPE_ALIASES_MASK)) { for (typeAliasName in typeAliasNames) { if (nameFilter(typeAliasName)) { - result.addIfNotNull(getTypeAlias(typeAliasName)) + result.addIfNotNull(typeAliasByName(typeAliasName)) } } } @@ -208,6 +206,21 @@ abstract class DeserializedMemberScope protected constructor( result.addAll(subResult) } + override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? = + when { + hasClass(name) -> deserializeClass(name) + name in typeAliasNames -> typeAliasByName(name) + else -> null + } + + private fun deserializeClass(name: Name): ClassDescriptor? = + c.components.deserializeClass(createClassId(name)) + + protected open fun hasClass(name: Name): Boolean = + name in classNames + + protected abstract fun createClassId(name: Name): ClassId + protected abstract fun getNonDeclaredFunctionNames(): Set protected abstract fun getNonDeclaredVariableNames(): Set diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedPackageMemberScope.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedPackageMemberScope.kt index 44e21c2c74b..c7065e639d8 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedPackageMemberScope.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedPackageMemberScope.kt @@ -16,19 +16,17 @@ package org.jetbrains.kotlin.serialization.deserialization.descriptors -import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.incremental.components.LookupLocation +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor +import org.jetbrains.kotlin.descriptors.SourceElement import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents import org.jetbrains.kotlin.serialization.deserialization.NameResolver import org.jetbrains.kotlin.serialization.deserialization.TypeTable -import org.jetbrains.kotlin.storage.getValue -import org.jetbrains.kotlin.utils.addIfNotNull open class DeserializedPackageMemberScope( packageDescriptor: PackageFragmentDescriptor, @@ -39,33 +37,17 @@ open class DeserializedPackageMemberScope( classNames: () -> Collection ) : DeserializedMemberScope( components.createContext(packageDescriptor, nameResolver, TypeTable(proto.typeTable), containerSource), - proto.functionList, proto.propertyList, proto.typeAliasList + proto.functionList, proto.propertyList, proto.typeAliasList, classNames ) { private val packageFqName = packageDescriptor.fqName - internal val classNames by c.storageManager.createLazyValue { classNames().toSet() } - override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean) = computeDescriptors(kindFilter, nameFilter, NoLookupLocation.WHEN_GET_ALL_DESCRIPTORS) - override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? { - if (SpecialNames.isSafeIdentifier(name) && - (name in classNames || c.components.fictitiousClassDescriptorFactory.shouldCreateClass(packageFqName, name))) { - return getClassDescriptor(name) - } - return getTypeAlias(name) - } + override fun hasClass(name: Name) = + super.hasClass(name) || c.components.fictitiousClassDescriptorFactory.shouldCreateClass(packageFqName, name) - private fun getClassDescriptor(name: Name): ClassDescriptor? = - c.components.deserializeClass(ClassId(packageFqName, name)) - - override fun addClassifierDescriptors(result: MutableCollection, nameFilter: (Name) -> Boolean) { - for (className in classNames) { - if (nameFilter(className)) { - result.addIfNotNull(getClassDescriptor(className)) - } - } - } + override fun createClassId(name: Name) = ClassId(packageFqName, name) override fun getNonDeclaredFunctionNames(): Set = emptySet() override fun getNonDeclaredVariableNames(): Set = emptySet()