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<Name, Collection<Descriptor>>

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
This commit is contained in:
Denis Zharkov
2016-09-08 15:40:02 +03:00
parent 8ee5f3de8f
commit b1edb01dd4
9 changed files with 82 additions and 7 deletions
@@ -70,6 +70,13 @@ class JvmPackageScope(
): Collection<DeclarationDescriptor> =
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()
@@ -627,8 +627,8 @@ class LazyJavaClassMemberScope(
if (jNestedClass == null) {
val field = enumEntryIndex()[name]
if (field != null) {
val enumMemberNames: NotNullLazyValue<Collection<Name>> = c.storageManager.createLazyValue {
memberIndex().getAllFieldNames() + memberIndex().getMethodNames({ true })
val enumMemberNames: NotNullLazyValue<Set<Name>> = c.storageManager.createLazyValue {
(memberIndex().getAllFieldNames() + memberIndex().getMethodNames({ true })).toSet()
}
EnumEntrySyntheticClassDescriptor.create(
c.storageManager, ownerDescriptor, name, enumMemberNames, c.resolveAnnotations(field),
@@ -45,7 +45,7 @@ public class EnumEntrySyntheticClassDescriptor extends ClassDescriptorBase {
private final TypeConstructor typeConstructor;
private final ConstructorDescriptor primaryConstructor;
private final MemberScope scope;
private final NotNullLazyValue<Collection<Name>> enumMemberNames;
private final NotNullLazyValue<Set<Name>> 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<Collection<Name>> enumMemberNames,
@NotNull NotNullLazyValue<Set<Name>> 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<Collection<Name>> enumMemberNames,
@NotNull NotNullLazyValue<Set<Name>> enumMemberNames,
@NotNull Annotations annotations,
@NotNull SourceElement source
) {
@@ -288,6 +288,18 @@ public class EnumEntrySyntheticClassDescriptor extends ClassDescriptorBase {
return result;
}
@NotNull
@Override
public Set<Name> getFunctionNames() {
return enumMemberNames.invoke();
}
@NotNull
@Override
public Set<Name> getVariableNames() {
return enumMemberNames.invoke();
}
@Override
public void printScopeStructure(@NotNull Printer p) {
p.println("enum entry scope for " + EnumEntrySyntheticClassDescriptor.this);
@@ -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()
@@ -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) {
@@ -28,6 +28,12 @@ interface MemberScope : ResolutionScope {
override fun getContributedVariables(name: Name, location: LookupLocation): Collection<PropertyDescriptor>
override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<SimpleFunctionDescriptor>
/**
* These methods may return a superset of an actual names' set
*/
fun getFunctionNames(): Set<Name>
fun getVariableNames(): Set<Name>
/**
* 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<Name>()
override fun getVariableNames() = emptySet<Name>()
}
companion object {
@@ -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<DeclarationDescriptor> = emptyList()
override fun getFunctionNames(): Set<Name> =
getContributedDescriptors(
DescriptorKindFilter.FUNCTIONS, alwaysTrue()
).filterIsInstance<SimpleFunctionDescriptor>().mapTo(mutableSetOf()) { it.name }
override fun getVariableNames(): Set<Name> =
getContributedDescriptors(
DescriptorKindFilter.VARIABLES, alwaysTrue()
).filterIsInstance<VariableDescriptor>().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)
}
}
@@ -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()
@@ -206,6 +206,18 @@ public class ErrorUtils {
return Collections.singleton(createErrorFunction(this));
}
@NotNull
@Override
public Set<Name> getFunctionNames() {
return Collections.emptySet();
}
@NotNull
@Override
public Set<Name> getVariableNames() {
return Collections.emptySet();
}
@NotNull
@Override
public Collection<DeclarationDescriptor> getContributedDescriptors(
@@ -262,6 +274,18 @@ public class ErrorUtils {
throw new IllegalStateException();
}
@NotNull
@Override
public Set<Name> getFunctionNames() {
throw new IllegalStateException();
}
@NotNull
@Override
public Set<Name> getVariableNames() {
throw new IllegalStateException();
}
@Override
public String toString() {
return "ThrowingScope{" + debugMessage + '}';