[FIR] Don't remove subsumed members from intersection overrides's overriddens

This fixes a bunch of missing overridden symbols in IR.
This is also required for fixing KT-59921 in the following commit
where we need to keep all overridden symbols of intersection overrides
so that we can enhance them properly.

#KT-57300 Fixed
#KT-57299 Fixed
#KT-59921
#KT-57300
#KT-62788
#KT-64271
#KT-64382
This commit is contained in:
Kirill Rakhman
2024-01-17 09:59:17 +01:00
committed by Space Team
parent d80dee6e1c
commit 3b841dcb98
58 changed files with 899 additions and 530 deletions
@@ -17,14 +17,12 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolOrigin
import org.jetbrains.kotlin.analysis.api.symbols.KtValueParameterSymbol
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.superConeTypes
import org.jetbrains.kotlin.fir.scopes.*
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirIntersectionOverrideFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirIntersectionOverridePropertySymbol
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.fir.types.toRegularClassSymbol
import org.jetbrains.kotlin.fir.unwrapFakeOverrides
@@ -36,15 +34,24 @@ internal class KtFirSymbolDeclarationOverridesProvider(
override fun <T : KtSymbol> getAllOverriddenSymbols(
callableSymbol: T,
): List<KtCallableSymbol> {
require(callableSymbol is KtFirSymbol<*>)
if (callableSymbol is KtFirBackingFieldSymbol) return emptyList()
if (callableSymbol is KtValueParameterSymbol) {
return callableSymbol.getAllOverriddenSymbols()
}
(callableSymbol.firSymbol as? FirIntersectionCallableSymbol)?.let { intersectionSymbol ->
return intersectionSymbol.intersections.flatMap {
getAllOverriddenSymbols(analysisSession.firSymbolBuilder.callableBuilder.buildCallableSymbol(it))
}
}
val overriddenElement = mutableSetOf<FirCallableSymbol<*>>()
processOverrides(callableSymbol) { firTypeScope, firCallableDeclaration ->
firTypeScope.processAllOverriddenDeclarations(firCallableDeclaration) { overriddenDeclaration ->
overriddenDeclaration.symbol.collectIntersectionOverridesSymbolsTo(overriddenElement)
overriddenDeclaration.symbol.collectIntersectionOverridesSymbolsTo(
overriddenElement,
callableSymbol.analysisSession.useSiteSession
)
}
}
@@ -52,15 +59,22 @@ internal class KtFirSymbolDeclarationOverridesProvider(
}
override fun <T : KtSymbol> getDirectlyOverriddenSymbols(callableSymbol: T): List<KtCallableSymbol> {
require(callableSymbol is KtFirSymbol<*>)
if (callableSymbol is KtFirBackingFieldSymbol) return emptyList()
if (callableSymbol is KtValueParameterSymbol) {
return callableSymbol.getDirectlyOverriddenSymbols()
}
if (callableSymbol is KtCallableSymbol && callableSymbol.firSymbol is FirIntersectionCallableSymbol) {
return getIntersectionOverriddenSymbols(callableSymbol)
}
val overriddenElement = mutableSetOf<FirCallableSymbol<*>>()
processOverrides(callableSymbol) { firTypeScope, firCallableDeclaration ->
firTypeScope.processDirectOverriddenDeclarations(firCallableDeclaration) { overriddenDeclaration ->
overriddenDeclaration.symbol.collectIntersectionOverridesSymbolsTo(overriddenElement)
overriddenDeclaration.symbol.collectIntersectionOverridesSymbolsTo(
overriddenElement,
callableSymbol.analysisSession.useSiteSession
)
}
}
@@ -139,13 +153,13 @@ internal class KtFirSymbolDeclarationOverridesProvider(
process(firTypeScope, firCallableDeclaration)
}
private fun FirCallableSymbol<*>.collectIntersectionOverridesSymbolsTo(to: MutableCollection<FirCallableSymbol<*>>) {
private fun FirCallableSymbol<*>.collectIntersectionOverridesSymbolsTo(
to: MutableCollection<FirCallableSymbol<*>>,
useSiteSession: FirSession,
) {
when (this) {
is FirIntersectionOverrideFunctionSymbol -> {
intersections.forEach { it.collectIntersectionOverridesSymbolsTo(to) }
}
is FirIntersectionOverridePropertySymbol -> {
intersections.forEach { it.collectIntersectionOverridesSymbolsTo(to) }
is FirIntersectionCallableSymbol -> {
getIntersectionOverriddenSymbols(useSiteSession).forEach { it.collectIntersectionOverridesSymbolsTo(to, useSiteSession) }
}
else -> {
to += this.fir.unwrapFakeOverrides().symbol
@@ -187,22 +201,21 @@ internal class KtFirSymbolDeclarationOverridesProvider(
return false
}
override fun getIntersectionOverriddenSymbols(symbol: KtCallableSymbol): Collection<KtCallableSymbol> {
override fun getIntersectionOverriddenSymbols(symbol: KtCallableSymbol): List<KtCallableSymbol> {
require(symbol is KtFirSymbol<*>)
if (symbol.origin != KtSymbolOrigin.INTERSECTION_OVERRIDE) return emptyList()
return symbol.firSymbol
.getIntersectionOverriddenSymbols()
.getIntersectionOverriddenSymbols(symbol.analysisSession.useSiteSession)
.map { analysisSession.firSymbolBuilder.callableBuilder.buildCallableSymbol(it) }
}
private fun FirBasedSymbol<*>.getIntersectionOverriddenSymbols(): Collection<FirCallableSymbol<*>> {
private fun FirBasedSymbol<*>.getIntersectionOverriddenSymbols(useSiteSession: FirSession): Collection<FirCallableSymbol<*>> {
require(this is FirCallableSymbol<*>) {
"Required FirCallableSymbol but ${this::class} found"
}
return when (this) {
is FirIntersectionOverrideFunctionSymbol -> intersections
is FirIntersectionOverridePropertySymbol -> intersections
is FirIntersectionCallableSymbol -> getNonSubsumedOverriddenSymbols(useSiteSession, analysisSession.getScopeSessionFor(useSiteSession))
else -> listOf(this)
}
}