FIR: Derive FirMemberDeclaration from FirAnnotatedDeclaration

It's necessary to have the sane logic that FirMemberDeclaration is a subtype of FirDeclaration
The only kind of controversial change here is making FirAnonymousObject
also be FirMemberDeclaration, thus having its own declaration status
This commit is contained in:
Denis.Zharkov
2021-10-13 15:58:27 +03:00
committed by TeamCityServer
parent 603655d63f
commit f441024fd4
18 changed files with 43 additions and 37 deletions
@@ -20,10 +20,10 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.util.getElementTextInCont
import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtDeclaration
internal fun <F> KtFirSymbol<F>.getModality( internal fun KtFirSymbol<FirMemberDeclaration>.getModality(
phase: FirResolvePhase = FirResolvePhase.STATUS, phase: FirResolvePhase = FirResolvePhase.STATUS,
defaultModality: Modality? = null defaultModality: Modality? = null
): Modality where F : FirDeclaration, F : FirMemberDeclaration { ): Modality {
return firRef.withFir(phase) { fir -> return firRef.withFir(phase) { fir ->
fir.modality fir.modality
?: defaultModality ?: defaultModality
@@ -42,9 +42,9 @@ private fun FirDeclaration.invalidModalityError(): Nothing {
} }
internal fun <F> KtFirSymbol<F>.getVisibility( internal fun KtFirSymbol<FirMemberDeclaration>.getVisibility(
phase: FirResolvePhase = FirResolvePhase.STATUS phase: FirResolvePhase = FirResolvePhase.STATUS
): Visibility where F : FirMemberDeclaration, F : FirDeclaration = ): Visibility =
firRef.withFir(phase) { fir -> fir.visibility } firRef.withFir(phase) { fir -> fir.visibility }
internal fun KtFirSymbol<FirCallableDeclaration>.getCallableIdIfNonLocal(): CallableId? = internal fun KtFirSymbol<FirCallableDeclaration>.getCallableIdIfNonLocal(): CallableId? =
@@ -247,7 +247,6 @@ fun FirMemberDeclaration.implicitModality(context: CheckerContext): Modality {
&& klass.classKind == ClassKind.INTERFACE && klass.classKind == ClassKind.INTERFACE
&& tree.visibilityModifier(source.lighterASTNode)?.tokenType != KtTokens.PRIVATE_KEYWORD && tree.visibilityModifier(source.lighterASTNode)?.tokenType != KtTokens.PRIVATE_KEYWORD
) { ) {
require(this is FirDeclaration)
return if (this.hasBody()) Modality.OPEN else Modality.ABSTRACT return if (this.hasBody()) Modality.OPEN else Modality.ABSTRACT
} }
@@ -40,12 +40,12 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() {
} }
} }
private fun <T> checkActualDeclarationHasExpected( private fun checkActualDeclarationHasExpected(
declaration: T, declaration: FirMemberDeclaration,
context: CheckerContext, context: CheckerContext,
reporter: DiagnosticReporter, reporter: DiagnosticReporter,
checkActual: Boolean = true checkActual: Boolean = true
) where T : FirDeclaration, T : FirMemberDeclaration { ) {
val scopeSession = ScopeSession() val scopeSession = ScopeSession()
val symbol = declaration.symbol val symbol = declaration.symbol
val compatibilityToMembersMap = FirExpectActualResolver.findExpectForActual(symbol, context.session, scopeSession) ?: return val compatibilityToMembersMap = FirExpectActualResolver.findExpectForActual(symbol, context.session, scopeSession) ?: return
@@ -35,7 +35,6 @@ object FirVisibilityQualifierChecker : FirResolvedQualifierChecker() {
) { ) {
val firFile = context.containingDeclarations.firstOrNull() as? FirFile ?: return val firFile = context.containingDeclarations.firstOrNull() as? FirFile ?: return
val firClassLikeDeclaration = symbol.fir val firClassLikeDeclaration = symbol.fir
if (firClassLikeDeclaration !is FirMemberDeclaration) return
if (!context.session.visibilityChecker.isVisible( if (!context.session.visibilityChecker.isVisible(
firClassLikeDeclaration, context.session, firFile, context.containingDeclarations, firClassLikeDeclaration, context.session, firFile, context.containingDeclarations,
@@ -50,8 +50,7 @@ object RedundantVisibilityModifierSyntaxChecker : FirDeclarationSyntaxChecker<Fi
val explicitVisibility = (visibilityModifier?.tokenType as? KtModifierKeywordToken)?.toVisibilityOrNull() val explicitVisibility = (visibilityModifier?.tokenType as? KtModifierKeywordToken)?.toVisibilityOrNull()
val implicitVisibility = element.implicitVisibility(context) val implicitVisibility = element.implicitVisibility(context)
val containingMemberDeclaration = context.findClosest<FirMemberDeclaration>() val containingMemberDeclaration = context.findClosest<FirMemberDeclaration>()
require(containingMemberDeclaration is FirDeclaration?)
val isHidden = explicitVisibility.isEffectivelyHiddenBy(containingMemberDeclaration) val isHidden = explicitVisibility.isEffectivelyHiddenBy(containingMemberDeclaration)
if (explicitVisibility != implicitVisibility && !isHidden) { if (explicitVisibility != implicitVisibility && !isHidden) {
@@ -1780,7 +1780,7 @@ class HtmlFirDump internal constructor(private var linkResolver: FirLinkResolver
private fun FlowContent.generate(declaration: FirDeclaration) { private fun FlowContent.generate(declaration: FirDeclaration) {
when (declaration) { when (declaration) {
is FirAnonymousInitializer -> generate(declaration) is FirAnonymousInitializer -> generate(declaration)
is FirMemberDeclaration -> generate(declaration as FirMemberDeclaration) is FirMemberDeclaration -> generate(declaration)
else -> unsupported(declaration) else -> unsupported(declaration)
} }
} }
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.resolve.calls.ReceiverValue
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes
import org.jetbrains.kotlin.fir.resolve.providers.firProvider import org.jetbrains.kotlin.fir.resolve.providers.firProvider
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.resolve.typeWithStarProjections import org.jetbrains.kotlin.fir.resolve.typeWithStarProjections
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
@@ -32,10 +33,10 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.types.AbstractTypeChecker
abstract class FirModuleVisibilityChecker : FirSessionComponent { abstract class FirModuleVisibilityChecker : FirSessionComponent {
abstract fun <T> isInFriendModule(declaration: T): Boolean where T : FirMemberDeclaration, T : FirDeclaration abstract fun isInFriendModule(declaration: FirMemberDeclaration): Boolean
class Standard(val session: FirSession) : FirModuleVisibilityChecker() { class Standard(val session: FirSession) : FirModuleVisibilityChecker() {
override fun <T> isInFriendModule(declaration: T): Boolean where T : FirMemberDeclaration, T : FirDeclaration { override fun isInFriendModule(declaration: FirMemberDeclaration): Boolean {
val useSiteModuleData = session.moduleData val useSiteModuleData = session.moduleData
val declarationModuleData = declaration.moduleData val declarationModuleData = declaration.moduleData
return useSiteModuleData == declarationModuleData || declarationModuleData in useSiteModuleData.friendDependencies return useSiteModuleData == declarationModuleData || declarationModuleData in useSiteModuleData.friendDependencies
@@ -32,7 +32,6 @@ enum class FirImportingScopeFilter {
if (this == ALL) return true if (this == ALL) return true
// TODO: also check DeprecationLevel.HIDDEN and required Kotlin version // TODO: also check DeprecationLevel.HIDDEN and required Kotlin version
val fir = symbol.fir val fir = symbol.fir
if (fir !is FirMemberDeclaration) return false
val isVisible = when (fir.status.visibility) { val isVisible = when (fir.status.visibility) {
// When importing from the same module, status may be unknown because the status resolver depends on super types // When importing from the same module, status may be unknown because the status resolver depends on super types
// to determine visibility for functions, so it may not have finished yet. Since we only care about classes, // to determine visibility for functions, so it may not have finished yet. Since we only care about classes,
@@ -583,6 +583,7 @@ class DeclarationsConverter(
classKind = ClassKind.OBJECT classKind = ClassKind.OBJECT
scopeProvider = baseScopeProvider scopeProvider = baseScopeProvider
symbol = FirAnonymousObjectSymbol() symbol = FirAnonymousObjectSymbol()
status = FirDeclarationStatusImpl(Visibilities.Local, Modality.FINAL)
context.applyToActualCapturedTypeParameters(false) { context.applyToActualCapturedTypeParameters(false) {
typeParameters += buildOuterClassTypeParameterRef { this.symbol = it } typeParameters += buildOuterClassTypeParameterRef { this.symbol = it }
} }
@@ -702,6 +703,7 @@ class DeclarationsConverter(
classKind = ClassKind.ENUM_ENTRY classKind = ClassKind.ENUM_ENTRY
scopeProvider = baseScopeProvider scopeProvider = baseScopeProvider
symbol = FirAnonymousObjectSymbol() symbol = FirAnonymousObjectSymbol()
status = FirDeclarationStatusImpl(Visibilities.Local, Modality.FINAL)
val enumClassWrapper = ClassWrapper( val enumClassWrapper = ClassWrapper(
enumEntryName, modifiers, ClassKind.ENUM_ENTRY, this, enumEntryName, modifiers, ClassKind.ENUM_ENTRY, this,
hasPrimaryConstructor = true, hasPrimaryConstructor = true,
@@ -10,10 +10,7 @@ import com.intellij.psi.tree.IElementType
import org.jetbrains.kotlin.KtNodeTypes import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.builtins.StandardNames.BACKING_FIELD import org.jetbrains.kotlin.builtins.StandardNames.BACKING_FIELD
import org.jetbrains.kotlin.builtins.StandardNames.DEFAULT_VALUE_PARAMETER import org.jetbrains.kotlin.builtins.StandardNames.DEFAULT_VALUE_PARAMETER
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.* import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.*
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.contracts.FirContractDescription import org.jetbrains.kotlin.fir.contracts.FirContractDescription
@@ -966,6 +963,7 @@ open class RawFirBuilder(
classKind = ClassKind.ENUM_ENTRY classKind = ClassKind.ENUM_ENTRY
scopeProvider = this@RawFirBuilder.baseScopeProvider scopeProvider = this@RawFirBuilder.baseScopeProvider
symbol = FirAnonymousObjectSymbol() symbol = FirAnonymousObjectSymbol()
status = FirDeclarationStatusImpl(Visibilities.Local, Modality.FINAL)
val delegatedEntrySelfType = buildResolvedTypeRef { val delegatedEntrySelfType = buildResolvedTypeRef {
type = type =
@@ -1158,6 +1156,7 @@ open class RawFirBuilder(
classKind = ClassKind.OBJECT classKind = ClassKind.OBJECT
scopeProvider = baseScopeProvider scopeProvider = baseScopeProvider
symbol = FirAnonymousObjectSymbol() symbol = FirAnonymousObjectSymbol()
status = FirDeclarationStatusImpl(Visibilities.Local, Modality.FINAL)
context.applyToActualCapturedTypeParameters(false) { context.applyToActualCapturedTypeParameters(false) {
typeParameters += buildOuterClassTypeParameterRef { symbol = it } typeParameters += buildOuterClassTypeParameterRef { symbol = it }
} }
@@ -5,8 +5,11 @@
package org.jetbrains.kotlin.fir.resolve.transformers package org.jetbrains.kotlin.fir.resolve.transformers
import org.jetbrains.kotlin.descriptors.EffectiveVisibility
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
import org.jetbrains.kotlin.fir.declarations.utils.isLocal import org.jetbrains.kotlin.fir.declarations.utils.isLocal
import org.jetbrains.kotlin.fir.expressions.FirBlock import org.jetbrains.kotlin.fir.expressions.FirBlock
import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.expressions.FirStatement
@@ -316,6 +319,14 @@ abstract class AbstractFirStatusResolveTransformer(
anonymousObject: FirAnonymousObject, anonymousObject: FirAnonymousObject,
data: FirResolvedDeclarationStatus? data: FirResolvedDeclarationStatus?
): FirStatement { ): FirStatement {
anonymousObject.transformStatus(
this,
FirResolvedDeclarationStatusImpl(
anonymousObject.status.visibility,
anonymousObject.status.modality ?: Modality.FINAL,
EffectiveVisibility.Local
)
)
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
return transformClass(anonymousObject, data) return transformClass(anonymousObject, data)
} }
@@ -48,9 +48,9 @@ class FirStatusResolver(
private val extensionStatusTransformers = session.extensionService.statusTransformerExtensions private val extensionStatusTransformers = session.extensionService.statusTransformerExtensions
private inline fun <T> T.applyExtensionTransformers( private inline fun FirMemberDeclaration.applyExtensionTransformers(
operation: FirStatusTransformerExtension.(FirDeclarationStatus) -> FirDeclarationStatus operation: FirStatusTransformerExtension.(FirDeclarationStatus) -> FirDeclarationStatus
): FirDeclarationStatus where T : FirMemberDeclaration, T : FirAnnotatedDeclaration { ): FirDeclarationStatus {
if (extensionStatusTransformers.isEmpty()) return status if (extensionStatusTransformers.isEmpty()) return status
val declaration = this val declaration = this
return extensionStatusTransformers.fold(status) { acc, it -> return extensionStatusTransformers.fold(status) { acc, it ->
@@ -161,7 +161,7 @@ open class FirApplySupertypesTransformer(
} }
private fun FirClassLikeDeclaration.typeParametersScope(): FirScope? { private fun FirClassLikeDeclaration.typeParametersScope(): FirScope? {
if (this !is FirMemberDeclaration || typeParameters.isEmpty()) return null if (typeParameters.isEmpty()) return null
return FirMemberTypeParameterScope(this) return FirMemberTypeParameterScope(this)
} }
@@ -605,7 +605,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
if (type.typeArguments.isNotEmpty()) return this if (type.typeArguments.isNotEmpty()) return this
val firClass = type.lookupTag.toSymbol(session)?.fir ?: return this val firClass = type.lookupTag.toSymbol(session)?.fir ?: return this
if (firClass !is FirTypeParameterRefsOwner || firClass.typeParameters.isEmpty()) return this if (firClass.typeParameters.isEmpty()) return this
val originalType = argument.unwrapSmartcastExpression().typeRef.coneTypeSafe<ConeKotlinType>() ?: return this val originalType = argument.unwrapSmartcastExpression().typeRef.coneTypeSafe<ConeKotlinType>() ?: return this
val newType = components.computeRepresentativeTypeForBareType(type, originalType) ?: return buildErrorTypeRef { val newType = components.computeRepresentativeTypeForBareType(type, originalType) ?: return buildErrorTypeRef {
@@ -20,7 +20,7 @@ fun <F : FirClassLikeDeclaration> F.runAllPhasesForLocalClass(
firTowerDataContextCollector: FirTowerDataContextCollector?, firTowerDataContextCollector: FirTowerDataContextCollector?,
firProviderInterceptor: FirProviderInterceptor?, firProviderInterceptor: FirProviderInterceptor?,
): F { ): F {
if (this is FirMemberDeclaration && status is FirResolvedDeclarationStatus) return this if (status is FirResolvedDeclarationStatus) return this
if (this is FirRegularClass) { if (this is FirRegularClass) {
components.context.storeClassIfNotNested(this) components.context.storeClassIfNotNested(this)
} }
@@ -381,7 +381,6 @@ open class FirRenderer(builder: StringBuilder, protected val mode: RenderMode =
memberDeclaration.typeParameters.renderTypeParameters() memberDeclaration.typeParameters.renderTypeParameters()
} }
} }
else -> {}
} }
} }
@@ -24,8 +24,7 @@ private object DanglingTypeConstraintsKey : FirDeclarationDataKey()
var FirProperty.isFromVararg: Boolean? by FirDeclarationDataRegistry.data(IsFromVarargKey) var FirProperty.isFromVararg: Boolean? by FirDeclarationDataRegistry.data(IsFromVarargKey)
var FirProperty.isReferredViaField: Boolean? by FirDeclarationDataRegistry.data(IsReferredViaField) var FirProperty.isReferredViaField: Boolean? by FirDeclarationDataRegistry.data(IsReferredViaField)
var FirProperty.fromPrimaryConstructor: Boolean? by FirDeclarationDataRegistry.data(IsFromPrimaryConstructor) var FirProperty.fromPrimaryConstructor: Boolean? by FirDeclarationDataRegistry.data(IsFromPrimaryConstructor)
var FirTypeAlias.sourceElement: SourceElement? by FirDeclarationDataRegistry.data(SourceElementKey) var FirClassLikeDeclaration.sourceElement: SourceElement? by FirDeclarationDataRegistry.data(SourceElementKey)
var FirRegularClass.sourceElement: SourceElement? by FirDeclarationDataRegistry.data(SourceElementKey)
var FirRegularClass.moduleName: String? by FirDeclarationDataRegistry.data(ModuleNameKey) var FirRegularClass.moduleName: String? by FirDeclarationDataRegistry.data(ModuleNameKey)
/** /**
@@ -42,8 +41,7 @@ var <T> T.danglingTypeConstraints: List<DanglingTypeConstraint>?
val FirMemberDeclaration.containerSource: SourceElement? val FirMemberDeclaration.containerSource: SourceElement?
get() = when (this) { get() = when (this) {
is FirCallableDeclaration -> containerSource is FirCallableDeclaration -> containerSource
is FirRegularClass -> sourceElement is FirClassLikeDeclaration -> sourceElement
is FirTypeAlias -> sourceElement
} }
val FirProperty.hasExplicitBackingField: Boolean val FirProperty.hasExplicitBackingField: Boolean
@@ -27,13 +27,13 @@ object FirTreeBuilder : AbstractFirTreeBuilder() {
val statement by element(Expression, annotationContainer) val statement by element(Expression, annotationContainer)
val expression by element(Expression, statement) val expression by element(Expression, statement)
val declaration by sealedElement(Declaration) val declaration by sealedElement(Declaration)
val annotatedDeclaration by sealedElement(Declaration, declaration, annotationContainer)
val anonymousInitializer by element(Declaration, declaration, controlFlowGraphOwner)
val typedDeclaration by sealedElement(Declaration, annotatedDeclaration)
val typeParameterRefsOwner by sealedElement(Declaration) val typeParameterRefsOwner by sealedElement(Declaration)
val typeParametersOwner by sealedElement(Declaration, typeParameterRefsOwner) val typeParametersOwner by sealedElement(Declaration, typeParameterRefsOwner)
val memberDeclaration by sealedElement(Declaration, typeParameterRefsOwner) val annotatedDeclaration by sealedElement(Declaration, declaration, annotationContainer)
val callableDeclaration by sealedElement(Declaration, typedDeclaration, memberDeclaration) val memberDeclaration by sealedElement(Declaration, annotatedDeclaration, typeParameterRefsOwner)
val anonymousInitializer by element(Declaration, declaration, controlFlowGraphOwner)
val typedDeclaration by sealedElement(Declaration, memberDeclaration)
val callableDeclaration by sealedElement(Declaration, typedDeclaration)
val typeParameterRef by element(Declaration) val typeParameterRef by element(Declaration)
val typeParameter by element(Declaration, typeParameterRef, annotatedDeclaration) val typeParameter by element(Declaration, typeParameterRef, annotatedDeclaration)
@@ -43,10 +43,10 @@ object FirTreeBuilder : AbstractFirTreeBuilder() {
val field by element(Declaration, variable) val field by element(Declaration, variable)
val enumEntry by element(Declaration, variable) val enumEntry by element(Declaration, variable)
val classLikeDeclaration by sealedElement(Declaration, annotatedDeclaration, statement) val classLikeDeclaration by sealedElement(Declaration, memberDeclaration, statement)
val klass by sealedElement("Class", Declaration, classLikeDeclaration, statement, typeParameterRefsOwner) val klass by sealedElement("Class", Declaration, classLikeDeclaration, statement, typeParameterRefsOwner)
val regularClass by element(Declaration, klass, memberDeclaration, controlFlowGraphOwner) val regularClass by element(Declaration, klass, controlFlowGraphOwner)
val typeAlias by element(Declaration, classLikeDeclaration, memberDeclaration, typeParametersOwner) val typeAlias by element(Declaration, classLikeDeclaration, typeParametersOwner)
val function by sealedElement(Declaration, callableDeclaration, targetElement, controlFlowGraphOwner, statement) val function by sealedElement(Declaration, callableDeclaration, targetElement, controlFlowGraphOwner, statement)