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> =
|
fun KtCallableSymbol.getOverriddenSymbols(containingDeclaration: KtClassOrObjectSymbol): List<KtCallableSymbol> =
|
||||||
symbolDeclarationOverridesProvider.getOverriddenSymbols(this, containingDeclaration)
|
symbolDeclarationOverridesProvider.getOverriddenSymbols(this, containingDeclaration)
|
||||||
|
|
||||||
|
fun KtCallableSymbol.getIntersectionOverriddenSymbols(): Collection<KtCallableSymbol> =
|
||||||
|
symbolDeclarationOverridesProvider.getIntersectionOverriddenSymbols(this)
|
||||||
|
|
||||||
fun KtExpression.getSmartCasts(): Collection<KtType> = smartCastProvider.getSmartCastedToTypes(this)
|
fun KtExpression.getSmartCasts(): Collection<KtType> = smartCastProvider.getSmartCastedToTypes(this)
|
||||||
|
|
||||||
fun KtExpression.getImplicitReceiverSmartCasts(): Collection<ImplicitReceiverSmartCast> =
|
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.KtCallableSymbol
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassOrObjectSymbol
|
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
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
|
||||||
|
|
||||||
abstract class KtSymbolDeclarationOverridesProvider : KtAnalysisSessionComponent() {
|
abstract class KtSymbolDeclarationOverridesProvider : KtAnalysisSessionComponent() {
|
||||||
@@ -19,5 +18,9 @@ abstract class KtSymbolDeclarationOverridesProvider : KtAnalysisSessionComponent
|
|||||||
containingDeclaration: KtClassOrObjectSymbol
|
containingDeclaration: KtClassOrObjectSymbol
|
||||||
): List<KtCallableSymbol>
|
): 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,
|
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 ->
|
KtSymbolOrigin.SOURCE, KtSymbolOrigin.SOURCE_MEMBER_GENERATED ->
|
||||||
getContainingDeclarationForKotlinInSourceSymbol(symbol)
|
getContainingDeclarationForKotlinInSourceSymbol(symbol)
|
||||||
KtSymbolOrigin.LIBRARY, KtSymbolOrigin.JAVA -> getContainingDeclarationForLibrarySymbol(symbol)
|
KtSymbolOrigin.LIBRARY, KtSymbolOrigin.JAVA -> getContainingDeclarationForLibrarySymbol(symbol)
|
||||||
|
KtSymbolOrigin.INTERSECTION_OVERRIDE -> TODO()
|
||||||
KtSymbolOrigin.SAM_CONSTRUCTOR -> TODO()
|
KtSymbolOrigin.SAM_CONSTRUCTOR -> TODO()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+26
@@ -5,9 +5,15 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.frontend.api.fir.components
|
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.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||||
import org.jetbrains.kotlin.fir.scopes.*
|
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.ValidityToken
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.components.KtSymbolDeclarationOverridesProvider
|
import org.jetbrains.kotlin.idea.frontend.api.components.KtSymbolDeclarationOverridesProvider
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession
|
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.Java -> KtSymbolOrigin.JAVA
|
||||||
FirDeclarationOrigin.SamConstructor -> KtSymbolOrigin.SAM_CONSTRUCTOR
|
FirDeclarationOrigin.SamConstructor -> KtSymbolOrigin.SAM_CONSTRUCTOR
|
||||||
FirDeclarationOrigin.Enhancement -> KtSymbolOrigin.JAVA
|
FirDeclarationOrigin.Enhancement -> KtSymbolOrigin.JAVA
|
||||||
|
FirDeclarationOrigin.IntersectionOverride -> KtSymbolOrigin.INTERSECTION_OVERRIDE
|
||||||
else -> {
|
else -> {
|
||||||
val overridden = (this as? FirCallableDeclaration<*>)?.originalIfFakeOverride()
|
val overridden = (this as? FirCallableDeclaration<*>)?.originalIfFakeOverride()
|
||||||
?: throw InvalidFirDeclarationOriginForSymbol(this)
|
?: 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.KtAnalysisSession
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.KtSymbolBasedReference
|
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.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.KtSymbol
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolOrigin
|
||||||
|
|
||||||
interface KtFirReference : KtReference, KtSymbolBasedReference {
|
interface KtFirReference : KtReference, KtSymbolBasedReference {
|
||||||
fun getResolvedToPsi(analysisSession: KtAnalysisSession): Collection<PsiElement> =
|
fun getResolvedToPsi(analysisSession: KtAnalysisSession): Collection<PsiElement> = with(analysisSession) {
|
||||||
analysisSession.resolveToSymbols().mapNotNull { symbol ->
|
resolveToSymbols().flatMap { symbol ->
|
||||||
(symbol as? KtFirSymbol<*>)?.firRef?.withFir { it.findReferencePsi() }
|
when (symbol) {
|
||||||
?: symbol.psi
|
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
|
override val resolver get() = KtFirReferenceResolver
|
||||||
}
|
}
|
||||||
@@ -1233,7 +1233,7 @@ KtFirFunctionSymbol:
|
|||||||
isSuspend: false
|
isSuspend: false
|
||||||
modality: OPEN
|
modality: OPEN
|
||||||
name: equals
|
name: equals
|
||||||
origin: LIBRARY
|
origin: INTERSECTION_OVERRIDE
|
||||||
receiverType: null
|
receiverType: null
|
||||||
symbolKind: MEMBER
|
symbolKind: MEMBER
|
||||||
typeParameters: []
|
typeParameters: []
|
||||||
@@ -1254,7 +1254,7 @@ KtFirFunctionSymbol:
|
|||||||
isSuspend: false
|
isSuspend: false
|
||||||
modality: OPEN
|
modality: OPEN
|
||||||
name: hashCode
|
name: hashCode
|
||||||
origin: LIBRARY
|
origin: INTERSECTION_OVERRIDE
|
||||||
receiverType: null
|
receiverType: null
|
||||||
symbolKind: MEMBER
|
symbolKind: MEMBER
|
||||||
typeParameters: []
|
typeParameters: []
|
||||||
@@ -1275,7 +1275,7 @@ KtFirFunctionSymbol:
|
|||||||
isSuspend: false
|
isSuspend: false
|
||||||
modality: OPEN
|
modality: OPEN
|
||||||
name: toString
|
name: toString
|
||||||
origin: LIBRARY
|
origin: INTERSECTION_OVERRIDE
|
||||||
receiverType: null
|
receiverType: null
|
||||||
symbolKind: MEMBER
|
symbolKind: MEMBER
|
||||||
typeParameters: []
|
typeParameters: []
|
||||||
|
|||||||
@@ -288,7 +288,7 @@ KtFirFunctionSymbol:
|
|||||||
isSuspend: false
|
isSuspend: false
|
||||||
modality: ABSTRACT
|
modality: ABSTRACT
|
||||||
name: contains
|
name: contains
|
||||||
origin: LIBRARY
|
origin: INTERSECTION_OVERRIDE
|
||||||
receiverType: null
|
receiverType: null
|
||||||
symbolKind: MEMBER
|
symbolKind: MEMBER
|
||||||
typeParameters: []
|
typeParameters: []
|
||||||
@@ -309,7 +309,7 @@ KtFirFunctionSymbol:
|
|||||||
isSuspend: false
|
isSuspend: false
|
||||||
modality: ABSTRACT
|
modality: ABSTRACT
|
||||||
name: containsAll
|
name: containsAll
|
||||||
origin: LIBRARY
|
origin: INTERSECTION_OVERRIDE
|
||||||
receiverType: null
|
receiverType: null
|
||||||
symbolKind: MEMBER
|
symbolKind: MEMBER
|
||||||
typeParameters: []
|
typeParameters: []
|
||||||
@@ -372,7 +372,7 @@ KtFirFunctionSymbol:
|
|||||||
isSuspend: false
|
isSuspend: false
|
||||||
modality: ABSTRACT
|
modality: ABSTRACT
|
||||||
name: isEmpty
|
name: isEmpty
|
||||||
origin: LIBRARY
|
origin: INTERSECTION_OVERRIDE
|
||||||
receiverType: null
|
receiverType: null
|
||||||
symbolKind: MEMBER
|
symbolKind: MEMBER
|
||||||
typeParameters: []
|
typeParameters: []
|
||||||
@@ -393,7 +393,7 @@ KtFirFunctionSymbol:
|
|||||||
isSuspend: false
|
isSuspend: false
|
||||||
modality: ABSTRACT
|
modality: ABSTRACT
|
||||||
name: iterator
|
name: iterator
|
||||||
origin: LIBRARY
|
origin: INTERSECTION_OVERRIDE
|
||||||
receiverType: null
|
receiverType: null
|
||||||
symbolKind: MEMBER
|
symbolKind: MEMBER
|
||||||
typeParameters: []
|
typeParameters: []
|
||||||
@@ -439,7 +439,7 @@ KtFirKotlinPropertySymbol:
|
|||||||
isVal: true
|
isVal: true
|
||||||
modality: ABSTRACT
|
modality: ABSTRACT
|
||||||
name: size
|
name: size
|
||||||
origin: LIBRARY
|
origin: INTERSECTION_OVERRIDE
|
||||||
receiverType: null
|
receiverType: null
|
||||||
setter: null
|
setter: null
|
||||||
symbolKind: MEMBER
|
symbolKind: MEMBER
|
||||||
@@ -459,7 +459,7 @@ KtFirFunctionSymbol:
|
|||||||
isSuspend: false
|
isSuspend: false
|
||||||
modality: OPEN
|
modality: OPEN
|
||||||
name: equals
|
name: equals
|
||||||
origin: LIBRARY
|
origin: INTERSECTION_OVERRIDE
|
||||||
receiverType: null
|
receiverType: null
|
||||||
symbolKind: MEMBER
|
symbolKind: MEMBER
|
||||||
typeParameters: []
|
typeParameters: []
|
||||||
@@ -480,7 +480,7 @@ KtFirFunctionSymbol:
|
|||||||
isSuspend: false
|
isSuspend: false
|
||||||
modality: OPEN
|
modality: OPEN
|
||||||
name: hashCode
|
name: hashCode
|
||||||
origin: LIBRARY
|
origin: INTERSECTION_OVERRIDE
|
||||||
receiverType: null
|
receiverType: null
|
||||||
symbolKind: MEMBER
|
symbolKind: MEMBER
|
||||||
typeParameters: []
|
typeParameters: []
|
||||||
@@ -501,7 +501,7 @@ KtFirFunctionSymbol:
|
|||||||
isSuspend: false
|
isSuspend: false
|
||||||
modality: OPEN
|
modality: OPEN
|
||||||
name: toString
|
name: toString
|
||||||
origin: LIBRARY
|
origin: INTERSECTION_OVERRIDE
|
||||||
receiverType: null
|
receiverType: null
|
||||||
symbolKind: MEMBER
|
symbolKind: MEMBER
|
||||||
typeParameters: []
|
typeParameters: []
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
// IGNORE_FIR
|
|
||||||
|
|
||||||
interface A {
|
interface A {
|
||||||
fun foo()
|
fun foo()
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
-2
@@ -1,5 +1,3 @@
|
|||||||
// IGNORE_FIR
|
|
||||||
|
|
||||||
var x : Int <caret>by Baz()
|
var x : Int <caret>by Baz()
|
||||||
|
|
||||||
interface Foo {
|
interface Foo {
|
||||||
|
|||||||
Reference in New Issue
Block a user