FIR IDE: introduce SOURCE_MEMBER_GENERATED declaration kind
This commit is contained in:
+10
-1
@@ -17,5 +17,14 @@ interface KtSymbol : ValidityTokenOwner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum class KtSymbolOrigin {
|
enum class KtSymbolOrigin {
|
||||||
SOURCE, LIBRARY, JAVA, SAM_CONSTRUCTOR
|
SOURCE,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Declaration which do not have it's PSI source and was generated, they are:
|
||||||
|
* For data classes the `copy`, `component{N}`, `toString`, `equals`, `hashCode` functions are generated
|
||||||
|
* For enum classes the `valueOf` & `values` functions are generated
|
||||||
|
*/
|
||||||
|
SOURCE_MEMBER_GENERATED,
|
||||||
|
LIBRARY,
|
||||||
|
JAVA, SAM_CONSTRUCTOR
|
||||||
}
|
}
|
||||||
+11
-1
@@ -10,6 +10,8 @@ import com.intellij.psi.PsiElement
|
|||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.fir.psi
|
||||||
|
import org.jetbrains.kotlin.fir.realPsi
|
||||||
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSession
|
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSession
|
||||||
import org.jetbrains.kotlin.idea.stubindex.KotlinFullClassNameIndex
|
import org.jetbrains.kotlin.idea.stubindex.KotlinFullClassNameIndex
|
||||||
import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelFunctionFqnNameIndex
|
import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelFunctionFqnNameIndex
|
||||||
@@ -138,7 +140,15 @@ object FirIdeDeserializedDeclarationSourceProvider {
|
|||||||
private fun KtElement.isCompiled(): Boolean = containingKtFile.isCompiled
|
private fun KtElement.isCompiled(): Boolean = containingKtFile.isCompiled
|
||||||
|
|
||||||
fun FirElement.findPsi(project: Project): PsiElement? =
|
fun FirElement.findPsi(project: Project): PsiElement? =
|
||||||
psi ?: FirIdeDeserializedDeclarationSourceProvider.findPsi(this, project)
|
realPsi ?: FirIdeDeserializedDeclarationSourceProvider.findPsi(this, project)
|
||||||
|
|
||||||
fun FirElement.findPsi(session: FirSession): PsiElement? =
|
fun FirElement.findPsi(session: FirSession): PsiElement? =
|
||||||
findPsi((session as FirIdeSession).project)
|
findPsi((session as FirIdeSession).project)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds [PsiElement] which will be used as go-to referenced element for [KtPsiReference]
|
||||||
|
* For data classes & enums generated members like `copy` `componentN`, `values` it will return corresponding enum/data class
|
||||||
|
* Otherwise, behaves the same way as [findPsi] returns exact PSI declaration corresponding to passed [FirDeclaration]
|
||||||
|
*/
|
||||||
|
fun FirDeclaration.findReferencePsi(): PsiElement? =
|
||||||
|
psi ?: FirIdeDeserializedDeclarationSourceProvider.findPsi(this, (session as FirIdeSession).project)
|
||||||
+11
-4
@@ -23,7 +23,8 @@ internal class KtFirSymbolContainingDeclarationProvider(
|
|||||||
if (symbol is KtPackageSymbol) return null
|
if (symbol is KtPackageSymbol) return null
|
||||||
if (symbol.symbolKind == KtSymbolKind.TOP_LEVEL) return null
|
if (symbol.symbolKind == KtSymbolKind.TOP_LEVEL) return null
|
||||||
return when (symbol.origin) {
|
return when (symbol.origin) {
|
||||||
KtSymbolOrigin.SOURCE -> getContainingDeclarationForKotlinInSourceSymbol(symbol)
|
KtSymbolOrigin.SOURCE, KtSymbolOrigin.SOURCE_MEMBER_GENERATED ->
|
||||||
|
getContainingDeclarationForKotlinInSourceSymbol(symbol)
|
||||||
KtSymbolOrigin.LIBRARY -> getContainingDeclarationForLibrarySymbol(symbol)
|
KtSymbolOrigin.LIBRARY -> getContainingDeclarationForLibrarySymbol(symbol)
|
||||||
KtSymbolOrigin.JAVA -> TODO()
|
KtSymbolOrigin.JAVA -> TODO()
|
||||||
KtSymbolOrigin.SAM_CONSTRUCTOR -> TODO()
|
KtSymbolOrigin.SAM_CONSTRUCTOR -> TODO()
|
||||||
@@ -31,11 +32,17 @@ internal class KtFirSymbolContainingDeclarationProvider(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getContainingDeclarationForKotlinInSourceSymbol(symbol: KtSymbolWithKind): KtSymbolWithKind = with(analysisSession) {
|
private fun getContainingDeclarationForKotlinInSourceSymbol(symbol: KtSymbolWithKind): KtSymbolWithKind = with(analysisSession) {
|
||||||
require(symbol.origin == KtSymbolOrigin.SOURCE)
|
require(symbol.origin == KtSymbolOrigin.SOURCE || symbol.origin == KtSymbolOrigin.SOURCE_MEMBER_GENERATED)
|
||||||
val psi = symbol.psi ?: error("PSI should present for declaration built by Kotlin code")
|
val psi = symbol.psi ?: error("PSI should present for declaration built by Kotlin code")
|
||||||
check(psi is KtDeclaration) { "PSI of kotlin declaration should be KtDeclaration" }
|
check(psi is KtDeclaration) { "PSI of kotlin declaration should be KtDeclaration" }
|
||||||
val containingDeclaration = psi.parentOfType<KtDeclaration>()
|
val containingDeclaration = when (symbol.origin) {
|
||||||
?: error("Containing declaration should present for non-toplevel declaration")
|
KtSymbolOrigin.SOURCE -> psi.parentOfType()
|
||||||
|
?: error("Containing declaration should present for non-toplevel declaration")
|
||||||
|
KtSymbolOrigin.SOURCE_MEMBER_GENERATED -> psi
|
||||||
|
else -> error("Unsupported declaration origin ${symbol.origin}")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return with(analysisSession) {
|
return with(analysisSession) {
|
||||||
val containingSymbol = containingDeclaration.getSymbol()
|
val containingSymbol = containingDeclaration.getSymbol()
|
||||||
check(containingSymbol is KtSymbolWithKind)
|
check(containingSymbol is KtSymbolWithKind)
|
||||||
|
|||||||
+8
-1
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.frontend.api.fir.symbols
|
package org.jetbrains.kotlin.idea.frontend.api.fir.symbols
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||||
@@ -22,7 +23,13 @@ internal interface KtFirSymbol<F : FirDeclaration> : KtSymbol, ValidityTokenOwne
|
|||||||
|
|
||||||
|
|
||||||
private tailrec fun FirDeclaration.ktSymbolOrigin(): KtSymbolOrigin = when (origin) {
|
private tailrec fun FirDeclaration.ktSymbolOrigin(): KtSymbolOrigin = when (origin) {
|
||||||
FirDeclarationOrigin.Source -> KtSymbolOrigin.SOURCE
|
FirDeclarationOrigin.Source -> {
|
||||||
|
if (source?.kind == FirFakeSourceElementKind.DataClassGeneratedMembers
|
||||||
|
|| source?.kind == FirFakeSourceElementKind.EnumGeneratedDeclaration
|
||||||
|
) {
|
||||||
|
KtSymbolOrigin.SOURCE_MEMBER_GENERATED
|
||||||
|
} else KtSymbolOrigin.SOURCE
|
||||||
|
}
|
||||||
FirDeclarationOrigin.Library -> KtSymbolOrigin.LIBRARY
|
FirDeclarationOrigin.Library -> KtSymbolOrigin.LIBRARY
|
||||||
FirDeclarationOrigin.Java -> KtSymbolOrigin.JAVA
|
FirDeclarationOrigin.Java -> KtSymbolOrigin.JAVA
|
||||||
FirDeclarationOrigin.SamConstructor -> KtSymbolOrigin.SAM_CONSTRUCTOR
|
FirDeclarationOrigin.SamConstructor -> KtSymbolOrigin.SAM_CONSTRUCTOR
|
||||||
|
|||||||
@@ -6,13 +6,18 @@
|
|||||||
package org.jetbrains.kotlin.idea.references
|
package org.jetbrains.kotlin.idea.references
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
|
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.symbols.KtSymbol
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
|
||||||
|
|
||||||
interface KtFirReference : KtReference, KtSymbolBasedReference {
|
interface KtFirReference : KtReference, KtSymbolBasedReference {
|
||||||
fun getResolvedToPsi(analysisSession: KtAnalysisSession): Collection<PsiElement> =
|
fun getResolvedToPsi(analysisSession: KtAnalysisSession): Collection<PsiElement> =
|
||||||
analysisSession.resolveToSymbols().mapNotNull(KtSymbol::psi)
|
analysisSession.resolveToSymbols().mapNotNull { symbol ->
|
||||||
|
(symbol as? KtFirSymbol<*>)?.firRef?.withFir { it.findReferencePsi() }
|
||||||
|
?: symbol.psi
|
||||||
|
}
|
||||||
|
|
||||||
override val resolver get() = KtFirReferenceResolver
|
override val resolver get() = KtFirReferenceResolver
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user