[Analysis API] remove caches from KtFirScopeProvider
The hit-rate for this cache seems to be very law and it causes additional memory consumption ^KTIJ-22749
This commit is contained in:
+33
-50
@@ -45,7 +45,6 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.applyIf
|
import org.jetbrains.kotlin.utils.addToStdlib.applyIf
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
internal class KtFirScopeProvider(
|
internal class KtFirScopeProvider(
|
||||||
override val analysisSession: KtFirAnalysisSession,
|
override val analysisSession: KtFirAnalysisSession,
|
||||||
@@ -56,12 +55,6 @@ internal class KtFirScopeProvider(
|
|||||||
// KtFirScopeProvider is thread local, so it's okay to use the same session here
|
// KtFirScopeProvider is thread local, so it's okay to use the same session here
|
||||||
private val scopeSession = analysisSession.getScopeSessionFor(analysisSession.useSiteSession)
|
private val scopeSession = analysisSession.getScopeSessionFor(analysisSession.useSiteSession)
|
||||||
|
|
||||||
private val memberScopeCache = IdentityHashMap<KtSymbolWithMembers, KtScope>()
|
|
||||||
private val declaredMemberScopeCache = IdentityHashMap<KtSymbolWithMembers, KtScope>()
|
|
||||||
private val delegatedMemberScopeCache = IdentityHashMap<KtSymbolWithMembers, KtScope>()
|
|
||||||
private val fileScopeCache = IdentityHashMap<KtFileSymbol, KtScope>()
|
|
||||||
private val packageMemberScopeCache = IdentityHashMap<KtPackageSymbol, KtScope>()
|
|
||||||
|
|
||||||
private inline fun <T> KtSymbolWithMembers.withFirForScope(crossinline body: (FirClass) -> T): T? {
|
private inline fun <T> KtSymbolWithMembers.withFirForScope(crossinline body: (FirClass) -> T): T? {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is KtFirNamedClassOrObjectSymbol -> body(firSymbol.fir)
|
is KtFirNamedClassOrObjectSymbol -> body(firSymbol.fir)
|
||||||
@@ -78,19 +71,17 @@ internal class KtFirScopeProvider(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getMemberScope(classSymbol: KtSymbolWithMembers): KtScope {
|
override fun getMemberScope(classSymbol: KtSymbolWithMembers): KtScope {
|
||||||
return memberScopeCache.getOrPut(classSymbol) {
|
val firScope = classSymbol.withFirForScope { fir ->
|
||||||
val firScope = classSymbol.withFirForScope { fir ->
|
fir.lazyResolveToPhase(FirResolvePhase.STATUS)
|
||||||
fir.lazyResolveToPhase(FirResolvePhase.STATUS)
|
val firSession = analysisSession.useSiteSession
|
||||||
val firSession = analysisSession.useSiteSession
|
fir.unsubstitutedScope(
|
||||||
fir.unsubstitutedScope(
|
firSession,
|
||||||
firSession,
|
scopeSession,
|
||||||
scopeSession,
|
withForcedTypeCalculator = false
|
||||||
withForcedTypeCalculator = false
|
)
|
||||||
)
|
}?.applyIf(classSymbol is KtEnumEntrySymbol, ::EnumEntryContainingNamesAwareScope)
|
||||||
}?.applyIf(classSymbol is KtEnumEntrySymbol, ::EnumEntryContainingNamesAwareScope)
|
?: return getEmptyScope()
|
||||||
?: return@getOrPut getEmptyScope()
|
return KtFirDelegatingScope(firScope, builder)
|
||||||
KtFirDelegatingScope(firScope, builder)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getStaticMemberScope(symbol: KtSymbolWithMembers): KtScope {
|
override fun getStaticMemberScope(symbol: KtSymbolWithMembers): KtScope {
|
||||||
@@ -106,43 +97,37 @@ internal class KtFirScopeProvider(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getDeclaredMemberScope(classSymbol: KtSymbolWithMembers): KtScope {
|
override fun getDeclaredMemberScope(classSymbol: KtSymbolWithMembers): KtScope {
|
||||||
return declaredMemberScopeCache.getOrPut(classSymbol) {
|
val firScope = classSymbol.withFirForScope {
|
||||||
val firScope = classSymbol.withFirForScope {
|
analysisSession.useSiteSession.declaredMemberScope(it)
|
||||||
analysisSession.useSiteSession.declaredMemberScope(it)
|
} ?: return getEmptyScope()
|
||||||
} ?: return@getOrPut getEmptyScope()
|
|
||||||
|
|
||||||
KtFirDelegatingScope(firScope, builder)
|
return KtFirDelegatingScope(firScope, builder)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getDelegatedMemberScope(classSymbol: KtSymbolWithMembers): KtScope {
|
override fun getDelegatedMemberScope(classSymbol: KtSymbolWithMembers): KtScope {
|
||||||
val declaredScope = (getDeclaredMemberScope(classSymbol) as? KtFirDelegatingScope)?.firScope
|
val declaredScope = (getDeclaredMemberScope(classSymbol) as? KtFirDelegatingScope)?.firScope
|
||||||
?: return delegatedMemberScopeCache.getOrPut(classSymbol) { getEmptyScope() }
|
?: return getEmptyScope()
|
||||||
return delegatedMemberScopeCache.getOrPut(classSymbol) {
|
val firScope = classSymbol.withFirForScope { fir ->
|
||||||
val firScope = classSymbol.withFirForScope { fir ->
|
fir.lazyResolveToPhase(FirResolvePhase.STATUS)
|
||||||
fir.lazyResolveToPhase(FirResolvePhase.STATUS)
|
val delegateFields = fir.delegateFields
|
||||||
val delegateFields = fir.delegateFields
|
if (delegateFields.isNotEmpty()) {
|
||||||
if (delegateFields.isNotEmpty()) {
|
val firSession = analysisSession.useSiteSession
|
||||||
val firSession = analysisSession.useSiteSession
|
FirDelegatedMemberScope(
|
||||||
FirDelegatedMemberScope(
|
firSession,
|
||||||
firSession,
|
scopeSession,
|
||||||
scopeSession,
|
fir,
|
||||||
fir,
|
declaredScope,
|
||||||
declaredScope,
|
delegateFields
|
||||||
delegateFields
|
)
|
||||||
)
|
} else null
|
||||||
} else null
|
} ?: return getEmptyScope()
|
||||||
} ?: return@getOrPut getEmptyScope()
|
|
||||||
|
|
||||||
KtFirDelegatedMemberScope(firScope, builder)
|
return KtFirDelegatedMemberScope(firScope, builder)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getFileScope(fileSymbol: KtFileSymbol): KtScope {
|
override fun getFileScope(fileSymbol: KtFileSymbol): KtScope {
|
||||||
return fileScopeCache.getOrPut(fileSymbol) {
|
|
||||||
check(fileSymbol is KtFirFileSymbol) { "KtFirScopeProvider can only work with KtFirFileSymbol, but ${fileSymbol::class} was provided" }
|
check(fileSymbol is KtFirFileSymbol) { "KtFirScopeProvider can only work with KtFirFileSymbol, but ${fileSymbol::class} was provided" }
|
||||||
KtFirFileScope(fileSymbol, builder)
|
return KtFirFileScope(fileSymbol, builder)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getEmptyScope(): KtScope {
|
override fun getEmptyScope(): KtScope {
|
||||||
@@ -150,9 +135,7 @@ internal class KtFirScopeProvider(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getPackageScope(packageSymbol: KtPackageSymbol): KtScope {
|
override fun getPackageScope(packageSymbol: KtPackageSymbol): KtScope {
|
||||||
return packageMemberScopeCache.getOrPut(packageSymbol) {
|
return createPackageScope(packageSymbol.fqName)
|
||||||
createPackageScope(packageSymbol.fqName)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user