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 propertiesFromSupertypes: MutableMap<Name, List<ResultOfIntersection<FirPropertySymbol>>> = mutableMapOf()
|
||||||
protected val fieldsFromSupertypes: MutableMap<Name, List<FirFieldSymbol>> = mutableMapOf()
|
protected val fieldsFromSupertypes: MutableMap<Name, List<FirFieldSymbol>> = mutableMapOf()
|
||||||
|
|
||||||
private val absentClassifiersFromSupertypes = mutableSetOf<Name>()
|
|
||||||
|
|
||||||
private val callableNamesCached by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
private val callableNamesCached by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||||
buildSet {
|
buildSet {
|
||||||
addAll(declaredMemberScope.getCallableNames())
|
addAll(declaredMemberScope.getCallableNames())
|
||||||
@@ -53,6 +51,8 @@ abstract class AbstractFirUseSiteMemberScope(
|
|||||||
}
|
}
|
||||||
|
|
||||||
final override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) {
|
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) {
|
functions.getOrPut(name) {
|
||||||
collectFunctions(name)
|
collectFunctions(name)
|
||||||
}.forEach {
|
}.forEach {
|
||||||
@@ -102,6 +102,8 @@ abstract class AbstractFirUseSiteMemberScope(
|
|||||||
}
|
}
|
||||||
|
|
||||||
final override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
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) {
|
properties.getOrPut(name) {
|
||||||
collectProperties(name)
|
collectProperties(name)
|
||||||
}.forEach {
|
}.forEach {
|
||||||
@@ -198,13 +200,16 @@ abstract class AbstractFirUseSiteMemberScope(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) {
|
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
|
var shadowed = false
|
||||||
declaredMemberScope.processClassifiersByNameWithSubstitution(name) { classifier, substitutor ->
|
declaredMemberScope.processClassifiersByNameWithSubstitution(name) { classifier, substitutor ->
|
||||||
shadowed = true
|
shadowed = true
|
||||||
processor(classifier, substitutor)
|
processor(classifier, substitutor)
|
||||||
}
|
}
|
||||||
if (!shadowed) {
|
if (!shadowed) {
|
||||||
supertypeScopeContext.processClassifiersByNameWithSubstitution(name, absentClassifiersFromSupertypes, processor)
|
supertypeScopeContext.processClassifiersByNameWithSubstitution(name, processor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+14
-20
@@ -21,41 +21,35 @@ class FirTypeIntersectionScope private constructor(
|
|||||||
private val intersectionContext =
|
private val intersectionContext =
|
||||||
FirTypeIntersectionScopeContext(session, overrideChecker, scopes, dispatchReceiverType, forClassUseSiteScope = false)
|
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 overriddenSymbols: MutableMap<FirCallableSymbol<*>, Collection<MemberWithBaseScope<FirCallableSymbol<*>>>> = mutableMapOf()
|
||||||
|
|
||||||
private val callableNamesCached by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
private val callableNamesCached by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||||
scopes.flatMapTo(mutableSetOf()) { it.getCallableNames() }
|
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) {
|
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) {
|
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(
|
private inline fun <D : FirCallableSymbol<*>> processCallablesByName(
|
||||||
name: Name,
|
name: Name,
|
||||||
noinline processor: (D) -> Unit,
|
noinline processor: (D) -> Unit,
|
||||||
absentNames: MutableSet<Name>,
|
|
||||||
processCallables: FirScope.(Name, (D) -> Unit) -> Unit
|
processCallables: FirScope.(Name, (D) -> Unit) -> Unit
|
||||||
) {
|
) {
|
||||||
if (name in absentNames) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val callablesWithOverridden = intersectionContext.collectIntersectionResultsForCallables(name, processCallables)
|
val callablesWithOverridden = intersectionContext.collectIntersectionResultsForCallables(name, processCallables)
|
||||||
|
|
||||||
if (callablesWithOverridden.isEmpty()) {
|
|
||||||
absentNames.add(name)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for (resultOfIntersection in callablesWithOverridden) {
|
for (resultOfIntersection in callablesWithOverridden) {
|
||||||
val symbol = resultOfIntersection.chosenSymbol
|
val symbol = resultOfIntersection.chosenSymbol
|
||||||
overriddenSymbols[symbol] = resultOfIntersection.overriddenMembers
|
overriddenSymbols[symbol] = resultOfIntersection.overriddenMembers
|
||||||
@@ -64,7 +58,9 @@ class FirTypeIntersectionScope private constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) {
|
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")
|
@Suppress("UNCHECKED_CAST")
|
||||||
@@ -112,9 +108,7 @@ class FirTypeIntersectionScope private constructor(
|
|||||||
|
|
||||||
override fun getCallableNames(): Set<Name> = callableNamesCached
|
override fun getCallableNames(): Set<Name> = callableNamesCached
|
||||||
|
|
||||||
override fun getClassifierNames(): Set<Name> {
|
override fun getClassifierNames(): Set<Name> = classifiersNamesCached
|
||||||
return scopes.flatMapTo(hashSetOf()) { it.getClassifierNames() }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "Intersection of [${scopes.joinToString(", ")}]"
|
return "Intersection of [${scopes.joinToString(", ")}]"
|
||||||
|
|||||||
+1
-8
@@ -76,16 +76,9 @@ class FirTypeIntersectionScopeContext(
|
|||||||
|
|
||||||
fun processClassifiersByNameWithSubstitution(
|
fun processClassifiersByNameWithSubstitution(
|
||||||
name: Name,
|
name: Name,
|
||||||
absentClassifierNames: MutableSet<Name>,
|
|
||||||
processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit
|
processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit
|
||||||
) {
|
) {
|
||||||
if (name in absentClassifierNames) return
|
for ((symbol, substitution) in collectClassifiers(name)) {
|
||||||
val classifiers = collectClassifiers(name)
|
|
||||||
if (classifiers.isEmpty()) {
|
|
||||||
absentClassifierNames += name
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for ((symbol, substitution) in classifiers) {
|
|
||||||
processor(symbol, substitution)
|
processor(symbol, substitution)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user