[Analysis API FIR] KtFirSymbolDeclarationOverridesProvider: unwrap fake overrides

We should unwrap substitution overrides as they sometimes cannot be
resolved on demand. We already have this in KDoc contract.
```kotlin
class MyClass {
    val prop = object : LazySchemeProcessor<Int, Int>() {
        override fun is<caret>SchemeFile(name: CharSequence) = name != "str"
    }
}

abstract class LazySchemeProcessor<SCHEME : Number, MUTABLE_SCHEME : SCHEME> {
    open fun isSchemeFile(name: CharSequence) = true
}
```
In this case, we will try to resolve fake override in the context of the
anonymous object, and it will fail because we cannot lazily resolve
local declarations as they are a part of the containing declarations
(KT-64243 for more details)

^KT-64108 Fixed
This commit is contained in:
Dmitrii Gridin
2023-12-08 18:35:25 +01:00
committed by Space Team
parent e033fe5ba1
commit b458d69689
15 changed files with 25 additions and 41 deletions
@@ -27,12 +27,12 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirIntersectionOverrideFunctionSymb
import org.jetbrains.kotlin.fir.symbols.impl.FirIntersectionOverridePropertySymbol
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.fir.types.toRegularClassSymbol
import org.jetbrains.kotlin.fir.unwrapFakeOverrides
internal class KtFirSymbolDeclarationOverridesProvider(
override val analysisSession: KtFirAnalysisSession,
override val token: KtLifetimeToken
) : KtSymbolDeclarationOverridesProviderBase(), KtFirAnalysisSessionComponent {
override fun <T : KtSymbol> getAllOverriddenSymbols(
callableSymbol: T,
): List<KtCallableSymbol> {
@@ -40,13 +40,15 @@ internal class KtFirSymbolDeclarationOverridesProvider(
if (callableSymbol is KtValueParameterSymbol) {
return callableSymbol.getAllOverriddenSymbols()
}
val overriddenElement = mutableSetOf<FirCallableSymbol<*>>()
processOverrides(callableSymbol) { firTypeScope, firCallableDeclaration ->
firTypeScope.processAllOverriddenDeclarations(firCallableDeclaration) { overriddenDeclaration ->
overriddenDeclaration.symbol.collectIntersectionOverridesSymbolsTo(overriddenElement)
}
}
return overriddenElement.map { analysisSession.firSymbolBuilder.callableBuilder.buildCallableSymbol(it) }.distinct()
return overriddenElement.map { analysisSession.firSymbolBuilder.callableBuilder.buildCallableSymbol(it) }
}
override fun <T : KtSymbol> getDirectlyOverriddenSymbols(callableSymbol: T): List<KtCallableSymbol> {
@@ -54,13 +56,15 @@ internal class KtFirSymbolDeclarationOverridesProvider(
if (callableSymbol is KtValueParameterSymbol) {
return callableSymbol.getDirectlyOverriddenSymbols()
}
val overriddenElement = mutableSetOf<FirCallableSymbol<*>>()
processOverrides(callableSymbol) { firTypeScope, firCallableDeclaration ->
firTypeScope.processDirectOverriddenDeclarations(firCallableDeclaration) { overriddenDeclaration ->
overriddenDeclaration.symbol.collectIntersectionOverridesSymbolsTo(overriddenElement)
}
}
return overriddenElement.map { analysisSession.firSymbolBuilder.callableBuilder.buildCallableSymbol(it) }.distinct()
return overriddenElement.map { analysisSession.firSymbolBuilder.callableBuilder.buildCallableSymbol(it) }
}
private fun FirTypeScope.processCallableByName(declaration: FirDeclaration) = when (declaration) {
@@ -144,7 +148,7 @@ internal class KtFirSymbolDeclarationOverridesProvider(
intersections.forEach { it.collectIntersectionOverridesSymbolsTo(to) }
}
else -> {
to += this
to += this.fir.unwrapFakeOverrides().symbol
}
}
}