Optimize class lookups in DeserializedPackageMemberScope

Do not try to load classes (and litter in ClassDeserializer#classes cache with
unsuccessful requests) which the deserialized scope knows nothing about. This
is possible because deserialized scopes have the full list of their class names
This commit is contained in:
Alexander Udalov
2016-04-26 16:42:49 +03:00
parent d259b91143
commit 05af72dc7a
5 changed files with 30 additions and 17 deletions
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.serialization.deserialization.ClassDescriptorFactory
import org.jetbrains.kotlin.storage.StorageManager
@@ -63,6 +64,12 @@ class BuiltInFictitiousFunctionClassFactory(
}
}
override fun shouldCreateClass(packageFqName: FqName, name: Name): Boolean {
val string = name.asString()
return (string.startsWith("Function") || string.startsWith("KFunction")) // an optimization
&& parseClassName(string, packageFqName) != null
}
override fun createClass(classId: ClassId): ClassDescriptor? {
if (classId.isLocal || classId.isNestedClass) return null
@@ -18,11 +18,17 @@ package org.jetbrains.kotlin.serialization.deserialization
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
interface ClassDescriptorFactory {
fun shouldCreateClass(packageFqName: FqName, name: Name): Boolean
fun createClass(classId: ClassId): ClassDescriptor?
object EMPTY : ClassDescriptorFactory {
override fun shouldCreateClass(packageFqName: FqName, name: Name): Boolean = false
override fun createClass(classId: ClassId): ClassDescriptor? = null
}
}
@@ -245,8 +245,10 @@ class DeserializedClassDescriptor(
}
}
override fun getClassDescriptor(name: Name): ClassifierDescriptor? =
classDescriptor.enumEntries?.findEnumEntry(name) ?: classDescriptor.nestedClasses?.findNestedClass(name)
override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? {
recordLookup(name, location)
return classDescriptor.enumEntries?.findEnumEntry(name) ?: classDescriptor.nestedClasses?.findNestedClass(name)
}
override fun addClassDescriptors(result: MutableCollection<DeclarationDescriptor>, nameFilter: (Name) -> Boolean) {
result.addAll(classDescriptor.nestedClasses?.all().orEmpty())
@@ -103,13 +103,6 @@ abstract class DeserializedMemberScope protected constructor(
return properties.invoke(name)
}
override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? {
recordLookup(name, location)
return getClassDescriptor(name)
}
protected abstract fun getClassDescriptor(name: Name): ClassifierDescriptor?
protected abstract fun addClassDescriptors(result: MutableCollection<DeclarationDescriptor>, nameFilter: (Name) -> Boolean)
protected fun computeDescriptors(
@@ -185,7 +178,7 @@ abstract class DeserializedMemberScope protected constructor(
p.println("}")
}
private fun recordLookup(name: Name, from: LookupLocation) {
protected fun recordLookup(name: Name, from: LookupLocation) {
c.components.lookupTracker.record(from, c.containingDeclaration, name)
}
}
@@ -16,10 +16,7 @@
package org.jetbrains.kotlin.serialization.deserialization.descriptors
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.ClassId
@@ -51,9 +48,17 @@ open class DeserializedPackageMemberScope(
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean)
= computeDescriptors(kindFilter, nameFilter, NoLookupLocation.WHEN_GET_ALL_DESCRIPTORS)
override fun getClassDescriptor(name: Name): ClassDescriptor? =
if (SpecialNames.isSafeIdentifier(name)) c.components.deserializeClass(ClassId(packageFqName, name))
else null
override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? {
if (SpecialNames.isSafeIdentifier(name) &&
(name in classNames || c.components.fictitiousClassDescriptorFactory.shouldCreateClass(packageFqName, name))) {
recordLookup(name, location)
return getClassDescriptor(name)
}
return null
}
private fun getClassDescriptor(name: Name): ClassDescriptor? =
c.components.deserializeClass(ClassId(packageFqName, name))
override fun addClassDescriptors(result: MutableCollection<DeclarationDescriptor>, nameFilter: (Name) -> Boolean) {
for (className in classNames) {