Refactor class lookup in deserialized scopes

Move the logic to DeserializedMemberScope; drop NestedClassDescriptors
This commit is contained in:
Alexander Udalov
2016-10-11 16:12:45 +03:00
parent e1ce6f88d5
commit 8828e671f5
3 changed files with 44 additions and 68 deletions
@@ -50,6 +50,8 @@ class DeserializedClassDescriptor(
outerContext.storageManager, outerContext.storageManager,
nameResolver.getClassId(classProto.fqName).shortClassName nameResolver.getClassId(classProto.fqName).shortClassName
) { ) {
private val classId = nameResolver.getClassId(classProto.fqName)
private val modality = Deserialization.modality(Flags.MODALITY.get(classProto.flags)) private val modality = Deserialization.modality(Flags.MODALITY.get(classProto.flags))
private val visibility = Deserialization.visibility(Flags.VISIBILITY.get(classProto.flags)) private val visibility = Deserialization.visibility(Flags.VISIBILITY.get(classProto.flags))
private val kind = Deserialization.classKind(Flags.CLASS_KIND.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 staticScope = if (kind == ClassKind.ENUM_CLASS) StaticScopeForKotlinEnum(c.storageManager, this) else MemberScope.Empty
private val typeConstructor = DeserializedClassTypeConstructor() private val typeConstructor = DeserializedClassTypeConstructor()
private val memberScope = DeserializedClassMemberScope() 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 enumEntries = if (kind == ClassKind.ENUM_CLASS) EnumEntryClassDescriptors() else null
private val containingDeclaration = outerContext.containingDeclaration private val containingDeclaration = outerContext.containingDeclaration
@@ -134,9 +135,8 @@ class DeserializedClassDescriptor(
override fun getCompanionObjectDescriptor(): ClassDescriptor? = companionObjectDescriptor() override fun getCompanionObjectDescriptor(): ClassDescriptor? = companionObjectDescriptor()
internal fun hasNestedClass(name: Name): Boolean { internal fun hasNestedClass(name: Name): Boolean =
return nestedClasses != null && name in nestedClasses.nestedClassNames name in memberScope.classNames
}
override fun toString() = "deserialized class $name" // not using descriptor render to preserve laziness override fun toString() = "deserialized class $name" // not using descriptor render to preserve laziness
@@ -186,9 +186,11 @@ class DeserializedClassDescriptor(
} }
private inner class DeserializedClassMemberScope : DeserializedMemberScope( 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 classDescriptor: DeserializedClassDescriptor get() = this@DeserializedClassDescriptor
private val allDescriptors = c.storageManager.createLazyValue { private val allDescriptors = c.storageManager.createLazyValue {
computeDescriptors(DescriptorKindFilter.ALL, MemberScope.ALL_NAME_FILTER, NoLookupLocation.WHEN_GET_ALL_DESCRIPTORS) 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? { override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? {
recordLookup(name, location) recordLookup(name, location)
return classDescriptor.enumEntries?.findEnumEntry(name) ?: classDescriptor.enumEntries?.findEnumEntry(name)?.let { return it }
classDescriptor.nestedClasses?.findNestedClass(name) ?: return super.getContributedClassifier(name, location)
getTypeAlias(name)
} }
override fun addClassifierDescriptors(result: MutableCollection<DeclarationDescriptor>, nameFilter: (Name) -> Boolean) { override fun createClassId(name: Name) = classId.createNestedClassId(name)
result.addAll(classDescriptor.nestedClasses?.all().orEmpty())
}
override fun addEnumEntryDescriptors(result: MutableCollection<DeclarationDescriptor>, nameFilter: (Name) -> Boolean) { override fun addEnumEntryDescriptors(result: MutableCollection<DeclarationDescriptor>, nameFilter: (Name) -> Boolean) {
result.addAll(classDescriptor.enumEntries?.all().orEmpty()) 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<ClassDescriptor> =
nestedClassNames.mapNotNull(this::getClassDescriptor)
}
private inner class EnumEntryClassDescriptors { private inner class EnumEntryClassDescriptors {
private val enumEntryProtos = classProto.enumEntryList.associateBy { c.nameResolver.getName(it.name) } private val enumEntryProtos = classProto.enumEntryList.associateBy { c.nameResolver.getName(it.name) }
@@ -16,11 +16,9 @@
package org.jetbrains.kotlin.serialization.deserialization.descriptors package org.jetbrains.kotlin.serialization.deserialization.descriptors
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.protobuf.MessageLite import org.jetbrains.kotlin.protobuf.MessageLite
import org.jetbrains.kotlin.resolve.MemberComparator import org.jetbrains.kotlin.resolve.MemberComparator
@@ -38,7 +36,8 @@ abstract class DeserializedMemberScope protected constructor(
protected val c: DeserializationContext, protected val c: DeserializationContext,
functionList: Collection<ProtoBuf.Function>, functionList: Collection<ProtoBuf.Function>,
propertyList: Collection<ProtoBuf.Property>, propertyList: Collection<ProtoBuf.Property>,
typeAliasList: Collection<ProtoBuf.TypeAlias> typeAliasList: Collection<ProtoBuf.TypeAlias>,
classNames: () -> Collection<Name>
) : MemberScopeImpl() { ) : MemberScopeImpl() {
private val functionProtos by private val functionProtos by
@@ -73,6 +72,8 @@ abstract class DeserializedMemberScope protected constructor(
private val typeAliasNames: Set<Name> get() = typeAliasProtos.keys private val typeAliasNames: Set<Name> get() = typeAliasProtos.keys
internal val classNames by c.storageManager.createLazyValue { classNames().toSet() }
override fun getFunctionNames() = functionNamesLazy override fun getFunctionNames() = functionNamesLazy
override fun getVariableNames() = variableNamesLazy override fun getVariableNames() = variableNamesLazy
@@ -131,13 +132,6 @@ abstract class DeserializedMemberScope protected constructor(
return properties(name) return properties(name)
} }
protected fun getTypeAlias(name: Name): TypeAliasDescriptor? {
if (name !in typeAliasNames) return null
return typeAliasByName(name)
}
protected abstract fun addClassifierDescriptors(result: MutableCollection<DeclarationDescriptor>, nameFilter: (Name) -> Boolean)
protected fun computeDescriptors( protected fun computeDescriptors(
kindFilter: DescriptorKindFilter, kindFilter: DescriptorKindFilter,
nameFilter: (Name) -> Boolean, nameFilter: (Name) -> Boolean,
@@ -154,13 +148,17 @@ abstract class DeserializedMemberScope protected constructor(
addFunctionsAndProperties(result, kindFilter, nameFilter, location) addFunctionsAndProperties(result, kindFilter, nameFilter, location)
if (kindFilter.acceptsKinds(DescriptorKindFilter.CLASSIFIERS_MASK)) { 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)) { if (kindFilter.acceptsKinds(DescriptorKindFilter.TYPE_ALIASES_MASK)) {
for (typeAliasName in typeAliasNames) { for (typeAliasName in typeAliasNames) {
if (nameFilter(typeAliasName)) { if (nameFilter(typeAliasName)) {
result.addIfNotNull(getTypeAlias(typeAliasName)) result.addIfNotNull(typeAliasByName(typeAliasName))
} }
} }
} }
@@ -208,6 +206,21 @@ abstract class DeserializedMemberScope protected constructor(
result.addAll(subResult) 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<Name> protected abstract fun getNonDeclaredFunctionNames(): Set<Name>
protected abstract fun getNonDeclaredVariableNames(): Set<Name> protected abstract fun getNonDeclaredVariableNames(): Set<Name>
@@ -16,19 +16,17 @@
package org.jetbrains.kotlin.serialization.deserialization.descriptors package org.jetbrains.kotlin.serialization.deserialization.descriptors
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents import org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents
import org.jetbrains.kotlin.serialization.deserialization.NameResolver import org.jetbrains.kotlin.serialization.deserialization.NameResolver
import org.jetbrains.kotlin.serialization.deserialization.TypeTable import org.jetbrains.kotlin.serialization.deserialization.TypeTable
import org.jetbrains.kotlin.storage.getValue
import org.jetbrains.kotlin.utils.addIfNotNull
open class DeserializedPackageMemberScope( open class DeserializedPackageMemberScope(
packageDescriptor: PackageFragmentDescriptor, packageDescriptor: PackageFragmentDescriptor,
@@ -39,33 +37,17 @@ open class DeserializedPackageMemberScope(
classNames: () -> Collection<Name> classNames: () -> Collection<Name>
) : DeserializedMemberScope( ) : DeserializedMemberScope(
components.createContext(packageDescriptor, nameResolver, TypeTable(proto.typeTable), containerSource), 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 private val packageFqName = packageDescriptor.fqName
internal val classNames by c.storageManager.createLazyValue { classNames().toSet() }
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean) override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean)
= computeDescriptors(kindFilter, nameFilter, NoLookupLocation.WHEN_GET_ALL_DESCRIPTORS) = computeDescriptors(kindFilter, nameFilter, NoLookupLocation.WHEN_GET_ALL_DESCRIPTORS)
override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? { override fun hasClass(name: Name) =
if (SpecialNames.isSafeIdentifier(name) && super.hasClass(name) || c.components.fictitiousClassDescriptorFactory.shouldCreateClass(packageFqName, name)
(name in classNames || c.components.fictitiousClassDescriptorFactory.shouldCreateClass(packageFqName, name))) {
return getClassDescriptor(name)
}
return getTypeAlias(name)
}
private fun getClassDescriptor(name: Name): ClassDescriptor? = override fun createClassId(name: Name) = ClassId(packageFqName, name)
c.components.deserializeClass(ClassId(packageFqName, name))
override fun addClassifierDescriptors(result: MutableCollection<DeclarationDescriptor>, nameFilter: (Name) -> Boolean) {
for (className in classNames) {
if (nameFilter(className)) {
result.addIfNotNull(getClassDescriptor(className))
}
}
}
override fun getNonDeclaredFunctionNames(): Set<Name> = emptySet() override fun getNonDeclaredFunctionNames(): Set<Name> = emptySet()
override fun getNonDeclaredVariableNames(): Set<Name> = emptySet() override fun getNonDeclaredVariableNames(): Set<Name> = emptySet()