[AA] Add specific implementation for KtFirEnumEntryInitializerSymbol
- Previously, `KtFirAnonymousObjectSymbol` was a `KtEnumEntryInitializerSymbol`, which carried the risk that an anonymous object unrelated to enum entries might be used as an enum entry initializer. This commit introduces a specific symbol for FIR enum entry initializers. - As a nice side effect, anonymous object symbol creation is simplified and `KtFirEnumEntryInitializerSymbolPointer` can restore the symbol via `KtFirEnumEntrySymbol.enumEntryInitializer`. ^KT-61425
This commit is contained in:
committed by
Space Team
parent
536e172d0e
commit
3fa2ca7ddd
+15
-9
@@ -10,6 +10,8 @@ import com.intellij.util.containers.ContainerUtil
|
||||
import org.jetbrains.kotlin.analysis.api.KtStarTypeProjection
|
||||
import org.jetbrains.kotlin.analysis.api.KtTypeArgumentWithVariance
|
||||
import org.jetbrains.kotlin.analysis.api.KtTypeProjection
|
||||
import org.jetbrains.kotlin.analysis.api.fir.signatures.KtFirFunctionLikeSubstitutorBasedSignature
|
||||
import org.jetbrains.kotlin.analysis.api.fir.signatures.KtFirVariableLikeSubstitutorBasedSignature
|
||||
import org.jetbrains.kotlin.analysis.api.fir.symbols.*
|
||||
import org.jetbrains.kotlin.analysis.api.fir.types.*
|
||||
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
|
||||
@@ -21,16 +23,13 @@ import org.jetbrains.kotlin.analysis.api.types.KtSubstitutor
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtType
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.errorWithFirSpecificEntries
|
||||
import org.jetbrains.kotlin.fir.utils.exceptions.withConeTypeEntry
|
||||
import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry
|
||||
import org.jetbrains.kotlin.fir.utils.exceptions.withFirSymbolEntry
|
||||
import org.jetbrains.kotlin.analysis.providers.KotlinPackageProvider
|
||||
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirFieldImpl
|
||||
import org.jetbrains.kotlin.fir.declarations.FirOuterClassTypeParameterRef
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirFieldImpl
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeCannotInferTypeParameterType
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaField
|
||||
@@ -48,6 +47,7 @@ import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.importedFromObjectOrStaticData
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.toConeType
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
|
||||
@@ -56,15 +56,16 @@ import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
import org.jetbrains.kotlin.fir.utils.exceptions.withConeTypeEntry
|
||||
import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry
|
||||
import org.jetbrains.kotlin.fir.utils.exceptions.withFirSymbolEntry
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.contract
|
||||
import org.jetbrains.kotlin.analysis.api.fir.signatures.KtFirFunctionLikeSubstitutorBasedSignature
|
||||
import org.jetbrains.kotlin.analysis.api.fir.signatures.KtFirVariableLikeSubstitutorBasedSignature
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.importedFromObjectOrStaticData
|
||||
|
||||
/**
|
||||
* Maps FirElement to KtSymbol & ConeType to KtType, thread safe
|
||||
@@ -160,7 +161,12 @@ internal class KtSymbolByFirBuilder constructor(
|
||||
}
|
||||
|
||||
fun buildAnonymousObjectSymbol(symbol: FirAnonymousObjectSymbol): KtAnonymousObjectSymbol {
|
||||
return symbolsCache.cache(symbol) { KtFirAnonymousObjectSymbol(symbol, analysisSession) }
|
||||
return symbolsCache.cache(symbol) {
|
||||
when (symbol.classKind) {
|
||||
ClassKind.ENUM_ENTRY -> KtFirEnumEntryInitializerSymbol(symbol, analysisSession)
|
||||
else -> KtFirAnonymousObjectSymbol(symbol, analysisSession)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun buildTypeAliasSymbol(symbol: FirTypeAliasSymbol): KtFirTypeAliasSymbol {
|
||||
|
||||
+2
-9
@@ -6,27 +6,23 @@
|
||||
package org.jetbrains.kotlin.analysis.api.fir.symbols
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.fir.annotations.KtFirAnnotationListForDeclaration
|
||||
import org.jetbrains.kotlin.analysis.api.fir.getAllowedPsi
|
||||
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.withValidityAssertion
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtAnonymousObjectSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtEnumEntryInitializerSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.pointers.CanNotCreateSymbolPointerForLocalLibraryDeclarationException
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtPsiBasedSymbolPointer
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtType
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousObjectSymbol
|
||||
|
||||
internal class KtFirAnonymousObjectSymbol(
|
||||
internal open class KtFirAnonymousObjectSymbol(
|
||||
override val firSymbol: FirAnonymousObjectSymbol,
|
||||
override val analysisSession: KtFirAnalysisSession,
|
||||
) : KtAnonymousObjectSymbol(), KtEnumEntryInitializerSymbol, KtFirSymbol<FirAnonymousObjectSymbol> {
|
||||
) : KtAnonymousObjectSymbol(), KtFirSymbol<FirAnonymousObjectSymbol> {
|
||||
override val psi: PsiElement? = withValidityAssertion { firSymbol.fir.getAllowedPsi() }
|
||||
|
||||
override val annotationsList by cached {
|
||||
@@ -38,9 +34,6 @@ internal class KtFirAnonymousObjectSymbol(
|
||||
context(KtAnalysisSession)
|
||||
override fun createPointer(): KtSymbolPointer<KtAnonymousObjectSymbol> = withValidityAssertion {
|
||||
KtPsiBasedSymbolPointer.createForSymbolFromSource<KtAnonymousObjectSymbol>(this)?.let { return it }
|
||||
if (firSymbol.source?.kind == KtFakeSourceElementKind.EnumInitializer) {
|
||||
return KtFirEnumEntryInitializerSymbolPointer(requireOwnerPointer())
|
||||
}
|
||||
|
||||
throw CanNotCreateSymbolPointerForLocalLibraryDeclarationException(this::class)
|
||||
}
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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
|
||||
|
||||
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
|
||||
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.lifetime.withValidityAssertion
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtEnumEntryInitializerSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtPsiBasedSymbolPointer
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousObjectSymbol
|
||||
|
||||
internal class KtFirEnumEntryInitializerSymbol(
|
||||
firSymbol: FirAnonymousObjectSymbol,
|
||||
analysisSession: KtFirAnalysisSession,
|
||||
) : KtFirAnonymousObjectSymbol(firSymbol, analysisSession), KtEnumEntryInitializerSymbol {
|
||||
init {
|
||||
check(firSymbol.source?.kind == KtFakeSourceElementKind.EnumInitializer) {
|
||||
"Expected the `firSymbol` of ${KtFirEnumEntryInitializerSymbol::class.simpleName} to have an enum initializer fake source kind."
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [KtFirEnumEntryInitializerSymbol] is the required return type instead of [KtEnumEntryInitializerSymbol] to fulfill return type
|
||||
* subtyping requirements, as [KtEnumEntryInitializerSymbol] is not a subtype of
|
||||
* [org.jetbrains.kotlin.analysis.api.symbols.KtAnonymousObjectSymbol]. (It cannot be a subtype in the general Analysis API because enum
|
||||
* entry initializers are classes in FE10.)
|
||||
*/
|
||||
context(KtAnalysisSession)
|
||||
override fun createPointer(): KtSymbolPointer<KtFirEnumEntryInitializerSymbol> = withValidityAssertion {
|
||||
KtPsiBasedSymbolPointer.createForSymbolFromSource<KtFirEnumEntryInitializerSymbol>(this)?.let { return it }
|
||||
|
||||
KtFirEnumEntryInitializerSymbolPointer(requireOwnerPointer())
|
||||
}
|
||||
}
|
||||
+5
-3
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.analysis.api.fir.symbols.pointers.KtFirEnumEntrySymb
|
||||
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.withValidityAssertion
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtEnumEntryInitializerSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtEnumEntrySymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtPsiBasedSymbolPointer
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
|
||||
@@ -45,7 +44,7 @@ internal class KtFirEnumEntrySymbol(
|
||||
|
||||
override val callableIdIfNonLocal: CallableId? get() = withValidityAssertion { firSymbol.getCallableIdIfNonLocal() }
|
||||
|
||||
override val enumEntryInitializer: KtEnumEntryInitializerSymbol? by cached {
|
||||
override val enumEntryInitializer: KtFirEnumEntryInitializerSymbol? by cached {
|
||||
if (firSymbol.fir.initializer == null) {
|
||||
return@cached null
|
||||
}
|
||||
@@ -56,7 +55,10 @@ internal class KtFirEnumEntrySymbol(
|
||||
check(initializerExpression is FirAnonymousObjectExpression) {
|
||||
"Unexpected enum entry initializer: ${initializerExpression?.javaClass}"
|
||||
}
|
||||
KtFirAnonymousObjectSymbol(initializerExpression.anonymousObject.symbol, analysisSession)
|
||||
|
||||
val classifierBuilder = analysisSession.firSymbolBuilder.classifierBuilder
|
||||
classifierBuilder.buildAnonymousObjectSymbol(initializerExpression.anonymousObject.symbol) as? KtFirEnumEntryInitializerSymbol
|
||||
?: error("The anonymous object symbol for an enum entry initializer should be a ${KtFirEnumEntryInitializerSymbol::class.simpleName}")
|
||||
}
|
||||
|
||||
context(KtAnalysisSession)
|
||||
|
||||
+6
-10
@@ -7,25 +7,21 @@ 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.fir.symbols.KtFirEnumEntryInitializerSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirEnumEntrySymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnonymousObjectExpression
|
||||
|
||||
internal class KtFirEnumEntryInitializerSymbolPointer(
|
||||
private val ownerPointer: KtSymbolPointer<KtEnumEntrySymbol>,
|
||||
) : KtSymbolPointer<KtAnonymousObjectSymbol>() {
|
||||
private val ownerPointer: KtSymbolPointer<KtFirEnumEntrySymbol>,
|
||||
) : KtSymbolPointer<KtFirEnumEntryInitializerSymbol>() {
|
||||
@Deprecated("Consider using org.jetbrains.kotlin.analysis.api.KtAnalysisSession.restoreSymbol")
|
||||
override fun restoreSymbol(analysisSession: KtAnalysisSession): KtAnonymousObjectSymbol? {
|
||||
override fun restoreSymbol(analysisSession: KtAnalysisSession): KtFirEnumEntryInitializerSymbol? {
|
||||
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)
|
||||
return owner?.enumEntryInitializer
|
||||
}
|
||||
|
||||
override fun pointsToTheSameSymbolAs(other: KtSymbolPointer<KtSymbol>): Boolean = this === other ||
|
||||
|
||||
analysis/analysis-api/testData/components/scopeProvider/scopeContextForPosition/enumEntry.pretty.txt
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
element: e
|
||||
implicit receivers:
|
||||
type: `<anonymous>`
|
||||
owner symbol: KtFirAnonymousObjectSymbol
|
||||
owner symbol: KtFirEnumEntryInitializerSymbol
|
||||
|
||||
type: kotlin.Enum.Companion
|
||||
owner symbol: KtFirNamedClassOrObjectSymbol
|
||||
|
||||
Vendored
+1
-1
@@ -4,7 +4,7 @@ implicit receivers:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: <anonymous>
|
||||
owner symbol: KtFirAnonymousObjectSymbol
|
||||
owner symbol: KtFirEnumEntryInitializerSymbol
|
||||
|
||||
type: KtUsualClassType:
|
||||
annotationsList: []
|
||||
|
||||
Reference in New Issue
Block a user