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,
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<DeclarationDescriptor>, nameFilter: (Name) -> Boolean) {
result.addAll(classDescriptor.nestedClasses?.all().orEmpty())
}
override fun createClassId(name: Name) = classId.createNestedClassId(name)
override fun addEnumEntryDescriptors(result: MutableCollection<DeclarationDescriptor>, 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<ClassDescriptor> =
nestedClassNames.mapNotNull(this::getClassDescriptor)
}
private inner class EnumEntryClassDescriptors {
private val enumEntryProtos = classProto.enumEntryList.associateBy { c.nameResolver.getName(it.name) }
@@ -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<ProtoBuf.Function>,
propertyList: Collection<ProtoBuf.Property>,
typeAliasList: Collection<ProtoBuf.TypeAlias>
typeAliasList: Collection<ProtoBuf.TypeAlias>,
classNames: () -> Collection<Name>
) : MemberScopeImpl() {
private val functionProtos by
@@ -73,6 +72,8 @@ abstract class DeserializedMemberScope protected constructor(
private val typeAliasNames: Set<Name> 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<DeclarationDescriptor>, 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<Name>
protected abstract fun getNonDeclaredVariableNames(): Set<Name>
@@ -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<Name>
) : 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<DeclarationDescriptor>, 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<Name> = emptySet()
override fun getNonDeclaredVariableNames(): Set<Name> = emptySet()