K2: Optimize use-site member and intersection scopes
Avoid creating cache keys for names that are definitely absent
This commit is contained in:
committed by
Space Team
parent
db3b7c4021
commit
24bd7e5eef
+8
-3
@@ -36,8 +36,6 @@ abstract class AbstractFirUseSiteMemberScope(
|
||||
protected val propertiesFromSupertypes: MutableMap<Name, List<ResultOfIntersection<FirPropertySymbol>>> = mutableMapOf()
|
||||
protected val fieldsFromSupertypes: MutableMap<Name, List<FirFieldSymbol>> = mutableMapOf()
|
||||
|
||||
private val absentClassifiersFromSupertypes = mutableSetOf<Name>()
|
||||
|
||||
private val callableNamesCached by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
buildSet {
|
||||
addAll(declaredMemberScope.getCallableNames())
|
||||
@@ -53,6 +51,8 @@ abstract class AbstractFirUseSiteMemberScope(
|
||||
}
|
||||
|
||||
final override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) {
|
||||
// Important optimization: avoid creating cache keys for names that are definitely absent
|
||||
if (name !in getCallableNames()) return
|
||||
functions.getOrPut(name) {
|
||||
collectFunctions(name)
|
||||
}.forEach {
|
||||
@@ -102,6 +102,8 @@ abstract class AbstractFirUseSiteMemberScope(
|
||||
}
|
||||
|
||||
final override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
||||
// Important optimization: avoid creating cache keys for names that are definitely absent
|
||||
if (name !in getCallableNames()) return
|
||||
properties.getOrPut(name) {
|
||||
collectProperties(name)
|
||||
}.forEach {
|
||||
@@ -198,13 +200,16 @@ abstract class AbstractFirUseSiteMemberScope(
|
||||
}
|
||||
|
||||
override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) {
|
||||
// Important optimization: avoid creating cache keys for names that are definitely absent
|
||||
if (name !in getClassifierNames()) return
|
||||
|
||||
var shadowed = false
|
||||
declaredMemberScope.processClassifiersByNameWithSubstitution(name) { classifier, substitutor ->
|
||||
shadowed = true
|
||||
processor(classifier, substitutor)
|
||||
}
|
||||
if (!shadowed) {
|
||||
supertypeScopeContext.processClassifiersByNameWithSubstitution(name, absentClassifiersFromSupertypes, processor)
|
||||
supertypeScopeContext.processClassifiersByNameWithSubstitution(name, processor)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+14
-20
@@ -21,41 +21,35 @@ class FirTypeIntersectionScope private constructor(
|
||||
private val intersectionContext =
|
||||
FirTypeIntersectionScopeContext(session, overrideChecker, scopes, dispatchReceiverType, forClassUseSiteScope = false)
|
||||
|
||||
private val absentFunctions: MutableSet<Name> = mutableSetOf()
|
||||
private val absentProperties: MutableSet<Name> = mutableSetOf()
|
||||
private val absentClassifiers: MutableSet<Name> = mutableSetOf()
|
||||
|
||||
private val overriddenSymbols: MutableMap<FirCallableSymbol<*>, Collection<MemberWithBaseScope<FirCallableSymbol<*>>>> = mutableMapOf()
|
||||
|
||||
private val callableNamesCached by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
scopes.flatMapTo(mutableSetOf()) { it.getCallableNames() }
|
||||
}
|
||||
|
||||
private val classifiersNamesCached by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
scopes.flatMapTo(hashSetOf()) { it.getClassifierNames() }
|
||||
}
|
||||
|
||||
override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) {
|
||||
processCallablesByName(name, processor, absentFunctions, FirScope::processFunctionsByName)
|
||||
// Important optimization: avoid creating cache keys for names that are definitely absent
|
||||
if (name !in getCallableNames()) return
|
||||
processCallablesByName(name, processor, FirScope::processFunctionsByName)
|
||||
}
|
||||
|
||||
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
||||
processCallablesByName(name, processor, absentProperties, FirScope::processPropertiesByName)
|
||||
// Important optimization: avoid creating cache keys for names that are definitely absent
|
||||
if (name !in getCallableNames()) return
|
||||
processCallablesByName(name, processor, FirScope::processPropertiesByName)
|
||||
}
|
||||
|
||||
private inline fun <D : FirCallableSymbol<*>> processCallablesByName(
|
||||
name: Name,
|
||||
noinline processor: (D) -> Unit,
|
||||
absentNames: MutableSet<Name>,
|
||||
processCallables: FirScope.(Name, (D) -> Unit) -> Unit
|
||||
) {
|
||||
if (name in absentNames) {
|
||||
return
|
||||
}
|
||||
|
||||
val callablesWithOverridden = intersectionContext.collectIntersectionResultsForCallables(name, processCallables)
|
||||
|
||||
if (callablesWithOverridden.isEmpty()) {
|
||||
absentNames.add(name)
|
||||
return
|
||||
}
|
||||
|
||||
for (resultOfIntersection in callablesWithOverridden) {
|
||||
val symbol = resultOfIntersection.chosenSymbol
|
||||
overriddenSymbols[symbol] = resultOfIntersection.overriddenMembers
|
||||
@@ -64,7 +58,9 @@ class FirTypeIntersectionScope private constructor(
|
||||
}
|
||||
|
||||
override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) {
|
||||
intersectionContext.processClassifiersByNameWithSubstitution(name, absentClassifiers, processor)
|
||||
// Important optimization: avoid creating cache keys for names that are definitely absent
|
||||
if (name !in getClassifierNames()) return
|
||||
intersectionContext.processClassifiersByNameWithSubstitution(name, processor)
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
@@ -112,9 +108,7 @@ class FirTypeIntersectionScope private constructor(
|
||||
|
||||
override fun getCallableNames(): Set<Name> = callableNamesCached
|
||||
|
||||
override fun getClassifierNames(): Set<Name> {
|
||||
return scopes.flatMapTo(hashSetOf()) { it.getClassifierNames() }
|
||||
}
|
||||
override fun getClassifierNames(): Set<Name> = classifiersNamesCached
|
||||
|
||||
override fun toString(): String {
|
||||
return "Intersection of [${scopes.joinToString(", ")}]"
|
||||
|
||||
+1
-8
@@ -76,16 +76,9 @@ class FirTypeIntersectionScopeContext(
|
||||
|
||||
fun processClassifiersByNameWithSubstitution(
|
||||
name: Name,
|
||||
absentClassifierNames: MutableSet<Name>,
|
||||
processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit
|
||||
) {
|
||||
if (name in absentClassifierNames) return
|
||||
val classifiers = collectClassifiers(name)
|
||||
if (classifiers.isEmpty()) {
|
||||
absentClassifierNames += name
|
||||
return
|
||||
}
|
||||
for ((symbol, substitution) in classifiers) {
|
||||
for ((symbol, substitution) in collectClassifiers(name)) {
|
||||
processor(symbol, substitution)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user