From 506d7ab3d2016afecc430673edc55d47400f5423 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Thu, 13 Apr 2017 13:11:09 +0300 Subject: [PATCH] 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 --- .../load/java/structure/impl/JavaClassImpl.kt | 8 ++++++-- .../lazy/descriptors/LazyJavaClassMemberScope.kt | 16 ++++++++++------ .../lazy/descriptors/LazyJavaStaticClassScope.kt | 2 +- .../kotlin/load/java/structure/javaElements.kt | 3 ++- .../java/structure/reflect/ReflectJavaClass.kt | 11 ++++++++--- 5 files changed, 27 insertions(+), 13 deletions(-) diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/structure/impl/JavaClassImpl.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/structure/impl/JavaClassImpl.kt index 535331d2137..7461e881c1f 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/structure/impl/JavaClassImpl.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/structure/impl/JavaClassImpl.kt @@ -31,8 +31,12 @@ class JavaClassImpl(psiClass: PsiClass) : JavaClassifierImpl(psiClass) assert(psiClass !is PsiTypeParameter) { "PsiTypeParameter should be wrapped in JavaTypeParameter, not JavaClass: use JavaClassifier.create()" } } - override val innerClasses: Collection - get() = classes(psi.innerClasses) + override val innerClassNames: Collection + 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? get() { diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassMemberScope.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassMemberScope.kt index 6a320382bc0..4b78ac69124 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassMemberScope.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassMemberScope.kt @@ -50,14 +50,17 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.DescriptorFactory import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.OverridingUtil +import org.jetbrains.kotlin.resolve.descriptorUtil.classId import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter import org.jetbrains.kotlin.storage.NotNullLazyValue import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeUtils 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.ifEmpty import java.util.* class LazyJavaClassMemberScope( @@ -613,7 +616,7 @@ class LazyJavaClassMemberScope( } private val nestedClassIndex = c.storageManager.createLazyValue { - jClass.innerClasses.associateBy { c -> c.name } + jClass.innerClassNames.toSet() } private val enumEntryIndex = c.storageManager.createLazyValue { @@ -622,8 +625,7 @@ class LazyJavaClassMemberScope( private val nestedClasses = c.storageManager.createMemoizedFunctionWithNullableValues { name: Name -> - val jNestedClass = nestedClassIndex()[name] - if (jNestedClass == null) { + if (name !in nestedClassIndex()) { val field = enumEntryIndex()[name] if (field != null) { val enumMemberNames: NotNullLazyValue> = c.storageManager.createLazyValue { @@ -637,7 +639,9 @@ class LazyJavaClassMemberScope( else null } 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 - = nestedClassIndex().keys + enumEntryIndex().keys + = nestedClassIndex() + enumEntryIndex().keys override fun computePropertyNames(kindFilter: DescriptorKindFilter, nameFilter: ((Name) -> Boolean)?): Set { if (jClass.isAnnotationType) return getFunctionNames() diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaStaticClassScope.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaStaticClassScope.kt index 4c7aa160c0f..b8d3bc10c29 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaStaticClassScope.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaStaticClassScope.kt @@ -48,7 +48,7 @@ class LazyJavaStaticClassScope( if (jClass.isEnum) { 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)?) = diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/structure/javaElements.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/structure/javaElements.kt index e10a98855c0..b5e2e1d96e1 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/structure/javaElements.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/structure/javaElements.kt @@ -65,7 +65,8 @@ interface JavaClass : JavaClassifier, JavaTypeParameterListOwner, JavaModifierLi val fqName: FqName? val supertypes: Collection - val innerClasses: Collection + val innerClassNames: Collection + fun findInnerClass(name: Name): JavaClass? val outerClass: JavaClass? val isInterface: Boolean diff --git a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaClass.kt b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaClass.kt index a9724a39105..e28e005c46a 100644 --- a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaClass.kt +++ b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaClass.kt @@ -31,7 +31,7 @@ class ReflectJavaClass( override val modifiers: Int get() = klass.modifiers - override val innerClasses: List + override val innerClassNames: List get() = klass.declaredClasses .asSequence() .filterNot { @@ -40,8 +40,13 @@ class ReflectJavaClass( // nested class constructor accessed from the outer class it.simpleName.isEmpty() } - .map(::ReflectJavaClass) - .toList() + .mapNotNull { it.simpleName.takeIf(Name::isValidIdentifier)?.let(Name::identifier) }.toList() + + override fun findInnerClass(name: Name) = klass.declaredClasses + .asSequence() + .firstOrNull { + it.simpleName == name.asString() + }?.let(::ReflectJavaClass) override val fqName: FqName get() = klass.classId.asSingleFqName()