Replace JavaClass.innerClasses with innerClassNames

Also add a findInnerClass method that can find an inner class
by its name

This change helps to avoid loading all the inner class files
eagerly (that may be rather slow), while all the names are available
in InnerClass attribute
This commit is contained in:
Denis Zharkov
2017-04-13 13:11:09 +03:00
parent 5936424659
commit 506d7ab3d2
5 changed files with 27 additions and 13 deletions
@@ -31,8 +31,12 @@ class JavaClassImpl(psiClass: PsiClass) : JavaClassifierImpl<PsiClass>(psiClass)
assert(psiClass !is PsiTypeParameter) { "PsiTypeParameter should be wrapped in JavaTypeParameter, not JavaClass: use JavaClassifier.create()" } assert(psiClass !is PsiTypeParameter) { "PsiTypeParameter should be wrapped in JavaTypeParameter, not JavaClass: use JavaClassifier.create()" }
} }
override val innerClasses: Collection<JavaClass> override val innerClassNames: Collection<Name>
get() = classes(psi.innerClasses) get() = psi.innerClasses.mapNotNull { it.name?.takeIf(Name::isValidIdentifier)?.let(Name::identifier) }
override fun findInnerClass(name: Name): JavaClass? {
return psi.findInnerClassByName(name.asString(), false)?.let(::JavaClassImpl)
}
override val fqName: FqName? override val fqName: FqName?
get() { get() {
@@ -50,14 +50,17 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorFactory import org.jetbrains.kotlin.resolve.DescriptorFactory
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.OverridingUtil import org.jetbrains.kotlin.resolve.OverridingUtil
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter
import org.jetbrains.kotlin.storage.NotNullLazyValue import org.jetbrains.kotlin.storage.NotNullLazyValue
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import org.jetbrains.kotlin.utils.* import org.jetbrains.kotlin.utils.SmartSet
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
import org.jetbrains.kotlin.utils.ifEmpty
import java.util.* import java.util.*
class LazyJavaClassMemberScope( class LazyJavaClassMemberScope(
@@ -613,7 +616,7 @@ class LazyJavaClassMemberScope(
} }
private val nestedClassIndex = c.storageManager.createLazyValue { private val nestedClassIndex = c.storageManager.createLazyValue {
jClass.innerClasses.associateBy { c -> c.name } jClass.innerClassNames.toSet()
} }
private val enumEntryIndex = c.storageManager.createLazyValue { private val enumEntryIndex = c.storageManager.createLazyValue {
@@ -622,8 +625,7 @@ class LazyJavaClassMemberScope(
private val nestedClasses = c.storageManager.createMemoizedFunctionWithNullableValues { private val nestedClasses = c.storageManager.createMemoizedFunctionWithNullableValues {
name: Name -> name: Name ->
val jNestedClass = nestedClassIndex()[name] if (name !in nestedClassIndex()) {
if (jNestedClass == null) {
val field = enumEntryIndex()[name] val field = enumEntryIndex()[name]
if (field != null) { if (field != null) {
val enumMemberNames: NotNullLazyValue<Set<Name>> = c.storageManager.createLazyValue { val enumMemberNames: NotNullLazyValue<Set<Name>> = c.storageManager.createLazyValue {
@@ -637,7 +639,9 @@ class LazyJavaClassMemberScope(
else null else null
} }
else { else {
LazyJavaClassDescriptor(c, ownerDescriptor, jNestedClass) c.components.finder.findClass(ownerDescriptor.classId!!.createNestedClassId(name))?.let {
LazyJavaClassDescriptor(c, ownerDescriptor, it)
}
} }
} }
@@ -660,7 +664,7 @@ class LazyJavaClassMemberScope(
} }
override fun computeClassNames(kindFilter: DescriptorKindFilter, nameFilter: ((Name) -> Boolean)?): Set<Name> override fun computeClassNames(kindFilter: DescriptorKindFilter, nameFilter: ((Name) -> Boolean)?): Set<Name>
= nestedClassIndex().keys + enumEntryIndex().keys = nestedClassIndex() + enumEntryIndex().keys
override fun computePropertyNames(kindFilter: DescriptorKindFilter, nameFilter: ((Name) -> Boolean)?): Set<Name> { override fun computePropertyNames(kindFilter: DescriptorKindFilter, nameFilter: ((Name) -> Boolean)?): Set<Name> {
if (jClass.isAnnotationType) return getFunctionNames() if (jClass.isAnnotationType) return getFunctionNames()
@@ -48,7 +48,7 @@ class LazyJavaStaticClassScope(
if (jClass.isEnum) { if (jClass.isEnum) {
addAll(listOf(DescriptorUtils.ENUM_VALUE_OF, DescriptorUtils.ENUM_VALUES)) addAll(listOf(DescriptorUtils.ENUM_VALUE_OF, DescriptorUtils.ENUM_VALUES))
} }
addAll(jClass.innerClasses.map(JavaClass::name)) addAll(jClass.innerClassNames)
} }
override fun computePropertyNames(kindFilter: DescriptorKindFilter, nameFilter: ((Name) -> Boolean)?) = override fun computePropertyNames(kindFilter: DescriptorKindFilter, nameFilter: ((Name) -> Boolean)?) =
@@ -65,7 +65,8 @@ interface JavaClass : JavaClassifier, JavaTypeParameterListOwner, JavaModifierLi
val fqName: FqName? val fqName: FqName?
val supertypes: Collection<JavaClassifierType> val supertypes: Collection<JavaClassifierType>
val innerClasses: Collection<JavaClass> val innerClassNames: Collection<Name>
fun findInnerClass(name: Name): JavaClass?
val outerClass: JavaClass? val outerClass: JavaClass?
val isInterface: Boolean val isInterface: Boolean
@@ -31,7 +31,7 @@ class ReflectJavaClass(
override val modifiers: Int get() = klass.modifiers override val modifiers: Int get() = klass.modifiers
override val innerClasses: List<ReflectJavaClass> override val innerClassNames: List<Name>
get() = klass.declaredClasses get() = klass.declaredClasses
.asSequence() .asSequence()
.filterNot { .filterNot {
@@ -40,8 +40,13 @@ class ReflectJavaClass(
// nested class constructor accessed from the outer class // nested class constructor accessed from the outer class
it.simpleName.isEmpty() it.simpleName.isEmpty()
} }
.map(::ReflectJavaClass) .mapNotNull { it.simpleName.takeIf(Name::isValidIdentifier)?.let(Name::identifier) }.toList()
.toList()
override fun findInnerClass(name: Name) = klass.declaredClasses
.asSequence()
.firstOrNull {
it.simpleName == name.asString()
}?.let(::ReflectJavaClass)
override val fqName: FqName override val fqName: FqName
get() = klass.classId.asSingleFqName() get() = klass.classId.asSingleFqName()