[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
This commit is contained in:
Roman Golyshev
2021-09-06 20:03:18 +03:00
committed by Space
parent 8b5d6827c9
commit 19d11f9149
3 changed files with 16 additions and 6 deletions
@@ -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
@@ -26,6 +26,13 @@ public class KtPsiBasedSymbolPointer<S : KtSymbol>(private val psiPointer: Smart
public companion object {
public fun <S : KtSymbol> createForSymbolFromSource(symbol: S): KtPsiBasedSymbolPointer<S>? {
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
@@ -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