[FIR] Update all required places according to changed overridden processing contract

This commit fixes all places that relied on the contract described in
  the previous commit and also updates corresponding tests

^KT-63738
This commit is contained in:
Dmitriy Novozhilov
2023-12-06 15:51:55 +02:00
committed by Space Team
parent 4272f2e156
commit 385bff3be1
18 changed files with 101 additions and 228 deletions
@@ -7,9 +7,14 @@ B:
C:
[Source]: public open override fun getFoo(): R|kotlin/String| from Java enhancement scope for /C [id: 0]
[Source]: public open override fun getFoo(): R|kotlin/String| from Use site scope of /B [id: 0]
[Enhancement]: public abstract fun getFoo(): R|kotlin/String!| from Java enhancement scope for /A [id: 1]
[Enhancement]: public abstract fun getFoo(): R|kotlin/String!| from Java enhancement scope for /A [id: 1]
D:
[Source]: public open override fun getFoo(): R|kotlin/String| from Use site scope of /D [id: 0]
[Enhancement]: public abstract fun getFoo(): R|kotlin/String!| from Java enhancement scope for /A [id: 1]
[Source]: public open override fun getFoo(): R|kotlin/String| from Java enhancement scope for /C [id: 0]
[Source]: public open override fun getFoo(): R|kotlin/String| from Use site scope of /B [id: 0]
[Enhancement]: public abstract fun getFoo(): R|kotlin/String!| from Java enhancement scope for /A [id: 1]
[Enhancement]: public abstract fun getFoo(): R|kotlin/String!| from Java enhancement scope for /A [id: 1]
@@ -1,26 +1,38 @@
C:
[Source]: public abstract override fun foo(): R|kotlin/Any| from Use site scope of /C [id: 0]
[Source]: public abstract fun foo(): R|kotlin/Any| from Use site scope of /A [id: 1]
[Source]: public abstract override fun foo(): R|kotlin/Any| from Use site scope of /B [id: 0]
[Source]: public abstract fun foo(): R|kotlin/Any| from Use site scope of /A [id: 1]
[Source]: public abstract override val x: R|kotlin/Any| from Use site scope of /C [id: 0]
[Source]: public abstract val x: R|kotlin/Any| from Use site scope of /A [id: 1]
[Source]: public abstract override val x: R|kotlin/Any| from Use site scope of /B [id: 0]
[Source]: public abstract val x: R|kotlin/Any| from Use site scope of /A [id: 1]
Explicit:
[Source]: public abstract override fun foo(): R|kotlin/Int| from Use site scope of /Explicit [id: 0]
[Source]: public abstract override fun foo(): R|kotlin/Any| from Use site scope of /C [id: 1]
[Source]: public abstract fun foo(): R|kotlin/Any| from Use site scope of /A [id: 2]
[Source]: public abstract override fun foo(): R|kotlin/Any| from Use site scope of /B [id: 1]
[Source]: public abstract fun foo(): R|kotlin/Any| from Use site scope of /A [id: 2]
[Source]: public abstract fun foo(): R|kotlin/Int| from Use site scope of /D [id: 3]
[Source]: public abstract override val x: R|kotlin/Any| from Use site scope of /Explicit [id: 0]
[Source]: public abstract override val x: R|kotlin/Any| from Use site scope of /C [id: 1]
[Source]: public abstract val x: R|kotlin/Any| from Use site scope of /A [id: 2]
[Source]: public abstract override val x: R|kotlin/Any| from Use site scope of /B [id: 1]
[Source]: public abstract val x: R|kotlin/Any| from Use site scope of /A [id: 2]
[Source]: public abstract val x: R|kotlin/Any| from Use site scope of /D [id: 3]
Implicit:
[IntersectionOverride]: public abstract fun foo(): R|kotlin/Int| from Use site scope of /Implicit [id: 0]
[Source]: public abstract override fun foo(): R|kotlin/Any| from Use site scope of /C [id: 1]
[Source]: public abstract fun foo(): R|kotlin/Any| from Use site scope of /A [id: 2]
[Source]: public abstract override fun foo(): R|kotlin/Any| from Use site scope of /B [id: 1]
[Source]: public abstract fun foo(): R|kotlin/Any| from Use site scope of /A [id: 2]
[Source]: public abstract fun foo(): R|kotlin/Int| from Use site scope of /D [id: 3]
[IntersectionOverride]: public abstract override val x: R|kotlin/Any| from Use site scope of /Implicit [id: 0]
[Source]: public abstract override val x: R|kotlin/Any| from Use site scope of /C [id: 1]
[Source]: public abstract val x: R|kotlin/Any| from Use site scope of /A [id: 2]
[Source]: public abstract override val x: R|kotlin/Any| from Use site scope of /B [id: 1]
[Source]: public abstract val x: R|kotlin/Any| from Use site scope of /A [id: 2]
[Source]: public abstract val x: R|kotlin/Any| from Use site scope of /D [id: 3]
@@ -1,25 +1,38 @@
C:
[Source]: public abstract override fun foo(): R|kotlin/Any| from Use site scope of /C [id: 0]
[Source]: public abstract fun foo(): R|kotlin/Any| from Use site scope of /A [id: 1]
[Source]: public abstract override fun foo(): R|kotlin/Any| from Use site scope of /B [id: 0]
[Source]: public abstract fun foo(): R|kotlin/Any| from Use site scope of /A [id: 1]
[Source]: public abstract override val x: R|kotlin/Any| from Use site scope of /C [id: 0]
[Source]: public abstract val x: R|kotlin/Any| from Use site scope of /A [id: 1]
[Source]: public abstract override val x: R|kotlin/Any| from Use site scope of /B [id: 0]
[Source]: public abstract val x: R|kotlin/Any| from Use site scope of /A [id: 1]
Explicit:
[Source]: public abstract override fun foo(): R|kotlin/Int| from Use site scope of /Explicit [id: 0]
[Source]: public abstract override fun foo(): R|kotlin/Any| from Use site scope of /C [id: 1]
[Source]: public abstract fun foo(): R|kotlin/Any| from Use site scope of /A [id: 2]
[Source]: public abstract override fun foo(): R|kotlin/Any| from Use site scope of /B [id: 1]
[Source]: public abstract fun foo(): R|kotlin/Any| from Use site scope of /A [id: 2]
[Source]: public abstract fun foo(): R|kotlin/Int| from Use site scope of /D [id: 3]
[Source]: public abstract override val x: R|kotlin/Any| from Use site scope of /Explicit [id: 0]
[Source]: public abstract override val x: R|kotlin/Any| from Use site scope of /C [id: 1]
[Source]: public abstract val x: R|kotlin/Any| from Use site scope of /A [id: 2]
[Source]: public abstract override val x: R|kotlin/Any| from Use site scope of /B [id: 1]
[Source]: public abstract val x: R|kotlin/Any| from Use site scope of /A [id: 2]
[Source]: public abstract val x: R|kotlin/Any| from Use site scope of /D [id: 3]
Implicit:
[IntersectionOverride]: public abstract fun foo(): R|kotlin/Int| from Use site scope of /Implicit [id: 0]
[Source]: public abstract override fun foo(): R|kotlin/Any| from Use site scope of /C [id: 1]
[Source]: public abstract fun foo(): R|kotlin/Any| from Use site scope of /A [id: 2]
[Source]: public abstract override fun foo(): R|kotlin/Any| from Use site scope of /B [id: 1]
[Source]: public abstract fun foo(): R|kotlin/Any| from Use site scope of /A [id: 2]
[Source]: public abstract fun foo(): R|kotlin/Int| from Use site scope of /D [id: 3]
[IntersectionOverride]: public abstract override val x: R|kotlin/Any| from Use site scope of /Implicit [id: 0]
[Source]: public abstract override val x: R|kotlin/Any| from Use site scope of /C [id: 1]
[Source]: public abstract val x: R|kotlin/Any| from Use site scope of /A [id: 2]
[Source]: public abstract override val x: R|kotlin/Any| from Use site scope of /B [id: 1]
[Source]: public abstract val x: R|kotlin/Any| from Use site scope of /A [id: 2]
[Source]: public abstract val x: R|kotlin/Any| from Use site scope of /D [id: 3]
@@ -1,6 +1,7 @@
C:
[Source]: public open override fun getName(): R|kotlin/String| from Use site scope of /C [id: 0]
[Enhancement]: public abstract fun getName(): R|kotlin/String!| from Substitution scope for [Java enhancement scope for /B] for type C [id: 1]
[Enhancement]: public abstract fun getName(): R|kotlin/String!| from Java enhancement scope for /A [id: 1]
[Source]: public open override fun setName(newName: R|kotlin/String|): R|kotlin/Any?| from Use site scope of /C [id: 0]
[SubstitutionOverride(DeclarationSite)]: public abstract fun setName(newName: R|kotlin/String!|): R|kotlin/Any!| from Substitution scope for [Java enhancement scope for /B] for type C [id: 1]
[Enhancement]: public abstract fun setName(newName: R|kotlin/String!|): R|ft<T & Any, T?>| from Java enhancement scope for /B [id: 2]
@@ -8,10 +9,13 @@ C:
D:
[Source]: public open override fun getName(): R|kotlin/String| from Java enhancement scope for /D [id: 0]
[Enhancement]: public abstract fun getName(): R|kotlin/String!| from Substitution scope for [Java enhancement scope for /B] for type C [id: 1]
[Source]: public open override fun getName(): R|kotlin/String| from Use site scope of /C [id: 0]
[Enhancement]: public abstract fun getName(): R|kotlin/String!| from Substitution scope for [Java enhancement scope for /B] for type C [id: 1]
[Enhancement]: public abstract fun getName(): R|kotlin/String!| from Java enhancement scope for /A [id: 1]
[Source]: public open override fun setName(newName: R|kotlin/String|): R|kotlin/Any?| from Java enhancement scope for /D [id: 0]
[SubstitutionOverride(DeclarationSite)]: public abstract fun setName(newName: R|kotlin/String!|): R|kotlin/Any!| from Substitution scope for [Java enhancement scope for /B] for type C [id: 1]
[Enhancement]: public abstract fun setName(newName: R|kotlin/String!|): R|ft<T & Any, T?>| from Java enhancement scope for /B [id: 2]
[Source]: public open override fun setName(newName: R|kotlin/String|): R|kotlin/Any?| from Use site scope of /C [id: 0]
[SubstitutionOverride(DeclarationSite)]: public abstract fun setName(newName: R|kotlin/String!|): R|kotlin/Any!| from Substitution scope for [Java enhancement scope for /B] for type C [id: 1]
[Enhancement]: public abstract fun setName(newName: R|kotlin/String!|): R|ft<T & Any, T?>| from Java enhancement scope for /B [id: 2]
[Source]: private final var name: R|kotlin/String| from Java enhancement scope for /D [id: 0]
[Source]: private final var name: R|kotlin/String| from Use site scope of /C [id: 0]
@@ -37,15 +37,16 @@ object FirJsNameClashClassMembersChecker : FirClassChecker() {
private val allSymbols = mutableSetOf<FirCallableSymbol<*>>()
private fun FirTypeScope.collectOverriddenLeaves(classMemberSymbol: FirCallableSymbol<*>): Set<FirCallableSymbol<*>> {
val visitedSymbols = hashSetOf(classMemberSymbol)
val symbolsToProcess = mutableListOf(classMemberSymbol)
val startMemberWithScope = MemberWithBaseScope(classMemberSymbol, this)
val visitedSymbols = hashSetOf(startMemberWithScope)
val symbolsToProcess = mutableListOf(startMemberWithScope)
val leaves = mutableSetOf<FirCallableSymbol<*>>()
while (symbolsToProcess.isNotEmpty()) {
val processingSymbol = symbolsToProcess.popLast()
val overriddenMembers = getDirectOverriddenMembers(processingSymbol, true)
for (overriddenMember in overriddenMembers) {
if (visitedSymbols.add(overriddenMember)) {
symbolsToProcess.add(overriddenMember)
val (processingSymbol, scope) = symbolsToProcess.popLast()
val overriddenMembers = scope.getDirectOverriddenMembersWithBaseScope(processingSymbol)
for (overriddenMemberWithScope in overriddenMembers) {
if (visitedSymbols.add(overriddenMemberWithScope)) {
symbolsToProcess.add(overriddenMemberWithScope)
}
}
if (overriddenMembers.isEmpty()) {
@@ -214,7 +214,7 @@ fun CheckerContext.findClosestClassOrObject(): FirClass? {
fun FirNamedFunctionSymbol.overriddenFunctions(
containingClass: FirClassSymbol<*>,
context: CheckerContext,
): List<FirFunctionSymbol<*>> {
): Collection<FirFunctionSymbol<*>> {
return overriddenFunctions(containingClass, context.session, context.scopeSession)
}
@@ -64,9 +64,9 @@ object FirNotImplementedOverrideChecker : FirClassChecker() {
fun collectSymbol(symbol: FirCallableSymbol<*>) {
val delegatedWrapperData = symbol.delegatedWrapperData
if (delegatedWrapperData != null) {
val directOverriddenMembersWithBaseScope = classScope.getDirectOverriddenMembersWithBaseScope(
symbol
)
val directOverriddenMembersWithBaseScope = classScope
.getDirectOverriddenMembersWithBaseScope(symbol)
.filter { it.member != symbol }
@Suppress("UNCHECKED_CAST")
val filteredOverriddenMembers = when (symbol) {
@@ -46,8 +46,8 @@ import org.jetbrains.kotlin.name.Name
* TODO: generic super interface types and generic delegated members.
*/
class DelegatedMemberGenerator(private val components: Fir2IrComponents) : Fir2IrComponents by components {
private val baseFunctionSymbols: MutableMap<IrFunction, List<FirNamedFunctionSymbol>> = mutableMapOf()
private val basePropertySymbols: MutableMap<IrProperty, List<FirPropertySymbol>> = mutableMapOf()
private val baseFunctionSymbols: MutableMap<IrFunction, Collection<FirNamedFunctionSymbol>> = mutableMapOf()
private val basePropertySymbols: MutableMap<IrProperty, Collection<FirPropertySymbol>> = mutableMapOf()
private data class DeclarationBodyInfo(
val declaration: IrDeclaration,
@@ -231,7 +231,7 @@ class DelegatedMemberGenerator(private val components: Fir2IrComponents) : Fir2I
delegateOverride, subClass, predefinedOrigin = IrDeclarationOrigin.DELEGATED_MEMBER,
fakeOverrideOwnerLookupTag = firSubClass.symbol.toLookupTag()
)
val baseSymbols = mutableListOf<FirNamedFunctionSymbol>()
val baseSymbols = mutableSetOf<FirNamedFunctionSymbol>()
// the overridden symbols should be collected only after all fake overrides for all superclases are created and bound to their
// overridden symbols, otherwise in some cases they will be left in inconsistent state leading to the errors in IR
delegateOverride.processOverriddenFunctionSymbols(firSubClass) {
@@ -364,7 +364,7 @@ class DelegatedMemberGenerator(private val components: Fir2IrComponents) : Fir2I
)
// the overridden symbols should be collected only after all fake overrides for all superclases are created and bound to their
// overridden symbols, otherwise in some cases they will be left in inconsistent state leading to the errors in IR
val baseSymbols = mutableListOf<FirPropertySymbol>()
val baseSymbols = mutableSetOf<FirPropertySymbol>()
firDelegateProperty.processOverriddenPropertySymbols(firSubClass) {
baseSymbols.add(it)
}
@@ -61,7 +61,7 @@ fun FirNamedFunctionSymbol.overriddenFunctions(
containingClass: FirClassSymbol<*>,
session: FirSession,
scopeSession: ScopeSession,
): List<FirFunctionSymbol<*>> {
): Collection<FirFunctionSymbol<*>> {
val firTypeScope = containingClass.unsubstitutedScope(
session,
scopeSession,
@@ -69,12 +69,20 @@ fun FirNamedFunctionSymbol.overriddenFunctions(
memberRequiredPhase = FirResolvePhase.STATUS,
)
val overriddenFunctions = mutableListOf<FirFunctionSymbol<*>>()
val overriddenFunctions = mutableSetOf<FirFunctionSymbol<*>>()
firTypeScope.processFunctionsByName(callableId.callableName) { }
firTypeScope.processOverriddenFunctions(this) {
overriddenFunctions.add(it)
ProcessorAction.NEXT
}
/*
* The original symbol may appear in `processOverriddenFunctions`, so it should be removed from the resulting
* list to not confuse the caller with a situation when the function directly overrides itself
*
* For details see FirTypeScope.processDirectOverriddenFunctionsWithBaseScope
*/
overriddenFunctions -= this
return overriddenFunctions
}
@@ -262,6 +262,14 @@ fun FirTypeScope.getDirectOverriddenFunctions(
ProcessorAction.NEXT
}
/*
* The original symbol may appear in `processOverriddenFunctions`, so it should be removed from the resulting
* list to not confuse the caller with a situation when the function directly overrides itself
*
* For details see FirTypeScope.processDirectOverriddenFunctionsWithBaseScope
*/
overriddenFunctions -= function
return overriddenFunctions.toList()
}
@@ -276,6 +284,11 @@ fun FirTypeScope.getDirectOverriddenProperties(
ProcessorAction.NEXT
}
/*
* See comment in `getDirectOverriddenFunctions` function above
*/
overriddenProperties -= property
return overriddenProperties.toList()
}
@@ -295,7 +308,7 @@ fun FirTypeScope.retrieveDirectOverriddenOf(memberSymbol: FirCallableSymbol<*>):
}
}
private inline fun <reified D : FirCallableSymbol<*>> MutableCollection<D>.addOverridden(
private inline fun <reified D : FirCallableSymbol<*>> MutableSet<D>.addOverridden(
symbol: D,
unwrapIntersectionAndSubstitutionOverride: Boolean
) {
@@ -59,23 +59,29 @@ class FirUnstableSmartcastTypeScope(
return processComposite(FirScope::processPropertiesByName, name, processor)
}
private inline fun <N, T : FirCallableSymbol<*>> processTypedComposite(
process: FirTypeScope.(N, (T, FirTypeScope) -> ProcessorAction) -> ProcessorAction,
name: N,
noinline processor: (T, FirTypeScope) -> ProcessorAction
private inline fun <S : FirCallableSymbol<*>> processDirectOverriddenWithBaseScope(
originalSymbol: S,
processDirectOverriddenSymbolsWithBaseScope: FirTypeScope.(S, (S, FirTypeScope) -> ProcessorAction) -> ProcessorAction,
noinline processor: (S, FirTypeScope) -> ProcessorAction
): ProcessorAction {
val unique = mutableSetOf<T>()
originalScope.process(name) { symbol, firTypeScope ->
val unique = mutableSetOf<S>()
originalScope.processDirectOverriddenSymbolsWithBaseScope(originalSymbol) { symbol, firTypeScope ->
unique += symbol
processor(symbol, firTypeScope)
}.let { if (it == ProcessorAction.STOP) return ProcessorAction.STOP }
smartcastScope.process(name) { symbol, firTypeScope ->
if (symbol !in unique) {
markSymbolFromUnstableSmartcast(symbol)
processor(symbol, firTypeScope)
} else {
ProcessorAction.NEXT
smartcastScope.processDirectOverriddenSymbolsWithBaseScope(originalSymbol) { symbol, firTypeScope ->
when (symbol) {
/**
* `processDirectOverriddenSymbolsWithBaseScope` may return the same symbol from underlying scopes,
* so we need to skip them until we found real overridden
*/
originalSymbol -> ProcessorAction.NEXT
!in unique -> {
markSymbolFromUnstableSmartcast(symbol)
processor(symbol, firTypeScope)
}
else -> ProcessorAction.NEXT
}
}.let { if (it == ProcessorAction.STOP) return ProcessorAction.STOP }
return ProcessorAction.NEXT
@@ -91,14 +97,14 @@ class FirUnstableSmartcastTypeScope(
functionSymbol: FirNamedFunctionSymbol,
processor: (FirNamedFunctionSymbol, FirTypeScope) -> ProcessorAction
): ProcessorAction {
return processTypedComposite(FirTypeScope::processDirectOverriddenFunctionsWithBaseScope, functionSymbol, processor)
return processDirectOverriddenWithBaseScope(functionSymbol, FirTypeScope::processDirectOverriddenFunctionsWithBaseScope, processor)
}
override fun processDirectOverriddenPropertiesWithBaseScope(
propertySymbol: FirPropertySymbol,
processor: (FirPropertySymbol, FirTypeScope) -> ProcessorAction
): ProcessorAction {
return processTypedComposite(FirTypeScope::processDirectOverriddenPropertiesWithBaseScope, propertySymbol, processor)
return processDirectOverriddenWithBaseScope(propertySymbol, FirTypeScope::processDirectOverriddenPropertiesWithBaseScope, processor)
}
override fun getCallableNames(): Set<Name> {