FIR IDE: resolve reference to intersection override member to overridden members
This commit is contained in:
@@ -58,6 +58,9 @@ abstract class KtAnalysisSession(final override val token: ValidityToken) : Vali
|
||||
fun KtCallableSymbol.getOverriddenSymbols(containingDeclaration: KtClassOrObjectSymbol): List<KtCallableSymbol> =
|
||||
symbolDeclarationOverridesProvider.getOverriddenSymbols(this, containingDeclaration)
|
||||
|
||||
fun KtCallableSymbol.getIntersectionOverriddenSymbols(): Collection<KtCallableSymbol> =
|
||||
symbolDeclarationOverridesProvider.getIntersectionOverriddenSymbols(this)
|
||||
|
||||
fun KtExpression.getSmartCasts(): Collection<KtType> = smartCastProvider.getSmartCastedToTypes(this)
|
||||
|
||||
fun KtExpression.getImplicitReceiverSmartCasts(): Collection<ImplicitReceiverSmartCast> =
|
||||
|
||||
+5
-2
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.idea.frontend.api.components
|
||||
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassOrObjectSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
|
||||
|
||||
abstract class KtSymbolDeclarationOverridesProvider : KtAnalysisSessionComponent() {
|
||||
@@ -19,5 +18,9 @@ abstract class KtSymbolDeclarationOverridesProvider : KtAnalysisSessionComponent
|
||||
containingDeclaration: KtClassOrObjectSymbol
|
||||
): List<KtCallableSymbol>
|
||||
|
||||
//abstract fun getOverriddenSymbols(callableSymbol: KtCallableSymbol, containingDeclaration: KtClassOrObjectSymbol): List<KtCallableSymbol>
|
||||
/**
|
||||
* If [symbol] origin is [org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolOrigin.INTERSECTION_OVERRIDE]
|
||||
* Then returns the symbols which [symbol] overrides, otherwise empty collection
|
||||
*/
|
||||
abstract fun getIntersectionOverriddenSymbols(symbol: KtCallableSymbol): Collection<KtCallableSymbol>
|
||||
}
|
||||
+13
-1
@@ -42,5 +42,17 @@ enum class KtSymbolOrigin {
|
||||
*/
|
||||
JAVA,
|
||||
|
||||
SAM_CONSTRUCTOR
|
||||
SAM_CONSTRUCTOR,
|
||||
|
||||
/**
|
||||
* Consider the following code:
|
||||
* ```
|
||||
* interface A { fun x() }
|
||||
* interface B { fun x() }
|
||||
*
|
||||
* interface C : A, B
|
||||
* ```
|
||||
* The intersection of functions A.foo & B.foo will create a function C.foo which will be marked with [INTERSECTION_OVERRIDE]
|
||||
*/
|
||||
INTERSECTION_OVERRIDE,
|
||||
}
|
||||
+1
@@ -26,6 +26,7 @@ internal class KtFirSymbolContainingDeclarationProvider(
|
||||
KtSymbolOrigin.SOURCE, KtSymbolOrigin.SOURCE_MEMBER_GENERATED ->
|
||||
getContainingDeclarationForKotlinInSourceSymbol(symbol)
|
||||
KtSymbolOrigin.LIBRARY, KtSymbolOrigin.JAVA -> getContainingDeclarationForLibrarySymbol(symbol)
|
||||
KtSymbolOrigin.INTERSECTION_OVERRIDE -> TODO()
|
||||
KtSymbolOrigin.SAM_CONSTRUCTOR -> TODO()
|
||||
}
|
||||
}
|
||||
|
||||
+26
@@ -5,9 +5,15 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.frontend.api.fir.components
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSymbolOwner
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.scopes.*
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirIntersectionOverrideFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirIntersectionOverridePropertySymbol
|
||||
import org.jetbrains.kotlin.fir.unwrapFakeOverrides
|
||||
import org.jetbrains.kotlin.idea.frontend.api.ValidityToken
|
||||
import org.jetbrains.kotlin.idea.frontend.api.components.KtSymbolDeclarationOverridesProvider
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession
|
||||
@@ -63,4 +69,24 @@ internal class KtFirSymbolDeclarationOverridesProvider(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getIntersectionOverriddenSymbols(symbol: KtCallableSymbol): Collection<KtCallableSymbol> {
|
||||
require(symbol is KtFirSymbol<*>)
|
||||
if (symbol.origin != KtSymbolOrigin.INTERSECTION_OVERRIDE) return emptyList()
|
||||
return symbol.firRef.withFir { fir ->
|
||||
val firSymbol = (fir as? FirSymbolOwner<*>)?.symbol ?: return@withFir emptyList()
|
||||
firSymbol.getIntersectionOverriddenSymbols().map { analysisSession.firSymbolBuilder.buildCallableSymbol(it.fir) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun AbstractFirBasedSymbol<*>.getIntersectionOverriddenSymbols(): Collection<FirCallableSymbol<*>> {
|
||||
require(this is FirCallableSymbol<*>) {
|
||||
"Required FirCallableSymbol but ${this::class} found"
|
||||
}
|
||||
return when (this) {
|
||||
is FirIntersectionOverrideFunctionSymbol -> intersections
|
||||
is FirIntersectionOverridePropertySymbol -> intersections
|
||||
else -> listOf(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -35,6 +35,7 @@ private tailrec fun FirDeclaration.ktSymbolOrigin(): KtSymbolOrigin = when (orig
|
||||
FirDeclarationOrigin.Java -> KtSymbolOrigin.JAVA
|
||||
FirDeclarationOrigin.SamConstructor -> KtSymbolOrigin.SAM_CONSTRUCTOR
|
||||
FirDeclarationOrigin.Enhancement -> KtSymbolOrigin.JAVA
|
||||
FirDeclarationOrigin.IntersectionOverride -> KtSymbolOrigin.INTERSECTION_OVERRIDE
|
||||
else -> {
|
||||
val overridden = (this as? FirCallableDeclaration<*>)?.originalIfFakeOverride()
|
||||
?: throw InvalidFirDeclarationOriginForSymbol(this)
|
||||
|
||||
@@ -10,14 +10,32 @@ import org.jetbrains.kotlin.idea.fir.findReferencePsi
|
||||
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.idea.frontend.api.KtSymbolBasedReference
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolOrigin
|
||||
|
||||
interface KtFirReference : KtReference, KtSymbolBasedReference {
|
||||
fun getResolvedToPsi(analysisSession: KtAnalysisSession): Collection<PsiElement> =
|
||||
analysisSession.resolveToSymbols().mapNotNull { symbol ->
|
||||
(symbol as? KtFirSymbol<*>)?.firRef?.withFir { it.findReferencePsi() }
|
||||
?: symbol.psi
|
||||
fun getResolvedToPsi(analysisSession: KtAnalysisSession): Collection<PsiElement> = with(analysisSession) {
|
||||
resolveToSymbols().flatMap { symbol ->
|
||||
when (symbol) {
|
||||
is KtFirSymbol<*> -> getPsiDeclarations(symbol)
|
||||
else -> listOfNotNull(symbol.psi)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun KtAnalysisSession.getPsiDeclarations(symbol: KtFirSymbol<*>): Collection<PsiElement> {
|
||||
val intersectionOverriddenSymbolsOrSingle = when {
|
||||
symbol.origin == KtSymbolOrigin.INTERSECTION_OVERRIDE && symbol is KtCallableSymbol -> symbol.getIntersectionOverriddenSymbols()
|
||||
else -> listOf(symbol)
|
||||
}
|
||||
return intersectionOverriddenSymbolsOrSingle.mapNotNull { it.findPsiForReferenceResolve() }
|
||||
}
|
||||
|
||||
private fun KtSymbol.findPsiForReferenceResolve(): PsiElement? {
|
||||
require(this is KtFirSymbol<*>)
|
||||
return firRef.withFir { it.findReferencePsi() }
|
||||
}
|
||||
|
||||
override val resolver get() = KtFirReferenceResolver
|
||||
}
|
||||
@@ -1233,7 +1233,7 @@ KtFirFunctionSymbol:
|
||||
isSuspend: false
|
||||
modality: OPEN
|
||||
name: equals
|
||||
origin: LIBRARY
|
||||
origin: INTERSECTION_OVERRIDE
|
||||
receiverType: null
|
||||
symbolKind: MEMBER
|
||||
typeParameters: []
|
||||
@@ -1254,7 +1254,7 @@ KtFirFunctionSymbol:
|
||||
isSuspend: false
|
||||
modality: OPEN
|
||||
name: hashCode
|
||||
origin: LIBRARY
|
||||
origin: INTERSECTION_OVERRIDE
|
||||
receiverType: null
|
||||
symbolKind: MEMBER
|
||||
typeParameters: []
|
||||
@@ -1275,7 +1275,7 @@ KtFirFunctionSymbol:
|
||||
isSuspend: false
|
||||
modality: OPEN
|
||||
name: toString
|
||||
origin: LIBRARY
|
||||
origin: INTERSECTION_OVERRIDE
|
||||
receiverType: null
|
||||
symbolKind: MEMBER
|
||||
typeParameters: []
|
||||
|
||||
@@ -288,7 +288,7 @@ KtFirFunctionSymbol:
|
||||
isSuspend: false
|
||||
modality: ABSTRACT
|
||||
name: contains
|
||||
origin: LIBRARY
|
||||
origin: INTERSECTION_OVERRIDE
|
||||
receiverType: null
|
||||
symbolKind: MEMBER
|
||||
typeParameters: []
|
||||
@@ -309,7 +309,7 @@ KtFirFunctionSymbol:
|
||||
isSuspend: false
|
||||
modality: ABSTRACT
|
||||
name: containsAll
|
||||
origin: LIBRARY
|
||||
origin: INTERSECTION_OVERRIDE
|
||||
receiverType: null
|
||||
symbolKind: MEMBER
|
||||
typeParameters: []
|
||||
@@ -372,7 +372,7 @@ KtFirFunctionSymbol:
|
||||
isSuspend: false
|
||||
modality: ABSTRACT
|
||||
name: isEmpty
|
||||
origin: LIBRARY
|
||||
origin: INTERSECTION_OVERRIDE
|
||||
receiverType: null
|
||||
symbolKind: MEMBER
|
||||
typeParameters: []
|
||||
@@ -393,7 +393,7 @@ KtFirFunctionSymbol:
|
||||
isSuspend: false
|
||||
modality: ABSTRACT
|
||||
name: iterator
|
||||
origin: LIBRARY
|
||||
origin: INTERSECTION_OVERRIDE
|
||||
receiverType: null
|
||||
symbolKind: MEMBER
|
||||
typeParameters: []
|
||||
@@ -439,7 +439,7 @@ KtFirKotlinPropertySymbol:
|
||||
isVal: true
|
||||
modality: ABSTRACT
|
||||
name: size
|
||||
origin: LIBRARY
|
||||
origin: INTERSECTION_OVERRIDE
|
||||
receiverType: null
|
||||
setter: null
|
||||
symbolKind: MEMBER
|
||||
@@ -459,7 +459,7 @@ KtFirFunctionSymbol:
|
||||
isSuspend: false
|
||||
modality: OPEN
|
||||
name: equals
|
||||
origin: LIBRARY
|
||||
origin: INTERSECTION_OVERRIDE
|
||||
receiverType: null
|
||||
symbolKind: MEMBER
|
||||
typeParameters: []
|
||||
@@ -480,7 +480,7 @@ KtFirFunctionSymbol:
|
||||
isSuspend: false
|
||||
modality: OPEN
|
||||
name: hashCode
|
||||
origin: LIBRARY
|
||||
origin: INTERSECTION_OVERRIDE
|
||||
receiverType: null
|
||||
symbolKind: MEMBER
|
||||
typeParameters: []
|
||||
@@ -501,7 +501,7 @@ KtFirFunctionSymbol:
|
||||
isSuspend: false
|
||||
modality: OPEN
|
||||
name: toString
|
||||
origin: LIBRARY
|
||||
origin: INTERSECTION_OVERRIDE
|
||||
receiverType: null
|
||||
symbolKind: MEMBER
|
||||
typeParameters: []
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// IGNORE_FIR
|
||||
|
||||
interface A {
|
||||
fun foo()
|
||||
}
|
||||
|
||||
Vendored
-2
@@ -1,5 +1,3 @@
|
||||
// IGNORE_FIR
|
||||
|
||||
var x : Int <caret>by Baz()
|
||||
|
||||
interface Foo {
|
||||
|
||||
Reference in New Issue
Block a user