Optimize resolution scope queries from the synthetic scopes

now required descriptors are queried in advance and passed to the
methods, to avoid multiple same name queries in a row
This commit is contained in:
Ilya Chernikov
2020-06-08 16:45:30 +02:00
parent a0efd1e323
commit 484d026d2f
6 changed files with 63 additions and 57 deletions
@@ -38,7 +38,6 @@ import org.jetbrains.kotlin.resolve.calls.inference.wrapWithCapturingSubstitutio
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
import org.jetbrains.kotlin.resolve.sam.* import org.jetbrains.kotlin.resolve.sam.*
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.ResolutionScope
import org.jetbrains.kotlin.resolve.scopes.SyntheticScope import org.jetbrains.kotlin.resolve.scopes.SyntheticScope
import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
@@ -168,19 +167,24 @@ class SamAdapterFunctionsScope(
} }
} }
override fun getSyntheticStaticFunctions(scope: ResolutionScope, name: Name, location: LookupLocation): Collection<FunctionDescriptor> { override fun getSyntheticStaticFunctions(
contributedFunctions: Collection<FunctionDescriptor>,
location: LookupLocation
): Collection<FunctionDescriptor> {
if (!shouldGenerateAdditionalSamCandidate) return emptyList() if (!shouldGenerateAdditionalSamCandidate) return emptyList()
return getSamFunctions(scope.getContributedFunctions(name, location), location) return getSamFunctions(contributedFunctions, location)
} }
override fun getSyntheticConstructors(scope: ResolutionScope, name: Name, location: LookupLocation): Collection<FunctionDescriptor> { override fun getSyntheticConstructors(
val classifier = scope.getContributedClassifier(name, location) ?: return emptyList() contributedClassifier: ClassifierDescriptor,
recordSamLookupsToClassifier(classifier, location) location: LookupLocation
): Collection<FunctionDescriptor> {
recordSamLookupsToClassifier(contributedClassifier, location)
if (!shouldGenerateAdditionalSamCandidate) return listOfNotNull(getSamConstructor(classifier)) if (!shouldGenerateAdditionalSamCandidate) return listOfNotNull(getSamConstructor(contributedClassifier))
return getAllSamConstructors(classifier) return getAllSamConstructors(contributedClassifier)
} }
private fun recordSamLookupsToClassifier(classifier: ClassifierDescriptor, location: LookupLocation) { private fun recordSamLookupsToClassifier(classifier: ClassifierDescriptor, location: LookupLocation) {
@@ -191,14 +195,14 @@ class SamAdapterFunctionsScope(
lookupTracker.record(location, classifier, SAM_LOOKUP_NAME) lookupTracker.record(location, classifier, SAM_LOOKUP_NAME)
} }
override fun getSyntheticStaticFunctions(scope: ResolutionScope): Collection<FunctionDescriptor> { override fun getSyntheticStaticFunctions(functionDescriptors: Collection<DeclarationDescriptor>): Collection<FunctionDescriptor> {
if (!shouldGenerateAdditionalSamCandidate) return emptyList() if (!shouldGenerateAdditionalSamCandidate) return emptyList()
return getSamFunctions(scope.getContributedDescriptors(DescriptorKindFilter.FUNCTIONS), location = null) return getSamFunctions(functionDescriptors, location = null)
} }
override fun getSyntheticConstructors(scope: ResolutionScope): Collection<FunctionDescriptor> { override fun getSyntheticConstructors(classifierDescriptors: Collection<DeclarationDescriptor>): Collection<FunctionDescriptor> {
val classifiers = scope.getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS).filterIsInstance<ClassifierDescriptor>() val classifiers = classifierDescriptors.filterIsInstance<ClassifierDescriptor>()
if (!shouldGenerateAdditionalSamCandidate) return classifiers.mapNotNull { getSamConstructor(it) } if (!shouldGenerateAdditionalSamCandidate) return classifiers.mapNotNull { getSamConstructor(it) }
@@ -23,7 +23,10 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.getReceiverValueWithSmartCa
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForTypeAliasObject import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForTypeAliasObject
import org.jetbrains.kotlin.resolve.calls.util.isLowPriorityFromStdlibJre7Or8 import org.jetbrains.kotlin.resolve.calls.util.isLowPriorityFromStdlibJre7Or8
import org.jetbrains.kotlin.resolve.descriptorUtil.* import org.jetbrains.kotlin.resolve.descriptorUtil.HIDES_MEMBERS_NAME_LIST
import org.jetbrains.kotlin.resolve.descriptorUtil.hasClassValueDescriptor
import org.jetbrains.kotlin.resolve.descriptorUtil.hasHidesMembersAnnotation
import org.jetbrains.kotlin.resolve.descriptorUtil.hasLowPriorityInOverloadResolution
import org.jetbrains.kotlin.resolve.scopes.* import org.jetbrains.kotlin.resolve.scopes.*
import org.jetbrains.kotlin.resolve.scopes.receivers.CastImplicitClassReceiver import org.jetbrains.kotlin.resolve.scopes.receivers.CastImplicitClassReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver
@@ -36,7 +39,6 @@ import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.typeUtil.getImmediateSuperclassNotAny import org.jetbrains.kotlin.types.typeUtil.getImmediateSuperclassNotAny
import org.jetbrains.kotlin.utils.SmartList import org.jetbrains.kotlin.utils.SmartList
import org.jetbrains.kotlin.utils.addIfNotNull import org.jetbrains.kotlin.utils.addIfNotNull
import kotlin.collections.ArrayList
internal abstract class AbstractScopeTowerLevel( internal abstract class AbstractScopeTowerLevel(
protected val scopeTower: ImplicitScopeTower protected val scopeTower: ImplicitScopeTower
@@ -382,14 +384,18 @@ private fun ResolutionScope.getContributedFunctionsAndConstructors(
extensionReceiver: ReceiverValueWithSmartCastInfo?, extensionReceiver: ReceiverValueWithSmartCastInfo?,
scopeTower: ImplicitScopeTower scopeTower: ImplicitScopeTower
): Collection<FunctionDescriptor> { ): Collection<FunctionDescriptor> {
val result = ArrayList<FunctionDescriptor>(getContributedFunctions(name, location)) val contributedFunctions = getContributedFunctions(name, location)
val result = ArrayList<FunctionDescriptor>(contributedFunctions)
getContributedClassifier(name, location)?.let { getContributedClassifier(name, location)?.let {
result.addAll(getConstructorsOfClassifier(it)) result.addAll(getConstructorsOfClassifier(it))
result.addAll(scopeTower.syntheticScopes.collectSyntheticConstructors(it, location))
} }
result.addAll(scopeTower.syntheticScopes.collectSyntheticStaticFunctions(this, name, location)) if (contributedFunctions.isNotEmpty()) {
result.addAll(scopeTower.syntheticScopes.collectSyntheticConstructors(this, name, location)) result.addAll(scopeTower.syntheticScopes.collectSyntheticStaticFunctions(contributedFunctions, location))
}
return scopeTower.interceptFunctionCandidates(this, name, result, location, dispatchReceiver, extensionReceiver) return scopeTower.interceptFunctionCandidates(this, name, result, location, dispatchReceiver, extensionReceiver)
} }
@@ -17,9 +17,7 @@
package org.jetbrains.kotlin.resolve.scopes package org.jetbrains.kotlin.resolve.scopes
import org.jetbrains.kotlin.container.DefaultImplementation import org.jetbrains.kotlin.container.DefaultImplementation
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.scopes.synthetic.FunInterfaceConstructorsScopeProvider import org.jetbrains.kotlin.resolve.scopes.synthetic.FunInterfaceConstructorsScopeProvider
@@ -27,19 +25,21 @@ import org.jetbrains.kotlin.types.KotlinType
interface SyntheticScope { interface SyntheticScope {
fun getSyntheticExtensionProperties(receiverTypes: Collection<KotlinType>, name: Name, location: LookupLocation): Collection<PropertyDescriptor> fun getSyntheticExtensionProperties(receiverTypes: Collection<KotlinType>, name: Name, location: LookupLocation): Collection<PropertyDescriptor>
fun getSyntheticMemberFunctions(receiverTypes: Collection<KotlinType>, name: Name, location: LookupLocation): Collection<FunctionDescriptor> fun getSyntheticMemberFunctions(receiverTypes: Collection<KotlinType>, name: Name, location: LookupLocation): Collection<FunctionDescriptor>
fun getSyntheticStaticFunctions(scope: ResolutionScope, name: Name, location: LookupLocation): Collection<FunctionDescriptor> fun getSyntheticStaticFunctions(contributedFunctions: Collection<FunctionDescriptor>, location: LookupLocation): Collection<FunctionDescriptor>
fun getSyntheticConstructors(scope: ResolutionScope, name: Name, location: LookupLocation): Collection<FunctionDescriptor> fun getSyntheticConstructors(contributedClassifier: ClassifierDescriptor, location: LookupLocation): Collection<FunctionDescriptor>
fun getSyntheticExtensionProperties(receiverTypes: Collection<KotlinType>, location: LookupLocation): Collection<PropertyDescriptor> fun getSyntheticExtensionProperties(receiverTypes: Collection<KotlinType>, location: LookupLocation): Collection<PropertyDescriptor>
fun getSyntheticMemberFunctions(receiverTypes: Collection<KotlinType>): Collection<FunctionDescriptor> fun getSyntheticMemberFunctions(receiverTypes: Collection<KotlinType>): Collection<FunctionDescriptor>
fun getSyntheticStaticFunctions(scope: ResolutionScope): Collection<FunctionDescriptor> fun getSyntheticStaticFunctions(functionDescriptors: Collection<DeclarationDescriptor>): Collection<FunctionDescriptor>
fun getSyntheticConstructors(scope: ResolutionScope): Collection<FunctionDescriptor> fun getSyntheticConstructors(classifierDescriptors: Collection<DeclarationDescriptor>): Collection<FunctionDescriptor>
fun getSyntheticConstructor(constructor: ConstructorDescriptor): ConstructorDescriptor? fun getSyntheticConstructor(constructor: ConstructorDescriptor): ConstructorDescriptor?
open class Default : SyntheticScope { open class Default : SyntheticScope {
override fun getSyntheticExtensionProperties( override fun getSyntheticExtensionProperties(
receiverTypes: Collection<KotlinType>, receiverTypes: Collection<KotlinType>,
name: Name, name: Name,
@@ -57,16 +57,14 @@ interface SyntheticScope {
} }
override fun getSyntheticStaticFunctions( override fun getSyntheticStaticFunctions(
scope: ResolutionScope, contributedFunctions: Collection<FunctionDescriptor>,
name: Name,
location: LookupLocation location: LookupLocation
): Collection<FunctionDescriptor> { ): Collection<FunctionDescriptor> {
return emptyList() return emptyList()
} }
override fun getSyntheticConstructors( override fun getSyntheticConstructors(
scope: ResolutionScope, contributedClassifier: ClassifierDescriptor,
name: Name,
location: LookupLocation location: LookupLocation
): Collection<FunctionDescriptor> { ): Collection<FunctionDescriptor> {
return emptyList() return emptyList()
@@ -83,11 +81,11 @@ interface SyntheticScope {
return emptyList() return emptyList()
} }
override fun getSyntheticStaticFunctions(scope: ResolutionScope): Collection<FunctionDescriptor> { override fun getSyntheticStaticFunctions(functionDescriptors: Collection<DeclarationDescriptor>): Collection<FunctionDescriptor> {
return emptyList() return emptyList()
} }
override fun getSyntheticConstructors(scope: ResolutionScope): Collection<FunctionDescriptor> { override fun getSyntheticConstructors(classifierDescriptors: Collection<DeclarationDescriptor>): Collection<FunctionDescriptor> {
return emptyList() return emptyList()
} }
@@ -106,18 +104,17 @@ interface SyntheticScopes {
} }
} }
fun SyntheticScopes.collectSyntheticExtensionProperties(receiverTypes: Collection<KotlinType>, name: Name, location: LookupLocation) fun SyntheticScopes.collectSyntheticExtensionProperties(receiverTypes: Collection<KotlinType>, name: Name, location: LookupLocation)
= scopes.flatMap { it.getSyntheticExtensionProperties(receiverTypes, name, location) } = scopes.flatMap { it.getSyntheticExtensionProperties(receiverTypes, name, location) }
fun SyntheticScopes.collectSyntheticMemberFunctions(receiverTypes: Collection<KotlinType>, name: Name, location: LookupLocation) fun SyntheticScopes.collectSyntheticMemberFunctions(receiverTypes: Collection<KotlinType>, name: Name, location: LookupLocation)
= scopes.flatMap { it.getSyntheticMemberFunctions(receiverTypes, name, location) } = scopes.flatMap { it.getSyntheticMemberFunctions(receiverTypes, name, location) }
fun SyntheticScopes.collectSyntheticStaticFunctions(scope: ResolutionScope, name: Name, location: LookupLocation) fun SyntheticScopes.collectSyntheticStaticFunctions(contributedFunctions: Collection<FunctionDescriptor>, location: LookupLocation)
= scopes.flatMap { it.getSyntheticStaticFunctions(scope, name, location) } = scopes.flatMap { it.getSyntheticStaticFunctions(contributedFunctions, location,) }
fun SyntheticScopes.collectSyntheticConstructors(scope: ResolutionScope, name: Name, location: LookupLocation) fun SyntheticScopes.collectSyntheticConstructors(contributedClassifier: ClassifierDescriptor, location: LookupLocation)
= scopes.flatMap { it.getSyntheticConstructors(scope, name, location) } = scopes.flatMap { it.getSyntheticConstructors(contributedClassifier, location) }
fun SyntheticScopes.collectSyntheticExtensionProperties(receiverTypes: Collection<KotlinType>, location: LookupLocation) fun SyntheticScopes.collectSyntheticExtensionProperties(receiverTypes: Collection<KotlinType>, location: LookupLocation)
= scopes.flatMap { it.getSyntheticExtensionProperties(receiverTypes, location) } = scopes.flatMap { it.getSyntheticExtensionProperties(receiverTypes, location) }
@@ -125,11 +122,11 @@ fun SyntheticScopes.collectSyntheticExtensionProperties(receiverTypes: Collectio
fun SyntheticScopes.collectSyntheticMemberFunctions(receiverTypes: Collection<KotlinType>) fun SyntheticScopes.collectSyntheticMemberFunctions(receiverTypes: Collection<KotlinType>)
= scopes.flatMap { it.getSyntheticMemberFunctions(receiverTypes) } = scopes.flatMap { it.getSyntheticMemberFunctions(receiverTypes) }
fun SyntheticScopes.collectSyntheticStaticFunctions(scope: ResolutionScope) fun SyntheticScopes.collectSyntheticStaticFunctions(functionDescriptors: Collection<DeclarationDescriptor>)
= scopes.flatMap { it.getSyntheticStaticFunctions(scope) } = scopes.flatMap { it.getSyntheticStaticFunctions(functionDescriptors) }
fun SyntheticScopes.collectSyntheticConstructors(scope: ResolutionScope) fun SyntheticScopes.collectSyntheticConstructors(classifierDescriptors: Collection<DeclarationDescriptor>)
= scopes.flatMap { it.getSyntheticConstructors(scope) } = scopes.flatMap { it.getSyntheticConstructors(classifierDescriptors) }
fun SyntheticScopes.collectSyntheticConstructors(constructor: ConstructorDescriptor) fun SyntheticScopes.collectSyntheticConstructors(constructor: ConstructorDescriptor)
= scopes.mapNotNull { it.getSyntheticConstructor(constructor) } = scopes.mapNotNull { it.getSyntheticConstructor(constructor) }
@@ -5,17 +5,11 @@
package org.jetbrains.kotlin.resolve.scopes.synthetic package org.jetbrains.kotlin.resolve.scopes.synthetic
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.incremental.record import org.jetbrains.kotlin.incremental.record
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.sam.* import org.jetbrains.kotlin.resolve.sam.*
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.ResolutionScope
import org.jetbrains.kotlin.resolve.scopes.SyntheticScope import org.jetbrains.kotlin.resolve.scopes.SyntheticScope
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.StorageManager
@@ -44,16 +38,17 @@ class FunInterfaceConstructorsSyntheticScope(
createSamConstructorFunction(classifier.containingDeclaration, classifier, samResolver, samConversionOracle) createSamConstructorFunction(classifier.containingDeclaration, classifier, samResolver, samConversionOracle)
} }
override fun getSyntheticConstructors(scope: ResolutionScope, name: Name, location: LookupLocation): Collection<FunctionDescriptor> { override fun getSyntheticConstructors(
val classifier = scope.getContributedClassifier(name, location) ?: return emptyList() contributedClassifier: ClassifierDescriptor,
recordSamLookupsToClassifier(classifier, location) location: LookupLocation
): Collection<FunctionDescriptor> {
recordSamLookupsToClassifier(contributedClassifier, location)
return listOfNotNull(getSamConstructor(classifier)) return listOfNotNull(getSamConstructor(contributedClassifier))
} }
override fun getSyntheticConstructors(scope: ResolutionScope): Collection<FunctionDescriptor> = override fun getSyntheticConstructors(classifierDescriptors: Collection<DeclarationDescriptor>): Collection<FunctionDescriptor> =
scope.getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS) classifierDescriptors.filterIsInstanceMapNotNull<ClassifierDescriptor, FunctionDescriptor> { getSamConstructor(it) }
.filterIsInstanceMapNotNull<ClassifierDescriptor, FunctionDescriptor> { getSamConstructor(it) }
private fun getSamConstructor(classifier: ClassifierDescriptor): SamConstructorDescriptor? { private fun getSamConstructor(classifier: ClassifierDescriptor): SamConstructorDescriptor? {
if (classifier is TypeAliasDescriptor) { if (classifier is TypeAliasDescriptor) {
@@ -469,9 +469,11 @@ fun ResolutionScope.collectSyntheticStaticMembersAndConstructors(
nameFilter: (Name) -> Boolean nameFilter: (Name) -> Boolean
): List<FunctionDescriptor> { ): List<FunctionDescriptor> {
val syntheticScopes = resolutionFacade.getFrontendService(SyntheticScopes::class.java) val syntheticScopes = resolutionFacade.getFrontendService(SyntheticScopes::class.java)
return (syntheticScopes.forceEnableSamAdapters().collectSyntheticStaticFunctions(this) + syntheticScopes.collectSyntheticConstructors( val functionDescriptors = getContributedDescriptors(DescriptorKindFilter.FUNCTIONS)
this val classifierDescriptors = getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS)
)).filter { kindFilter.accepts(it) && nameFilter(it.name) } return (syntheticScopes.forceEnableSamAdapters().collectSyntheticStaticFunctions(functionDescriptors) +
syntheticScopes.collectSyntheticConstructors(classifierDescriptors))
.filter { kindFilter.accepts(it) && nameFilter(it.name) }
} }
// New Inference disables scope with synthetic SAM-adapters because it uses conversions for resolution // New Inference disables scope with synthetic SAM-adapters because it uses conversions for resolution
@@ -471,7 +471,9 @@ class KotlinIndicesHelper(
// SAM-adapter // SAM-adapter
val syntheticScopes = resolutionFacade.getFrontendService(SyntheticScopes::class.java).forceEnableSamAdapters() val syntheticScopes = resolutionFacade.getFrontendService(SyntheticScopes::class.java).forceEnableSamAdapters()
syntheticScopes.collectSyntheticStaticFunctions(container.staticScope, descriptor.name, NoLookupLocation.FROM_IDE) val contributedFunctions = container.staticScope.getContributedFunctions(descriptor.name, NoLookupLocation.FROM_IDE)
syntheticScopes.collectSyntheticStaticFunctions(contributedFunctions, NoLookupLocation.FROM_IDE)
.filterIsInstance<SamAdapterDescriptor<*>>() .filterIsInstance<SamAdapterDescriptor<*>>()
.firstOrNull { it.baseDescriptorForSynthetic.original == descriptor.original } .firstOrNull { it.baseDescriptorForSynthetic.original == descriptor.original }
?.let { processor(it) } ?.let { processor(it) }