[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
@@ -22,11 +22,13 @@ public abstract class KtSymbolDeclarationOverridesProvider : KtAnalysisSessionCo
public interface KtSymbolDeclarationOverridesProviderMixIn : KtAnalysisSessionMixIn {
/**
* Return a list of **all** symbols which are overridden by symbol
* Return a list of **all** explicitly declared symbols that are overridden by symbol
*
* E.g, if we have `A.foo` overrides `B.foo` overrides `C.foo`, all two super declarations `B.foo`, `C.foo` will be returned
* E.g., if we have `A.foo` overrides `B.foo` overrides `C.foo`, all two super declarations `B.foo`, `C.foo` will be returned
*
* Unwraps substituted overridden symbols (see [org.jetbrains.kotlin.analysis.api.symbols.KtSymbolOrigin.INTERSECTION_OVERRIDE])
* Unwraps substituted overridden symbols
* (see [INTERSECTION_OVERRIDE][org.jetbrains.kotlin.analysis.api.symbols.KtSymbolOrigin.INTERSECTION_OVERRIDE] and [SUBSTITUTION_OVERRIDE][org.jetbrains.kotlin.analysis.api.symbols.KtSymbolOrigin.SUBSTITUTION_OVERRIDE]),
* so such fake declaration won't be returned.
*
* @see getDirectlyOverriddenSymbols
*/
@@ -34,11 +36,13 @@ public interface KtSymbolDeclarationOverridesProviderMixIn : KtAnalysisSessionMi
withValidityAssertion { analysisSession.symbolDeclarationOverridesProvider.getAllOverriddenSymbols(this) }
/**
* Return a list of symbols which are **directly** overridden by symbol
* Return a list of explicitly declared symbols which are **directly** overridden by symbol
**
* E.g, if we have `A.foo` overrides `B.foo` overrides `C.foo`, only declarations directly overridden `B.foo` will be returned
* E.g., if we have `A.foo` overrides `B.foo` overrides `C.foo`, only declarations directly overridden `B.foo` will be returned
*
* Unwraps substituted overridden symbols (see [org.jetbrains.kotlin.analysis.api.symbols.KtSymbolOrigin.INTERSECTION_OVERRIDE])
* Unwraps substituted overridden symbols
* (see [INTERSECTION_OVERRIDE][org.jetbrains.kotlin.analysis.api.symbols.KtSymbolOrigin.INTERSECTION_OVERRIDE] and [SUBSTITUTION_OVERRIDE][org.jetbrains.kotlin.analysis.api.symbols.KtSymbolOrigin.SUBSTITUTION_OVERRIDE]),
* so such fake declaration won't be returned.
*
* @see getAllOverriddenSymbols
*/
@@ -2,14 +2,3 @@ class MyList : ArrayList<Int>() {
override val size<caret>: Int = 0
override fun get(index: Int): Int = 0
}
// RESULT
// ALL:
// java/util/ArrayList.size: Int
// java/util/AbstractList.size: Int
// java/util/AbstractCollection.size: Int
// List.size: Int
// Collection.size: Int
// DIRECT:
// java/util/ArrayList.size: Int
@@ -1,6 +1,5 @@
ALL:
java/util/ArrayList.size: Int
java/util/AbstractList.size: Int
java/util/AbstractCollection.size: Int
kotlin/collections/List.size: Int
kotlin/collections/Collection.size: Int
@@ -1,6 +1,5 @@
ALL:
java/util/ArrayList.size: Int
java/util/AbstractList.size: Int
java/util/AbstractCollection.size: Int
List.size: Int
Collection.size: Int
@@ -1,4 +1,3 @@
// IGNORE_FIR
class MyClass {
lateinit var d: IntermediateClass<Int>
val prop = object : IntermediateClass<Int> by d {
@@ -1,4 +0,0 @@
ALL:
BaseClass.isSchemeFile(name: CharSequence): Boolean
DIRECT:
BaseClass.isSchemeFile(name: CharSequence): Boolean
@@ -1,5 +1,4 @@
ALL:
BaseClass.isSchemeFile(name: CharSequence): Boolean
BaseClass.isSchemeFile(name: CharSequence): Boolean
DIRECT:
BaseClass.isSchemeFile(name: CharSequence): Boolean
@@ -1,2 +1,5 @@
ALL:
C.foo(x: T): Unit
D.foo(x: F): Unit
DIRECT:
C.foo(x: T): Unit
@@ -1,8 +1,5 @@
ALL:
C.foo(x: String): Unit
C.foo(x: T): Unit
D.foo(x: T): Unit
C.foo(x: T): Unit
D.foo(x: F): Unit
DIRECT:
C.foo(x: String): Unit
C.foo(x: T): Unit
@@ -1,4 +0,0 @@
ALL:
LazySchemeProcessor.isSchemeFile(name: CharSequence): Boolean
DIRECT:
LazySchemeProcessor.isSchemeFile(name: CharSequence): Boolean
@@ -1,5 +1,4 @@
ALL:
LazySchemeProcessor.isSchemeFile(name: CharSequence): Boolean
LazySchemeProcessor.isSchemeFile(name: CharSequence): Boolean
DIRECT:
LazySchemeProcessor.isSchemeFile(name: CharSequence): Boolean
LazySchemeProcessor.isSchemeFile(name: CharSequence): Boolean