From 897a5b085ddbbf044e736c5543df66d03d65c811 Mon Sep 17 00:00:00 2001 From: Dmitrii Gridin Date: Fri, 4 Nov 2022 13:25:06 +0100 Subject: [PATCH] [AA K2] implement symbol pointers for enum entry members without psi ^KT-54311 --- ...tFirSymbolContainingDeclarationProvider.kt | 7 ++--- .../fir/symbols/KtFirAnonymousObjectSymbol.kt | 11 +++++-- .../fir/symbols/KtFirKotlinPropertySymbol.kt | 2 +- .../KtFirEnumEntryInitializerSymbolPointer.kt | 29 +++++++++++++++++++ .../KtFirMemberPropertySymbolPointer.kt | 6 ++-- .../api/fir/symbols/pointers/pointerUtils.kt | 5 ++-- .../scopes/memberScopeByFqName/enumEntry.kt | 2 +- .../symbols/symbolByPsi/enumEntryFunctions.kt | 2 +- .../symbols/symbolByPsi/enumEntryOverride.kt | 2 +- .../symbolByPsi/enumEntryProperties.kt | 2 +- .../symbols/symbolByPsi/enumValueMember.kt | 3 +- 11 files changed, 55 insertions(+), 16 deletions(-) create mode 100644 analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/pointers/KtFirEnumEntryInitializerSymbolPointer.kt diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSymbolContainingDeclarationProvider.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSymbolContainingDeclarationProvider.kt index 88ab12f75a4..109f0f64775 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSymbolContainingDeclarationProvider.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSymbolContainingDeclarationProvider.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ @@ -83,12 +83,11 @@ internal class KtFirSymbolContainingDeclarationProvider( withSymbolAttachment("symbolForContainingPsi", symbol, analysisSession) } - KtFakeSourceElementKind.ImplicitConstructor -> - return source.psi as KtDeclaration - + KtFakeSourceElementKind.ImplicitConstructor -> return source.psi as KtDeclaration KtFakeSourceElementKind.PropertyFromParameter -> return source.psi?.parentOfType()!! KtFakeSourceElementKind.DefaultAccessor -> return source.psi as KtProperty KtFakeSourceElementKind.ItLambdaParameter -> return source.psi as KtFunctionLiteral + KtFakeSourceElementKind.EnumInitializer -> return source.psi as KtEnumEntry KtRealSourceElementKind -> source.psi!! else -> buildErrorWithAttachment("errorWithAttachment FirSourceElement: kind=${source.kind} element=${source.psi!!::class.simpleName}") { diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirAnonymousObjectSymbol.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirAnonymousObjectSymbol.kt index 3f93c4ebd0b..4d0bd62d8ee 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirAnonymousObjectSymbol.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirAnonymousObjectSymbol.kt @@ -6,9 +6,12 @@ package org.jetbrains.kotlin.analysis.api.fir.symbols import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.KtFakeSourceElementKind import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder import org.jetbrains.kotlin.analysis.api.fir.annotations.KtFirAnnotationListForDeclaration import org.jetbrains.kotlin.analysis.api.fir.findPsi +import org.jetbrains.kotlin.analysis.api.fir.symbols.pointers.KtFirEnumEntryInitializerSymbolPointer +import org.jetbrains.kotlin.analysis.api.fir.symbols.pointers.requireOwnerPointer import org.jetbrains.kotlin.analysis.api.fir.utils.cached import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion @@ -35,8 +38,12 @@ internal class KtFirAnonymousObjectSymbol( override val superTypes: List by cached { firSymbol.superTypesList(builder) } override fun createPointer(): KtSymbolPointer = withValidityAssertion { - KtPsiBasedSymbolPointer.createForSymbolFromSource(this) - ?: throw CanNotCreateSymbolPointerForLocalLibraryDeclarationException("Cannot create pointer for KtFirAnonymousObjectSymbol") + KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it } + if (firSymbol.source?.kind == KtFakeSourceElementKind.EnumInitializer) { + return KtFirEnumEntryInitializerSymbolPointer(requireOwnerPointer()) + } + + throw CanNotCreateSymbolPointerForLocalLibraryDeclarationException("Cannot create pointer for KtFirAnonymousObjectSymbol") } override fun equals(other: Any?): Boolean = symbolEquals(other) diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirKotlinPropertySymbol.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirKotlinPropertySymbol.kt index dd798df3f81..e9ff66b5ab4 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirKotlinPropertySymbol.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirKotlinPropertySymbol.kt @@ -135,7 +135,7 @@ internal class KtFirKotlinPropertySymbol( KtFirMemberPropertySymbolPointer( requireOwnerPointer(), firSymbol.name, - firSymbol.createSignature() + firSymbol.createSignature(), ) else -> throw UnsupportedSymbolKind(this::class, kind) diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/pointers/KtFirEnumEntryInitializerSymbolPointer.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/pointers/KtFirEnumEntryInitializerSymbolPointer.kt new file mode 100644 index 00000000000..d8d0ada76aa --- /dev/null +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/pointers/KtFirEnumEntryInitializerSymbolPointer.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.analysis.api.fir.symbols.pointers + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession +import org.jetbrains.kotlin.analysis.api.fir.utils.firSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtAnonymousObjectSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtEnumEntrySymbol +import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer +import org.jetbrains.kotlin.fir.expressions.FirAnonymousObjectExpression + +internal class KtFirEnumEntryInitializerSymbolPointer( + private val ownerPointer: KtSymbolPointer, +) : KtSymbolPointer() { + @Deprecated("Consider using org.jetbrains.kotlin.analysis.api.KtAnalysisSession.restoreSymbol") + override fun restoreSymbol(analysisSession: KtAnalysisSession): KtAnonymousObjectSymbol? { + require(analysisSession is KtFirAnalysisSession) + val owner = with(analysisSession) { + ownerPointer.restoreSymbol() + } + + val initializer = owner?.firSymbol?.fir?.initializer as? FirAnonymousObjectExpression ?: return null + return analysisSession.firSymbolBuilder.classifierBuilder.buildAnonymousObjectSymbol(initializer.anonymousObject.symbol) + } +} diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/pointers/KtFirMemberPropertySymbolPointer.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/pointers/KtFirMemberPropertySymbolPointer.kt index 256d03e5566..db5bccbc8c9 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/pointers/KtFirMemberPropertySymbolPointer.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/pointers/KtFirMemberPropertySymbolPointer.kt @@ -24,8 +24,10 @@ internal class KtFirMemberPropertySymbolPointer( candidates: FirScope, firSession: FirSession ): KtKotlinPropertySymbol? { - val firProperty = candidates.findDeclarationWithSignature(signature, firSession) { processPropertiesByName(name, it) } - ?: return null + val firProperty = candidates.findDeclarationWithSignature(signature, firSession) { + processPropertiesByName(name, it) + } ?: return null + return firSymbolBuilder.variableLikeBuilder.buildVariableSymbol(firProperty.symbol) as? KtKotlinPropertySymbol } } diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/pointers/pointerUtils.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/pointers/pointerUtils.kt index b198e3c53be..750582a0cd3 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/pointers/pointerUtils.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/pointers/pointerUtils.kt @@ -29,10 +29,11 @@ internal inline fun FirScope.findDeclarationWithSig var foundSymbol: D? = null processor { symbol -> val declaration = symbol.fir - if (declaration is D && signatureComposer.composeSignature(declaration) == signature) { + if (declaration is D && signatureComposer.composeSignature(declaration, allowLocalClasses = true) == signature) { foundSymbol = declaration } } + return foundSymbol } @@ -66,7 +67,7 @@ internal fun FirBasedSymbol<*>.createSignature(): IdSignature = internal fun FirDeclaration.createSignature(): IdSignature { val signatureComposer = moduleData.session.ideSessionComponents.signatureComposer - return signatureComposer.composeSignature(this) + return signatureComposer.composeSignature(this, allowLocalClasses = true) ?: error("Could not compose signature for ${this.renderWithType()}, looks like it is private or local") } diff --git a/analysis/analysis-api/testData/scopes/memberScopeByFqName/enumEntry.kt b/analysis/analysis-api/testData/scopes/memberScopeByFqName/enumEntry.kt index e2004e4cd65..3989e0c7156 100644 --- a/analysis/analysis-api/testData/scopes/memberScopeByFqName/enumEntry.kt +++ b/analysis/analysis-api/testData/scopes/memberScopeByFqName/enumEntry.kt @@ -1,4 +1,4 @@ -// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE +// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE_K1 package test enum class E { diff --git a/analysis/analysis-api/testData/symbols/symbolByPsi/enumEntryFunctions.kt b/analysis/analysis-api/testData/symbols/symbolByPsi/enumEntryFunctions.kt index e6ce5f840c1..50ac244f41c 100644 --- a/analysis/analysis-api/testData/symbols/symbolByPsi/enumEntryFunctions.kt +++ b/analysis/analysis-api/testData/symbols/symbolByPsi/enumEntryFunctions.kt @@ -1,4 +1,4 @@ -// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE +// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE_K1 enum class MyEnumClass { FirstEntry { diff --git a/analysis/analysis-api/testData/symbols/symbolByPsi/enumEntryOverride.kt b/analysis/analysis-api/testData/symbols/symbolByPsi/enumEntryOverride.kt index 5f59177eee2..1e876f06a4e 100644 --- a/analysis/analysis-api/testData/symbols/symbolByPsi/enumEntryOverride.kt +++ b/analysis/analysis-api/testData/symbols/symbolByPsi/enumEntryOverride.kt @@ -1,4 +1,4 @@ -// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE +// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE_K1 enum class MyEnumClass { FirstEntry { diff --git a/analysis/analysis-api/testData/symbols/symbolByPsi/enumEntryProperties.kt b/analysis/analysis-api/testData/symbols/symbolByPsi/enumEntryProperties.kt index c602c187f61..02497e47aea 100644 --- a/analysis/analysis-api/testData/symbols/symbolByPsi/enumEntryProperties.kt +++ b/analysis/analysis-api/testData/symbols/symbolByPsi/enumEntryProperties.kt @@ -1,4 +1,4 @@ -// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE +// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE_K1 enum class MyEnumClass { FirstEntry { diff --git a/analysis/analysis-api/testData/symbols/symbolByPsi/enumValueMember.kt b/analysis/analysis-api/testData/symbols/symbolByPsi/enumValueMember.kt index f7d5cd49743..ac0cb4b2b02 100644 --- a/analysis/analysis-api/testData/symbols/symbolByPsi/enumValueMember.kt +++ b/analysis/analysis-api/testData/symbols/symbolByPsi/enumValueMember.kt @@ -1,4 +1,5 @@ -// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE +// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE_K1 + enum class Style(val value: String) { SHEET("foo") { override val exitAnimation: String