Optimize data handling inside scopes
This commit is contained in:
+8
-6
@@ -44,6 +44,7 @@ import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.checker.findCorrespondingSupertype
|
||||
import org.jetbrains.kotlin.types.typeUtil.isNothing
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
interface SamAdapterExtensionFunctionDescriptor : FunctionDescriptor, FunctionInterfaceAdapterExtensionFunctionDescriptor {
|
||||
@@ -244,14 +245,15 @@ class SamAdapterFunctionsScope(
|
||||
}
|
||||
}
|
||||
|
||||
private fun getAllSamConstructors(classifier: ClassifierDescriptor): List<FunctionDescriptor> {
|
||||
return getSamAdaptersFromConstructors(classifier) + listOfNotNull(getSamConstructor(classifier))
|
||||
}
|
||||
private fun getAllSamConstructors(classifier: ClassifierDescriptor): List<FunctionDescriptor> =
|
||||
getSamAdaptersFromConstructors(classifier).also {
|
||||
it.addIfNotNull(getSamConstructor(classifier))
|
||||
}
|
||||
|
||||
private fun getSamAdaptersFromConstructors(classifier: ClassifierDescriptor): List<FunctionDescriptor> {
|
||||
if (!shouldGenerateAdditionalSamCandidate || classifier !is JavaClassDescriptor) return emptyList()
|
||||
private fun getSamAdaptersFromConstructors(classifier: ClassifierDescriptor): MutableList<FunctionDescriptor> {
|
||||
if (!shouldGenerateAdditionalSamCandidate || classifier !is JavaClassDescriptor) return SmartList()
|
||||
|
||||
return arrayListOf<FunctionDescriptor>().apply {
|
||||
return SmartList<FunctionDescriptor>().apply {
|
||||
for (constructor in classifier.constructors) {
|
||||
val samConstructor = getSyntheticConstructor(constructor) ?: continue
|
||||
add(samConstructor)
|
||||
|
||||
@@ -24,6 +24,8 @@ import org.jetbrains.kotlin.resolve.scopes.BaseImportingScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.computeAllNames
|
||||
import org.jetbrains.kotlin.util.collectionUtils.flatMapScopes
|
||||
import org.jetbrains.kotlin.util.collectionUtils.listOfNonEmptyScopes
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.flatMapToNullable
|
||||
|
||||
@@ -32,13 +34,13 @@ class AllUnderImportScope(
|
||||
excludedImportNames: Collection<FqName>
|
||||
) : BaseImportingScope(null) {
|
||||
|
||||
private val scopes: List<MemberScope> = if (descriptor is ClassDescriptor) {
|
||||
listOf(descriptor.staticScope, descriptor.unsubstitutedInnerClassesScope)
|
||||
private val scopes: Array<MemberScope> = if (descriptor is ClassDescriptor) {
|
||||
listOfNonEmptyScopes(descriptor.staticScope, descriptor.unsubstitutedInnerClassesScope).toTypedArray()
|
||||
} else {
|
||||
assert(descriptor is PackageViewDescriptor) {
|
||||
"Must be class or package view descriptor: $descriptor"
|
||||
}
|
||||
listOf((descriptor as PackageViewDescriptor).memberScope)
|
||||
listOfNonEmptyScopes((descriptor as PackageViewDescriptor).memberScope).toTypedArray()
|
||||
}
|
||||
|
||||
private val excludedNames: Set<Name> = if (excludedImportNames.isEmpty()) { // optimization
|
||||
@@ -49,7 +51,11 @@ class AllUnderImportScope(
|
||||
excludedImportNames.mapNotNull { if (it.parent() == fqName) it.shortName() else null }.toSet()
|
||||
}
|
||||
|
||||
override fun computeImportedNames(): Set<Name>? = scopes.flatMapToNullable(hashSetOf(), MemberScope::computeAllNames)
|
||||
override fun computeImportedNames(): Set<Name>? = when (scopes.size) {
|
||||
0 -> null
|
||||
1 -> scopes[0].computeAllNames()
|
||||
else -> scopes.asIterable().flatMapToNullable(hashSetOf(), MemberScope::computeAllNames)
|
||||
}
|
||||
|
||||
override fun getContributedDescriptors(
|
||||
kindFilter: DescriptorKindFilter,
|
||||
@@ -64,23 +70,29 @@ class AllUnderImportScope(
|
||||
|
||||
val noPackagesKindFilter = kindFilter.withoutKinds(DescriptorKindFilter.PACKAGES_MASK)
|
||||
return scopes
|
||||
.flatMap { it.getContributedDescriptors(noPackagesKindFilter, nameFilterToUse) }
|
||||
.flatMapScopes { it.getContributedDescriptors(noPackagesKindFilter, nameFilterToUse) }
|
||||
.filter { it !is PackageViewDescriptor } // subpackages are not imported
|
||||
}
|
||||
|
||||
override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? {
|
||||
if (name in excludedNames) return null
|
||||
return scopes.asSequence().mapNotNull { it.getContributedClassifier(name, location) }.singleOrNull()
|
||||
var single: ClassifierDescriptor? = null
|
||||
for (scope in scopes) {
|
||||
val res = scope.getContributedClassifier(name, location) ?: continue
|
||||
if (single == null) single = res
|
||||
else return null
|
||||
}
|
||||
return single
|
||||
}
|
||||
|
||||
override fun getContributedVariables(name: Name, location: LookupLocation): List<VariableDescriptor> {
|
||||
override fun getContributedVariables(name: Name, location: LookupLocation): Collection<VariableDescriptor> {
|
||||
if (name in excludedNames) return emptyList()
|
||||
return scopes.flatMap { it.getContributedVariables(name, location) }
|
||||
return scopes.flatMapScopes { it.getContributedVariables(name, location) }
|
||||
}
|
||||
|
||||
override fun getContributedFunctions(name: Name, location: LookupLocation): List<FunctionDescriptor> {
|
||||
override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<FunctionDescriptor> {
|
||||
if (name in excludedNames) return emptyList()
|
||||
return scopes.flatMap { it.getContributedFunctions(name, location) }
|
||||
return scopes.flatMapScopes { it.getContributedFunctions(name, location) }
|
||||
}
|
||||
|
||||
override fun recordLookup(name: Name, location: LookupLocation) {
|
||||
@@ -92,3 +104,4 @@ class AllUnderImportScope(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ import org.jetbrains.kotlin.psi.KtImportDirective
|
||||
import org.jetbrains.kotlin.psi.KtImportInfo
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.ImportPath
|
||||
import org.jetbrains.kotlin.resolve.*
|
||||
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
||||
import org.jetbrains.kotlin.resolve.TemporaryBindingTrace
|
||||
import org.jetbrains.kotlin.resolve.extensions.ExtraImportsProviderExtension
|
||||
import org.jetbrains.kotlin.resolve.scopes.*
|
||||
@@ -85,20 +85,20 @@ class FileScopeFactory(
|
||||
}
|
||||
|
||||
val explicit = createDefaultImportResolver(
|
||||
ExplicitImportsIndexed(defaultImportsFiltered),
|
||||
makeExplicitImportsIndexed(defaultImportsFiltered, components.storageManager),
|
||||
tempTrace,
|
||||
packageFragment = null,
|
||||
aliasImportNames = aliasImportNames
|
||||
)
|
||||
val allUnder = createDefaultImportResolver(
|
||||
AllUnderImportsIndexed(defaultImportsFiltered),
|
||||
makeAllUnderImportsIndexed(defaultImportsFiltered),
|
||||
tempTrace,
|
||||
packageFragment = null,
|
||||
aliasImportNames = aliasImportNames,
|
||||
excludedImports = analyzerServices.excludedImports
|
||||
)
|
||||
val lowPriority = createDefaultImportResolver(
|
||||
AllUnderImportsIndexed(defaultLowPriorityImports.also { imports ->
|
||||
makeAllUnderImportsIndexed(defaultLowPriorityImports.also { imports ->
|
||||
assert(imports.all { it.isAllUnder }) { "All low priority imports must be all-under: $imports" }
|
||||
}),
|
||||
tempTrace,
|
||||
@@ -142,9 +142,13 @@ class FileScopeFactory(
|
||||
val imports = file.importDirectives
|
||||
val aliasImportNames = imports.mapNotNull { if (it.aliasName != null) it.importedFqName else null }
|
||||
|
||||
val explicitImportResolver = createImportResolver(ExplicitImportsIndexed(imports), bindingTrace, aliasImportNames, packageFragment)
|
||||
val explicitImportResolver =
|
||||
createImportResolver(
|
||||
makeExplicitImportsIndexed(imports, components.storageManager),
|
||||
bindingTrace, aliasImportNames, packageFragment
|
||||
)
|
||||
val allUnderImportResolver = createImportResolver(
|
||||
AllUnderImportsIndexed(imports),
|
||||
makeAllUnderImportsIndexed(imports),
|
||||
bindingTrace,
|
||||
aliasImportNames,
|
||||
packageFragment
|
||||
|
||||
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.resolve.scopes.ImportingScope
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import org.jetbrains.kotlin.storage.NotNullLazyValue
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
@@ -47,20 +48,20 @@ import org.jetbrains.kotlin.utils.Printer
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.flatMapToNullable
|
||||
import org.jetbrains.kotlin.utils.ifEmpty
|
||||
|
||||
interface IndexedImports<I : KtImportInfo> {
|
||||
val imports: List<I>
|
||||
fun importsForName(name: Name): Collection<I>
|
||||
open class IndexedImports<I : KtImportInfo>(val imports: Array<I>) {
|
||||
open fun importsForName(name: Name): Iterable<I> = imports.asIterable()
|
||||
}
|
||||
|
||||
class AllUnderImportsIndexed<I : KtImportInfo>(allImports: Collection<I>) : IndexedImports<I> {
|
||||
override val imports = allImports.filter { it.isAllUnder }
|
||||
override fun importsForName(name: Name) = imports
|
||||
}
|
||||
inline fun <reified I : KtImportInfo> makeAllUnderImportsIndexed(imports: Collection<I>) : IndexedImports<I> =
|
||||
IndexedImports(imports.filter { it.isAllUnder }.toTypedArray())
|
||||
|
||||
class ExplicitImportsIndexed<I : KtImportInfo>(allImports: Collection<I>) : IndexedImports<I> {
|
||||
override val imports = allImports.filter { !it.isAllUnder }
|
||||
|
||||
private val nameToDirectives: ListMultimap<Name, I> by lazy {
|
||||
class ExplicitImportsIndexed<I : KtImportInfo>(
|
||||
imports: Array<I>,
|
||||
storageManager: StorageManager
|
||||
) : IndexedImports<I>(imports) {
|
||||
|
||||
private val nameToDirectives: NotNullLazyValue<ListMultimap<Name, I>> = storageManager.createLazyValue {
|
||||
val builder = ImmutableListMultimap.builder<Name, I>()
|
||||
|
||||
for (directive in imports) {
|
||||
@@ -71,9 +72,15 @@ class ExplicitImportsIndexed<I : KtImportInfo>(allImports: Collection<I>) : Inde
|
||||
builder.build()
|
||||
}
|
||||
|
||||
override fun importsForName(name: Name) = nameToDirectives.get(name)
|
||||
override fun importsForName(name: Name) = nameToDirectives().get(name)
|
||||
}
|
||||
|
||||
inline fun <reified I : KtImportInfo> makeExplicitImportsIndexed(
|
||||
imports: Collection<I>,
|
||||
storageManager: StorageManager
|
||||
) : IndexedImports<I> =
|
||||
ExplicitImportsIndexed(imports.filter { !it.isAllUnder }.toTypedArray(), storageManager)
|
||||
|
||||
interface ImportForceResolver {
|
||||
fun forceResolveNonDefaultImports()
|
||||
fun forceResolveImport(importDirective: KtImportDirective)
|
||||
@@ -119,15 +126,18 @@ open class LazyImportResolver<I : KtImportInfo>(
|
||||
}
|
||||
|
||||
val allNames: Set<Name>? by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
indexedImports.imports.flatMapToNullable(THashSet()) { getImportScope(it).computeImportedNames() }
|
||||
indexedImports.imports.asIterable().flatMapToNullable(THashSet()) { getImportScope(it).computeImportedNames() }
|
||||
}
|
||||
|
||||
fun definitelyDoesNotContainName(name: Name) = allNames?.let { name !in it } == true
|
||||
|
||||
fun recordLookup(name: Name, location: LookupLocation) {
|
||||
if (allNames == null) return
|
||||
indexedImports.importsForName(name).forEach {
|
||||
getImportScope(it).recordLookup(name, location)
|
||||
for (it in indexedImports.importsForName(name)) {
|
||||
val scope = getImportScope(it)
|
||||
if (scope !== ImportingScope.Empty) {
|
||||
scope.recordLookup(name, location)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+10
-13
@@ -58,25 +58,22 @@ open class LazyClassMemberScope(
|
||||
c, declarationProvider, thisClass, trace, scopeForDeclaredMembers
|
||||
) {
|
||||
|
||||
private val descriptorsFromDeclaredElements = storageManager.createLazyValue {
|
||||
computeDescriptorsFromDeclaredElements(
|
||||
DescriptorKindFilter.ALL,
|
||||
MemberScope.ALL_NAME_FILTER,
|
||||
NoLookupLocation.WHEN_GET_ALL_DESCRIPTORS
|
||||
private val allDescriptors = storageManager.createLazyValue {
|
||||
val result = LinkedHashSet(
|
||||
computeDescriptorsFromDeclaredElements(
|
||||
DescriptorKindFilter.ALL,
|
||||
MemberScope.ALL_NAME_FILTER,
|
||||
NoLookupLocation.WHEN_GET_ALL_DESCRIPTORS
|
||||
)
|
||||
)
|
||||
}
|
||||
private val extraDescriptors: NotNullLazyValue<Collection<DeclarationDescriptor>> = storageManager.createLazyValue {
|
||||
computeExtraDescriptors(NoLookupLocation.FOR_ALREADY_TRACKED)
|
||||
result.addAll(computeExtraDescriptors(NoLookupLocation.FOR_ALREADY_TRACKED))
|
||||
result
|
||||
}
|
||||
|
||||
override fun getContributedDescriptors(
|
||||
kindFilter: DescriptorKindFilter,
|
||||
nameFilter: (Name) -> Boolean
|
||||
): Collection<DeclarationDescriptor> {
|
||||
val result = LinkedHashSet(descriptorsFromDeclaredElements())
|
||||
result.addAll(extraDescriptors())
|
||||
return result
|
||||
}
|
||||
): Collection<DeclarationDescriptor> = allDescriptors()
|
||||
|
||||
protected open fun computeExtraDescriptors(location: LookupLocation): Collection<DeclarationDescriptor> {
|
||||
val result = ArrayList<DeclarationDescriptor>()
|
||||
|
||||
Reference in New Issue
Block a user