From b1edb01dd49717415d4326cf34be635d5825a30c Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Thu, 8 Sep 2016 15:40:02 +0300 Subject: [PATCH] Introduce getFunctionNames and getVariableNames into MemberScope Also provide some basic implementation The main purpose of these methods is optimization. Most of the member scopes store mapping from names to descriptors MemoizedFunction> While there are 10 functions in class in average, there are a lot of queries with names of non-existent functions, that leads to many effectively redundant Map nodes in MemoizedFunction and also cause additional computation that is worth to compute at once --- .../java/lazy/descriptors/JvmPackageScope.kt | 7 ++++++ .../descriptors/LazyJavaClassMemberScope.kt | 4 ++-- .../EnumEntrySyntheticClassDescriptor.java | 18 +++++++++++--- .../resolve/scopes/AbstractScopeAdapter.kt | 8 ++++++- .../resolve/scopes/ChainedMemberScope.kt | 3 +++ .../kotlin/resolve/scopes/MemberScope.kt | 9 +++++++ .../kotlin/resolve/scopes/MemberScopeImpl.kt | 13 +++++++++- .../resolve/scopes/SubstitutingScope.kt | 3 +++ .../jetbrains/kotlin/types/ErrorUtils.java | 24 +++++++++++++++++++ 9 files changed, 82 insertions(+), 7 deletions(-) diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/JvmPackageScope.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/JvmPackageScope.kt index 167bbc148f5..c9ef9c1aa81 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/JvmPackageScope.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/JvmPackageScope.kt @@ -70,6 +70,13 @@ class JvmPackageScope( ): Collection = getFromAllScopes(javaScope, kotlinScopes) { it.getContributedDescriptors(kindFilter, nameFilter) } + override fun getFunctionNames() = kotlinScopes.flatMapTo(mutableSetOf()) { it.getFunctionNames() }.apply { + addAll(javaScope.getFunctionNames()) + } + override fun getVariableNames() = kotlinScopes.flatMapTo(mutableSetOf()) { it.getVariableNames() }.apply { + addAll(javaScope.getVariableNames()) + } + override fun printScopeStructure(p: Printer) { p.println(javaClass.simpleName, " {") p.pushIndent() 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 a459c72bf0c..8aaa5f1954f 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 @@ -627,8 +627,8 @@ class LazyJavaClassMemberScope( if (jNestedClass == null) { val field = enumEntryIndex()[name] if (field != null) { - val enumMemberNames: NotNullLazyValue> = c.storageManager.createLazyValue { - memberIndex().getAllFieldNames() + memberIndex().getMethodNames({ true }) + val enumMemberNames: NotNullLazyValue> = c.storageManager.createLazyValue { + (memberIndex().getAllFieldNames() + memberIndex().getMethodNames({ true })).toSet() } EnumEntrySyntheticClassDescriptor.create( c.storageManager, ownerDescriptor, name, enumMemberNames, c.resolveAnnotations(field), diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/EnumEntrySyntheticClassDescriptor.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/EnumEntrySyntheticClassDescriptor.java index b0fc8599266..b9944f8457e 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/EnumEntrySyntheticClassDescriptor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/EnumEntrySyntheticClassDescriptor.java @@ -45,7 +45,7 @@ public class EnumEntrySyntheticClassDescriptor extends ClassDescriptorBase { private final TypeConstructor typeConstructor; private final ConstructorDescriptor primaryConstructor; private final MemberScope scope; - private final NotNullLazyValue> enumMemberNames; + private final NotNullLazyValue> enumMemberNames; private final Annotations annotations; /** @@ -57,7 +57,7 @@ public class EnumEntrySyntheticClassDescriptor extends ClassDescriptorBase { @NotNull StorageManager storageManager, @NotNull ClassDescriptor enumClass, @NotNull Name name, - @NotNull NotNullLazyValue> enumMemberNames, + @NotNull NotNullLazyValue> enumMemberNames, @NotNull Annotations annotations, @NotNull SourceElement source ) { @@ -71,7 +71,7 @@ public class EnumEntrySyntheticClassDescriptor extends ClassDescriptorBase { @NotNull ClassDescriptor containingClass, @NotNull KotlinType supertype, @NotNull Name name, - @NotNull NotNullLazyValue> enumMemberNames, + @NotNull NotNullLazyValue> enumMemberNames, @NotNull Annotations annotations, @NotNull SourceElement source ) { @@ -288,6 +288,18 @@ public class EnumEntrySyntheticClassDescriptor extends ClassDescriptorBase { return result; } + @NotNull + @Override + public Set getFunctionNames() { + return enumMemberNames.invoke(); + } + + @NotNull + @Override + public Set getVariableNames() { + return enumMemberNames.invoke(); + } + @Override public void printScopeStructure(@NotNull Printer p) { p.println("enum entry scope for " + EnumEntrySyntheticClassDescriptor.this); diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/AbstractScopeAdapter.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/AbstractScopeAdapter.kt index bc4b0eb84aa..076750b7a7a 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/AbstractScopeAdapter.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/AbstractScopeAdapter.kt @@ -16,7 +16,10 @@ package org.jetbrains.kotlin.resolve.scopes -import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.ClassifierDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.PropertyDescriptor +import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.utils.Printer @@ -50,6 +53,9 @@ abstract class AbstractScopeAdapter : MemberScope { return workerScope.getContributedDescriptors(kindFilter, nameFilter) } + override fun getFunctionNames() = workerScope.getFunctionNames() + override fun getVariableNames() = workerScope.getVariableNames() + override fun printScopeStructure(p: Printer) { p.println(javaClass.simpleName, " {") p.pushIndent() diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/ChainedMemberScope.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/ChainedMemberScope.kt index 7e6f21dcedd..74bc02ae28a 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/ChainedMemberScope.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/ChainedMemberScope.kt @@ -41,6 +41,9 @@ class ChainedMemberScope( override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean) = getFromAllScopes(scopes) { it.getContributedDescriptors(kindFilter, nameFilter) } + override fun getFunctionNames() = scopes.flatMapTo(mutableSetOf()) { it.getFunctionNames() } + override fun getVariableNames() = scopes.flatMapTo(mutableSetOf()) { it.getVariableNames() } + override fun toString() = debugName override fun printScopeStructure(p: Printer) { diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/MemberScope.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/MemberScope.kt index 174e639fcf6..f48968b8d7a 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/MemberScope.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/MemberScope.kt @@ -28,6 +28,12 @@ interface MemberScope : ResolutionScope { override fun getContributedVariables(name: Name, location: LookupLocation): Collection override fun getContributedFunctions(name: Name, location: LookupLocation): Collection + /** + * These methods may return a superset of an actual names' set + */ + fun getFunctionNames(): Set + fun getVariableNames(): Set + /** * Is supposed to be used in tests and debug only */ @@ -37,6 +43,9 @@ interface MemberScope : ResolutionScope { override fun printScopeStructure(p: Printer) { p.println("Empty member scope") } + + override fun getFunctionNames() = emptySet() + override fun getVariableNames() = emptySet() } companion object { diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/MemberScopeImpl.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/MemberScopeImpl.kt index c2cb4db8f62..f54f05fea1b 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/MemberScopeImpl.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/MemberScopeImpl.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.utils.Printer +import org.jetbrains.kotlin.utils.alwaysTrue abstract class MemberScopeImpl : MemberScope { override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? = null @@ -31,6 +32,16 @@ abstract class MemberScopeImpl : MemberScope { override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection = emptyList() + override fun getFunctionNames(): Set = + getContributedDescriptors( + DescriptorKindFilter.FUNCTIONS, alwaysTrue() + ).filterIsInstance().mapTo(mutableSetOf()) { it.name } + + override fun getVariableNames(): Set = + getContributedDescriptors( + DescriptorKindFilter.VARIABLES, alwaysTrue() + ).filterIsInstance().mapTo(mutableSetOf()) { it.name } + // This method should not be implemented here by default: every scope class has its unique structure pattern abstract override fun printScopeStructure(p: Printer) -} \ No newline at end of file +} diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/SubstitutingScope.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/SubstitutingScope.kt index 289a0e2e9d5..7f290b61668 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/SubstitutingScope.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/SubstitutingScope.kt @@ -75,6 +75,9 @@ class SubstitutingScope(private val workerScope: MemberScope, givenSubstitutor: override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean) = _allDescriptors + override fun getFunctionNames() = workerScope.getFunctionNames() + override fun getVariableNames() = workerScope.getVariableNames() + override fun printScopeStructure(p: Printer) { p.println(javaClass.simpleName, " {") p.pushIndent() diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java b/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java index fe32885a0aa..50cb466ad7c 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java +++ b/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java @@ -206,6 +206,18 @@ public class ErrorUtils { return Collections.singleton(createErrorFunction(this)); } + @NotNull + @Override + public Set getFunctionNames() { + return Collections.emptySet(); + } + + @NotNull + @Override + public Set getVariableNames() { + return Collections.emptySet(); + } + @NotNull @Override public Collection getContributedDescriptors( @@ -262,6 +274,18 @@ public class ErrorUtils { throw new IllegalStateException(); } + @NotNull + @Override + public Set getFunctionNames() { + throw new IllegalStateException(); + } + + @NotNull + @Override + public Set getVariableNames() { + throw new IllegalStateException(); + } + @Override public String toString() { return "ThrowingScope{" + debugMessage + '}';