[FIR] Process all overridden members from intersection scopes
Previously, there was a contract that each callable symbol in the chain of `processDirectOverriddenWithBaseScope` will be unique. And if some symbol is accessible from multiple scopes, then only last of them will be returned as a component of `MemberWithScope` But after the change from previous commit, we don't have this contract anymore. Which means that we may meet the same symbol during processing hierarchy of overridden functions (but with different base scopes) So if some code utilizes `process...Overridden...WithBaseScope` functions it should consider that the same symbol may be obtained several times ^KT-63738 Fixed
This commit is contained in:
committed by
Space Team
parent
c34511af37
commit
4272f2e156
Vendored
+8
-3
@@ -1,6 +1,11 @@
|
||||
D:
|
||||
[SubstitutionOverride(DeclarationSite)]: public abstract override fun foo(): R|E4| from Use site scope of /D [id: 0]
|
||||
[Source]: public abstract override fun foo(): R|E2| from Use site scope of /B [id: 1]
|
||||
[SubstitutionOverride(DeclarationSite)]: public abstract fun foo(): R|E2| from Substitution scope for [Use site scope of /A] for type B<E2> [id: 2]
|
||||
[Source]: public abstract fun foo(): R|E1| from Use site scope of /A [id: 3]
|
||||
[SubstitutionOverride(DeclarationSite)]: public abstract override fun foo(): R|E4| from Substitution scope for [Use site scope of /B] for type D<E4> [id: 0]
|
||||
[Source]: public abstract override fun foo(): R|E2| from Use site scope of /B [id: 1]
|
||||
[SubstitutionOverride(DeclarationSite)]: public abstract fun foo(): R|E2| from Substitution scope for [Use site scope of /A] for type B<E2> [id: 2]
|
||||
[Source]: public abstract fun foo(): R|E1| from Use site scope of /A [id: 3]
|
||||
[SubstitutionOverride(DeclarationSite)]: public abstract fun foo(): R|E4| from Substitution scope for [Use site scope of /C] for type D<E4> [id: 4]
|
||||
[SubstitutionOverride(DeclarationSite)]: public abstract fun foo(): R|E3| from Use site scope of /C [id: 5]
|
||||
[SubstitutionOverride(DeclarationSite)]: public abstract fun foo(): R|E3| from Substitution scope for [Use site scope of /A] for type C<E3> [id: 5]
|
||||
[Source]: public abstract fun foo(): R|E1| from Use site scope of /A [id: 3]
|
||||
|
||||
|
||||
+1
@@ -11,6 +11,7 @@ Some:
|
||||
[Library]: public abstract fun toInt(): R|kotlin/Int| from Use site scope of kotlin/Number [id: 1]
|
||||
[RenamedForOverride]: public abstract fun toInt(): R|kotlin/Int| from Java enhancement scope for /MyNumber [id: 2]
|
||||
[Library]: public abstract fun toLong(): R|kotlin/Long| from Java enhancement scope for /Some [id: 0]
|
||||
[Library]: public abstract fun toLong(): R|kotlin/Long| from Use site scope of kotlin/Number [id: 0]
|
||||
|
||||
MyNumber:
|
||||
[Enhancement]: public abstract fun byteValue(): R|kotlin/Byte| from Java enhancement scope for /MyNumber [id: 0]
|
||||
|
||||
+8
-4
@@ -2,7 +2,8 @@ SomeMap:
|
||||
[Enhancement]: public abstract fun containsKey(key: R|ft<K3 & Any, K3?>|): R|kotlin/Boolean| from Java enhancement scope for /SomeMap [id: 0]
|
||||
[SubstitutionOverride(DeclarationSite)]: public abstract fun containsKey(key: R|ft<K3 & Any, K3?>|): R|kotlin/Boolean| from Substitution scope for [Use site scope of kotlin/collections/MutableMap] for type SomeMap<K3, V3> [id: 1]
|
||||
[SubstitutionOverride(DeclarationSite)]: public abstract fun containsKey(key: R|K|): R|kotlin/Boolean| from Use site scope of kotlin/collections/MutableMap [id: 2]
|
||||
[Library]: public abstract fun containsKey(key: R|K|): R|kotlin/Boolean| from Use site scope of kotlin/collections/Map [id: 3]
|
||||
[SubstitutionOverride(DeclarationSite)]: public abstract fun containsKey(key: R|K|): R|kotlin/Boolean| from Substitution scope for [Use site scope of kotlin/collections/Map] for type kotlin/collections/MutableMap<K, V> [id: 2]
|
||||
[Library]: public abstract fun containsKey(key: R|K|): R|kotlin/Boolean| from Use site scope of kotlin/collections/Map [id: 3]
|
||||
[SubstitutionOverride(DeclarationSite)]: public abstract fun containsKey(key: R|kotlin/Any!|): R|kotlin/Boolean| from Substitution scope for [Java enhancement scope for /MyMap] for type SomeMap<K3, V3> [id: 4]
|
||||
[Enhancement]: public abstract fun containsKey(key: R|kotlin/Any!|): R|kotlin/Boolean| from Java enhancement scope for /MyMap [id: 5]
|
||||
[SubstitutionOverride(DeclarationSite)]: public abstract fun containsKey(key: R|kotlin/Any!|): R|kotlin/Boolean| from Substitution scope for [Java enhancement scope for /MyBaseMap] for type MyMap<K2, V2> [id: 6]
|
||||
@@ -10,20 +11,23 @@ SomeMap:
|
||||
[IntersectionOverride]: public abstract fun containsValue(value: R|ft<V3 & Any, V3?>|): R|kotlin/Boolean| from Java enhancement scope for /SomeMap [id: 0]
|
||||
[SubstitutionOverride(DeclarationSite)]: public abstract fun containsValue(value: R|ft<V3 & Any, V3?>|): R|kotlin/Boolean| from Substitution scope for [Use site scope of kotlin/collections/MutableMap] for type SomeMap<K3, V3> [id: 1]
|
||||
[SubstitutionOverride(DeclarationSite)]: public abstract fun containsValue(value: R|V|): R|kotlin/Boolean| from Use site scope of kotlin/collections/MutableMap [id: 2]
|
||||
[Library]: public abstract fun containsValue(value: R|V|): R|kotlin/Boolean| from Use site scope of kotlin/collections/Map [id: 3]
|
||||
[SubstitutionOverride(DeclarationSite)]: public abstract fun containsValue(value: R|V|): R|kotlin/Boolean| from Substitution scope for [Use site scope of kotlin/collections/Map] for type kotlin/collections/MutableMap<K, V> [id: 2]
|
||||
[Library]: public abstract fun containsValue(value: R|V|): R|kotlin/Boolean| from Use site scope of kotlin/collections/Map [id: 3]
|
||||
[SubstitutionOverride(DeclarationSite)]: public abstract fun containsValue(key: R|kotlin/Any!|): R|kotlin/Boolean| from Substitution scope for [Java enhancement scope for /MyMap] for type SomeMap<K3, V3> [id: 4]
|
||||
[Enhancement]: public abstract fun containsValue(key: R|kotlin/Any!|): R|kotlin/Boolean| from Java enhancement scope for /MyMap [id: 5]
|
||||
[IntersectionOverride]: public abstract operator fun get(key: R|ft<K3 & Any, K3?>|): R|V3?| from Java enhancement scope for /SomeMap [id: 0]
|
||||
[SubstitutionOverride(DeclarationSite)]: public abstract operator fun get(key: R|ft<K3 & Any, K3?>|): R|V3?| from Substitution scope for [Use site scope of kotlin/collections/MutableMap] for type SomeMap<K3, V3> [id: 1]
|
||||
[SubstitutionOverride(DeclarationSite)]: public abstract operator fun get(key: R|K|): R|V?| from Use site scope of kotlin/collections/MutableMap [id: 2]
|
||||
[Library]: public abstract operator fun get(key: R|K|): R|V?| from Use site scope of kotlin/collections/Map [id: 3]
|
||||
[SubstitutionOverride(DeclarationSite)]: public abstract operator fun get(key: R|K|): R|V?| from Substitution scope for [Use site scope of kotlin/collections/Map] for type kotlin/collections/MutableMap<K, V> [id: 2]
|
||||
[Library]: public abstract operator fun get(key: R|K|): R|V?| from Use site scope of kotlin/collections/Map [id: 3]
|
||||
[SubstitutionOverride(DeclarationSite)]: public abstract operator fun get(key: R|ft<K3 & Any, K3?>|): R|ft<V3 & Any, V3?>| from Substitution scope for [Java enhancement scope for /MyMap] for type SomeMap<K3, V3> [id: 4]
|
||||
[Enhancement]: public abstract operator fun get(key: R|ft<K2 & Any, K2?>|): R|ft<V2 & Any, V2?>| from Java enhancement scope for /MyMap [id: 5]
|
||||
[Enhancement]: public abstract fun remove(key: R|ft<K3 & Any, K3?>|): R|V3?| from Java enhancement scope for /SomeMap [id: 0]
|
||||
[SubstitutionOverride(DeclarationSite)]: public abstract fun remove(key: R|ft<K3 & Any, K3?>|): R|V3?| from Substitution scope for [Use site scope of kotlin/collections/MutableMap] for type SomeMap<K3, V3> [id: 1]
|
||||
[Library]: public abstract fun remove(key: R|K|): R|V?| from Use site scope of kotlin/collections/MutableMap [id: 2]
|
||||
[SubstitutionOverride(DeclarationSite)]: public open fun remove(key: R|ft<K3 & Any, K3?>|, value: R|ft<V3 & Any, V3?>|): R|kotlin/Boolean| from Java enhancement scope for /SomeMap [id: 0]
|
||||
[Library]: public open fun remove(key: R|K|, value: R|V|): R|kotlin/Boolean| from Use site scope of kotlin/collections/MutableMap [id: 1]
|
||||
[SubstitutionOverride(DeclarationSite)]: public open fun remove(key: R|ft<K3 & Any, K3?>|, value: R|ft<V3 & Any, V3?>|): R|kotlin/Boolean| from Substitution scope for [Use site scope of kotlin/collections/MutableMap] for type SomeMap<K3, V3> [id: 0]
|
||||
[Library]: public open fun remove(key: R|K|, value: R|V|): R|kotlin/Boolean| from Use site scope of kotlin/collections/MutableMap [id: 1]
|
||||
|
||||
MyMap:
|
||||
[Enhancement]: public abstract fun containsKey(key: R|kotlin/Any!|): R|kotlin/Boolean| from Java enhancement scope for /MyMap [id: 0]
|
||||
|
||||
+6
-15
@@ -148,8 +148,7 @@ abstract class AbstractFirUseSiteMemberScope(
|
||||
directOverriddenFunctions,
|
||||
functionsFromSupertypes,
|
||||
functionSymbol,
|
||||
processor,
|
||||
FirTypeScope::processDirectOverriddenFunctionsWithBaseScope
|
||||
processor
|
||||
)
|
||||
}
|
||||
|
||||
@@ -161,8 +160,7 @@ abstract class AbstractFirUseSiteMemberScope(
|
||||
directOverriddenProperties,
|
||||
propertiesFromSupertypes,
|
||||
propertySymbol,
|
||||
processor,
|
||||
FirTypeScope::processDirectOverriddenPropertiesWithBaseScope
|
||||
processor
|
||||
)
|
||||
}
|
||||
|
||||
@@ -170,24 +168,17 @@ abstract class AbstractFirUseSiteMemberScope(
|
||||
directOverriddenMap: Map<D, List<ResultOfIntersection<D>>>,
|
||||
callablesFromSupertypes: Map<Name, List<ResultOfIntersection<D>>>,
|
||||
callableSymbol: D,
|
||||
processor: (D, FirTypeScope) -> ProcessorAction,
|
||||
processDirectOverriddenCallables: FirTypeScope.(D, (D, FirTypeScope) -> ProcessorAction) -> ProcessorAction
|
||||
processor: (D, FirTypeScope) -> ProcessorAction
|
||||
): ProcessorAction {
|
||||
when (val directOverridden = directOverriddenMap[callableSymbol]) {
|
||||
null -> {
|
||||
val resultOfIntersection = callablesFromSupertypes[callableSymbol.name]
|
||||
?.firstOrNull { it.chosenSymbol == callableSymbol }
|
||||
?: return ProcessorAction.NONE
|
||||
if (resultOfIntersection.isIntersectionOverride()) {
|
||||
for ((overridden, baseScope) in resultOfIntersection.overriddenMembers) {
|
||||
if (!processor(overridden, baseScope)) return ProcessorAction.STOP
|
||||
}
|
||||
return ProcessorAction.NONE
|
||||
} else {
|
||||
return resultOfIntersection.containingScope
|
||||
?.processDirectOverriddenCallables(callableSymbol, processor)
|
||||
?: ProcessorAction.NONE
|
||||
for ((overridden, baseScope) in resultOfIntersection.overriddenMembers) {
|
||||
if (!processor(overridden, baseScope)) return ProcessorAction.STOP
|
||||
}
|
||||
return ProcessorAction.NONE
|
||||
}
|
||||
else -> {
|
||||
for (resultOfIntersection in directOverridden) {
|
||||
|
||||
@@ -27,8 +27,8 @@ abstract class FirTypeScope : FirContainingNamesAwareScope() {
|
||||
// Then, for B::foo from scope for B one may receive override A::foo and scope for A
|
||||
//
|
||||
// Currently, this function and its property brother both have very weak guarantees
|
||||
// - It may silently do nothing on symbols originated from different scope instance
|
||||
// - It may return the same overridden symbols more then once in case of substitution
|
||||
// - It may return the same overridden symbols more than once in case of substitution or intersection
|
||||
// (but with different base scope)
|
||||
abstract fun processDirectOverriddenFunctionsWithBaseScope(
|
||||
functionSymbol: FirNamedFunctionSymbol,
|
||||
processor: (FirNamedFunctionSymbol, FirTypeScope) -> ProcessorAction
|
||||
|
||||
Vendored
-2
@@ -1,7 +1,5 @@
|
||||
// ISSUE: KT-55828
|
||||
// DUMP_IR
|
||||
// IGNORE_BACKEND_K2: ANY
|
||||
// Ignore reason: FIR scopes skip part of overridden hierarchy. It will fixed in next commits
|
||||
// IGNORE_CODEGEN_WITH_IR_FAKE_OVERRIDE_GENERATION: extra overridden symbols for declarations in MyMutableList.
|
||||
// ^ This is most likely not a problem, and IR dump can be changed once IR fake override generation is enabled by default.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user