Optimize data handling inside scopes
This commit is contained in:
+7
-4
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.resolve.scopes.flatMapClassifierNamesOrNull
|
||||
import org.jetbrains.kotlin.storage.getValue
|
||||
import org.jetbrains.kotlin.util.collectionUtils.getFirstClassifierDiscriminateHeaders
|
||||
import org.jetbrains.kotlin.util.collectionUtils.getFromAllScopes
|
||||
import org.jetbrains.kotlin.util.collectionUtils.listOfNonEmptyScopes
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
|
||||
class JvmPackageScope(
|
||||
@@ -41,9 +42,11 @@ class JvmPackageScope(
|
||||
internal val javaScope = LazyJavaPackageScope(c, jPackage, packageFragment)
|
||||
|
||||
private val kotlinScopes by c.storageManager.createLazyValue {
|
||||
packageFragment.binaryClasses.values.mapNotNull { partClass ->
|
||||
c.components.deserializedDescriptorResolver.createKotlinPackagePartScope(packageFragment, partClass)
|
||||
}.toList()
|
||||
listOfNonEmptyScopes(
|
||||
packageFragment.binaryClasses.values.mapNotNull { partClass ->
|
||||
c.components.deserializedDescriptorResolver.createKotlinPackagePartScope(packageFragment, partClass)
|
||||
}
|
||||
).toTypedArray()
|
||||
}
|
||||
|
||||
override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? {
|
||||
@@ -78,7 +81,7 @@ class JvmPackageScope(
|
||||
addAll(javaScope.getVariableNames())
|
||||
}
|
||||
|
||||
override fun getClassifierNames(): Set<Name>? = kotlinScopes.flatMapClassifierNamesOrNull()?.apply {
|
||||
override fun getClassifierNames(): Set<Name>? = kotlinScopes.asIterable().flatMapClassifierNamesOrNull()?.apply {
|
||||
addAll(javaScope.getClassifierNames())
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.resolve.NonReportingOverrideStrategy
|
||||
import org.jetbrains.kotlin.resolve.OverridingUtil
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.storage.getValue
|
||||
import org.jetbrains.kotlin.util.collectionUtils.filterIsInstanceAnd
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
import org.jetbrains.kotlin.utils.compact
|
||||
import java.util.*
|
||||
@@ -47,11 +48,11 @@ abstract class GivenFunctionsMemberScope(
|
||||
}
|
||||
|
||||
override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<SimpleFunctionDescriptor> {
|
||||
return allDescriptors.filterIsInstance<SimpleFunctionDescriptor>().filter { it.name == name }
|
||||
return allDescriptors.filterIsInstanceAnd { it.name == name }
|
||||
}
|
||||
|
||||
override fun getContributedVariables(name: Name, location: LookupLocation): Collection<PropertyDescriptor> {
|
||||
return allDescriptors.filterIsInstance<PropertyDescriptor>().filter { it.name == name }
|
||||
return allDescriptors.filterIsInstanceAnd { it.name == name }
|
||||
}
|
||||
|
||||
private fun createFakeOverrides(functionsFromCurrent: List<FunctionDescriptor>): List<DeclarationDescriptor> {
|
||||
|
||||
@@ -58,9 +58,14 @@ interface MemberScope : ResolutionScope {
|
||||
}
|
||||
}
|
||||
|
||||
fun MemberScope.computeAllNames() = getClassifierNames()?.let { getFunctionNames() + getVariableNames() + it }
|
||||
fun MemberScope.computeAllNames() = getClassifierNames()?.let { classifierNames ->
|
||||
getFunctionNames().toMutableSet().also {
|
||||
it.addAll(getVariableNames())
|
||||
it.addAll(classifierNames)
|
||||
}
|
||||
}
|
||||
|
||||
fun Collection<MemberScope>.flatMapClassifierNamesOrNull(): MutableSet<Name>? =
|
||||
fun Iterable<MemberScope>.flatMapClassifierNamesOrNull(): MutableSet<Name>? =
|
||||
flatMapToNullable(hashSetOf(), MemberScope::getClassifierNames)
|
||||
|
||||
/**
|
||||
@@ -167,7 +172,6 @@ class DescriptorKindFilter(
|
||||
val filter = field.get(null) as? DescriptorKindFilter
|
||||
if (filter != null) MaskToName(filter.kindMask, field.name) else null
|
||||
}
|
||||
.toList()
|
||||
|
||||
private val DEBUG_MASK_BIT_NAMES = staticFields<DescriptorKindFilter>()
|
||||
.filter { it.type == Integer.TYPE }
|
||||
@@ -176,7 +180,6 @@ class DescriptorKindFilter(
|
||||
val isOneBitMask = mask == (mask and (-mask))
|
||||
if (isOneBitMask) MaskToName(mask, field.name) else null
|
||||
}
|
||||
.toList()
|
||||
|
||||
private inline fun <reified T : Any> staticFields() = T::class.java.fields.filter { Modifier.isStatic(it.modifiers) }
|
||||
}
|
||||
|
||||
@@ -16,9 +16,13 @@
|
||||
|
||||
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.util.collectionUtils.filterIsInstanceMapTo
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
import org.jetbrains.kotlin.utils.alwaysTrue
|
||||
|
||||
@@ -35,14 +39,14 @@ abstract class MemberScopeImpl : MemberScope {
|
||||
nameFilter: (Name) -> Boolean): Collection<DeclarationDescriptor> = emptyList()
|
||||
|
||||
override fun getFunctionNames(): Set<Name> =
|
||||
getContributedDescriptors(
|
||||
DescriptorKindFilter.FUNCTIONS, alwaysTrue()
|
||||
).filterIsInstance<SimpleFunctionDescriptor>().mapTo(mutableSetOf()) { it.name }
|
||||
getContributedDescriptors(
|
||||
DescriptorKindFilter.FUNCTIONS, alwaysTrue()
|
||||
).filterIsInstanceMapTo<SimpleFunctionDescriptor, Name, MutableSet<Name>>(mutableSetOf()) { it.name }
|
||||
|
||||
override fun getVariableNames(): Set<Name> =
|
||||
getContributedDescriptors(
|
||||
DescriptorKindFilter.VARIABLES, alwaysTrue()
|
||||
).filterIsInstance<VariableDescriptor>().mapTo(mutableSetOf()) { it.name }
|
||||
getContributedDescriptors(
|
||||
DescriptorKindFilter.VARIABLES, alwaysTrue()
|
||||
).filterIsInstanceMapTo<SimpleFunctionDescriptor, Name, MutableSet<Name>>(mutableSetOf()) { it.name }
|
||||
|
||||
override fun getClassifierNames(): Set<Name>? = null
|
||||
|
||||
|
||||
+2
-2
@@ -26,7 +26,7 @@ import org.jetbrains.kotlin.resolve.DescriptorFactory.createEnumValuesMethod
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.storage.getValue
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
import java.util.*
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
|
||||
// We don't need to track lookups here since this scope used only for introduce special Enum class members
|
||||
class StaticScopeForKotlinEnum(
|
||||
@@ -46,7 +46,7 @@ class StaticScopeForKotlinEnum(
|
||||
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean) = functions
|
||||
|
||||
override fun getContributedFunctions(name: Name, location: LookupLocation) =
|
||||
functions.filterTo(ArrayList<SimpleFunctionDescriptor>(1)) { it.name == name }
|
||||
functions.filterTo(SmartList()) { it.name == name }
|
||||
|
||||
override fun printScopeStructure(p: Printer) {
|
||||
p.println("Static scope for $containingClass")
|
||||
|
||||
+8
-6
@@ -5,7 +5,10 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve.scopes.synthetic
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
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.LookupTracker
|
||||
import org.jetbrains.kotlin.incremental.record
|
||||
@@ -16,6 +19,7 @@ import org.jetbrains.kotlin.resolve.scopes.ResolutionScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.SyntheticScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.util.collectionUtils.filterIsInstanceMapNotNull
|
||||
|
||||
class FunInterfaceConstructorsScopeProvider(
|
||||
storageManager: StorageManager,
|
||||
@@ -47,11 +51,9 @@ class FunInterfaceConstructorsSyntheticScope(
|
||||
return listOfNotNull(getSamConstructor(classifier))
|
||||
}
|
||||
|
||||
override fun getSyntheticConstructors(scope: ResolutionScope): Collection<FunctionDescriptor> {
|
||||
val classifiers = scope.getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS).filterIsInstance<ClassifierDescriptor>()
|
||||
|
||||
return classifiers.mapNotNull { getSamConstructor(it) }
|
||||
}
|
||||
override fun getSyntheticConstructors(scope: ResolutionScope): Collection<FunctionDescriptor> =
|
||||
scope.getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS)
|
||||
.filterIsInstanceMapNotNull<ClassifierDescriptor, FunctionDescriptor> { getSamConstructor(it) }
|
||||
|
||||
private fun getSamConstructor(classifier: ClassifierDescriptor): SamConstructorDescriptor? {
|
||||
if (classifier is TypeAliasDescriptor) {
|
||||
|
||||
@@ -18,6 +18,8 @@ package org.jetbrains.kotlin.util.collectionUtils
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
@@ -41,30 +43,20 @@ fun <T> Collection<T>?.concat(collection: Collection<T>): Collection<T>? {
|
||||
return result
|
||||
}
|
||||
|
||||
fun <T> concatInOrder(c1: Collection<T>?, c2: Collection<T>?): Collection<T> {
|
||||
val result = if (c1 == null || c1.isEmpty())
|
||||
c2
|
||||
else if (c2 == null || c2.isEmpty())
|
||||
c1
|
||||
else {
|
||||
val result = LinkedHashSet<T>()
|
||||
result.addAll(c1)
|
||||
result.addAll(c2)
|
||||
result
|
||||
inline fun <Scope, T> getFromAllScopes(scopes: Array<Scope>, callback: (Scope) -> Collection<T>): Collection<T> =
|
||||
when (scopes.size) {
|
||||
0 -> emptyList()
|
||||
1 -> callback(scopes[0])
|
||||
else -> {
|
||||
var result: Collection<T>? = null
|
||||
for (scope in scopes) {
|
||||
result = result.concat(callback(scope))
|
||||
}
|
||||
result ?: emptySet()
|
||||
}
|
||||
}
|
||||
return result ?: emptySet()
|
||||
}
|
||||
|
||||
inline fun <Scope, T> getFromAllScopes(scopes: List<Scope>, callback: (Scope) -> Collection<T>): Collection<T> {
|
||||
if (scopes.isEmpty()) return emptySet()
|
||||
var result: Collection<T>? = null
|
||||
for (scope in scopes) {
|
||||
result = result.concat(callback(scope))
|
||||
}
|
||||
return result ?: emptySet()
|
||||
}
|
||||
|
||||
inline fun <Scope, T> getFromAllScopes(firstScope: Scope, restScopes: List<Scope>, callback: (Scope) -> Collection<T>): Collection<T> {
|
||||
inline fun <Scope, T> getFromAllScopes(firstScope: Scope, restScopes: Array<Scope>, callback: (Scope) -> Collection<T>): Collection<T> {
|
||||
var result: Collection<T>? = callback(firstScope)
|
||||
for (scope in restScopes) {
|
||||
result = result.concat(callback(scope))
|
||||
@@ -72,7 +64,20 @@ inline fun <Scope, T> getFromAllScopes(firstScope: Scope, restScopes: List<Scope
|
||||
return result ?: emptySet()
|
||||
}
|
||||
|
||||
inline fun <Scope, T : ClassifierDescriptor> getFirstClassifierDiscriminateHeaders(scopes: List<Scope>, callback: (Scope) -> T?): T? {
|
||||
inline fun <Scope, R> Array<out Scope>.flatMapScopes(transform: (Scope) -> Collection<R>): Collection<R> =
|
||||
when (size) {
|
||||
0 -> emptyList()
|
||||
1 -> transform(get(0))
|
||||
else -> flatMapTo(ArrayList<R>(), transform)
|
||||
}
|
||||
|
||||
fun listOfNonEmptyScopes(vararg scopes: MemberScope?): SmartList<MemberScope> =
|
||||
scopes.filterTo(SmartList<MemberScope>()) { it != null && it !== MemberScope.Empty }
|
||||
|
||||
fun listOfNonEmptyScopes(scopes: Iterable<MemberScope?>): SmartList<MemberScope> =
|
||||
scopes.filterTo(SmartList<MemberScope>()) { it != null && it !== MemberScope.Empty }
|
||||
|
||||
inline fun <Scope, T : ClassifierDescriptor> getFirstClassifierDiscriminateHeaders(scopes: Array<Scope>, callback: (Scope) -> T?): T? {
|
||||
// NOTE: This is performance-sensitive; please don't replace with map().firstOrNull()
|
||||
var result: T? = null
|
||||
for (scope in scopes) {
|
||||
@@ -89,3 +94,32 @@ inline fun <Scope, T : ClassifierDescriptor> getFirstClassifierDiscriminateHeade
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
inline fun <reified R> Iterable<*>.filterIsInstanceAnd(predicate: (R) -> Boolean): Collection<R> =
|
||||
filterIsInstanceAndTo(SmartList(), predicate)
|
||||
|
||||
inline fun <reified R, C : MutableCollection<in R>> Iterable<*>.filterIsInstanceAndTo(destination: C, predicate: (R) -> Boolean): C {
|
||||
for (element in this) if (element is R && predicate(element)) destination.add(element)
|
||||
return destination
|
||||
}
|
||||
|
||||
inline fun <reified T, reified R, C : MutableCollection<in R>> Iterable<*>.filterIsInstanceMapTo(destination: C, transform: (T) -> R): C {
|
||||
for (element in this) if (element is T) {
|
||||
destination.add(transform(element))
|
||||
}
|
||||
return destination
|
||||
}
|
||||
|
||||
inline fun <reified T, reified R> Iterable<*>.filterIsInstanceMapNotNull(transform: (T) -> R?): Collection<R> =
|
||||
filterIsInstanceMapNotNullTo(SmartList(), transform)
|
||||
|
||||
inline fun <reified T, reified R, C : MutableCollection<in R>> Iterable<*>.filterIsInstanceMapNotNullTo(destination: C, transform: (T) -> R?): C {
|
||||
for (element in this) if (element is T) {
|
||||
val result = transform(element)
|
||||
if (result != null) {
|
||||
destination.add(result)
|
||||
}
|
||||
}
|
||||
return destination
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user