From 19d11f9149b109dd245ee24a352ffb85b76c5ac1 Mon Sep 17 00:00:00 2001 From: Roman Golyshev Date: Mon, 6 Sep 2021 20:03:18 +0300 Subject: [PATCH] [FIR IDE] Do not create `KtPsiBasedSymbolPointer` for generated members For example, if a class has default constructor (`class Foo`), both KtClassSymbol and KtConstructorSymbol will be pointing to the same PSI - thus creating effectively the same `KtSymbolPointer`. Later it will be impossible to deduce which symbol we had in mind Currently, `Show Parameters Info` works incorrectly for such generated declarations because of that - it throws CCE while trying to cast class symbol to function (constructor) symbol --- .../kotlin/idea/frontend/api/symbols/KtSymbol.kt | 1 + .../symbols/pointers/KtPsiBasedSymbolPointer.kt | 7 +++++++ .../idea/frontend/api/fir/symbols/KtFirSymbol.kt | 14 ++++++++------ 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtSymbol.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtSymbol.kt index 2f37a13179d..2e1c7cbea00 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtSymbol.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtSymbol.kt @@ -51,6 +51,7 @@ public enum class KtSymbolOrigin { /** * Declaration which do not have it's PSI source and was generated, they are: + * For regular classes, implicit default constructor is generated * For data classes the `copy`, `component{N}`, `toString`, `equals`, `hashCode` functions are generated * For enum classes the `valueOf` & `values` functions are generated * For lambda the `it` property is generated diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/pointers/KtPsiBasedSymbolPointer.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/pointers/KtPsiBasedSymbolPointer.kt index 8c7e9cff239..d610a8a38d0 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/pointers/KtPsiBasedSymbolPointer.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/pointers/KtPsiBasedSymbolPointer.kt @@ -26,6 +26,13 @@ public class KtPsiBasedSymbolPointer(private val psiPointer: Smart public companion object { public fun createForSymbolFromSource(symbol: S): KtPsiBasedSymbolPointer? { if (symbol.origin == KtSymbolOrigin.LIBRARY) return null + + /** + * If symbol points to a generated member, we won't be able to recover it later on, because there is no corresponding + * psi by which it can be found + */ + if (symbol.origin == KtSymbolOrigin.SOURCE_MEMBER_GENERATED) return null + val psi = when (val psi = symbol.psi) { is KtDeclaration -> psi is KtObjectLiteralExpression -> psi.objectDeclaration diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirSymbol.kt index fb68c001790..974c4ce7468 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirSymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirSymbol.kt @@ -34,12 +34,14 @@ internal fun KtFirSymbol<*>.symbolHashCode(): Int = firRef.hashCode() * 31 + tok private tailrec fun FirDeclaration.ktSymbolOrigin(): KtSymbolOrigin = when (origin) { FirDeclarationOrigin.Source -> { - if (source?.kind == FirFakeSourceElementKind.DataClassGeneratedMembers - || source?.kind == FirFakeSourceElementKind.EnumGeneratedDeclaration - || source?.kind == FirFakeSourceElementKind.ItLambdaParameter - ) { - KtSymbolOrigin.SOURCE_MEMBER_GENERATED - } else KtSymbolOrigin.SOURCE + when (source?.kind) { + FirFakeSourceElementKind.ImplicitConstructor, + FirFakeSourceElementKind.DataClassGeneratedMembers, + FirFakeSourceElementKind.EnumGeneratedDeclaration, + FirFakeSourceElementKind.ItLambdaParameter -> KtSymbolOrigin.SOURCE_MEMBER_GENERATED + + else -> KtSymbolOrigin.SOURCE + } } FirDeclarationOrigin.Library, FirDeclarationOrigin.BuiltIns -> KtSymbolOrigin.LIBRARY FirDeclarationOrigin.Java -> KtSymbolOrigin.JAVA