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.psi.KtDeclaration
internal fun <F> KtFirSymbol<F>.getModality(
internal fun KtFirSymbol<FirMemberDeclaration>.getModality(
phase: FirResolvePhase = FirResolvePhase.STATUS,
defaultModality: Modality? = null
): Modality where F : FirDeclaration, F : FirMemberDeclaration {
): Modality {
return firRef.withFir(phase) { fir ->
fir.modality
?: 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
): Visibility where F : FirMemberDeclaration, F : FirDeclaration =
): Visibility =
firRef.withFir(phase) { fir -> fir.visibility }
internal fun KtFirSymbol<FirCallableDeclaration>.getCallableIdIfNonLocal(): CallableId? =
@@ -247,7 +247,6 @@ fun FirMemberDeclaration.implicitModality(context: CheckerContext): Modality {
&& klass.classKind == ClassKind.INTERFACE
&& tree.visibilityModifier(source.lighterASTNode)?.tokenType != KtTokens.PRIVATE_KEYWORD
) {
require(this is FirDeclaration)
return if (this.hasBody()) Modality.OPEN else Modality.ABSTRACT
}
@@ -40,12 +40,12 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() {
}
}
private fun <T> checkActualDeclarationHasExpected(
declaration: T,
private fun checkActualDeclarationHasExpected(
declaration: FirMemberDeclaration,
context: CheckerContext,
reporter: DiagnosticReporter,
checkActual: Boolean = true
) where T : FirDeclaration, T : FirMemberDeclaration {
) {
val scopeSession = ScopeSession()
val symbol = declaration.symbol
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 firClassLikeDeclaration = symbol.fir
if (firClassLikeDeclaration !is FirMemberDeclaration) return
if (!context.session.visibilityChecker.isVisible(
firClassLikeDeclaration, context.session, firFile, context.containingDeclarations,
@@ -50,8 +50,7 @@ object RedundantVisibilityModifierSyntaxChecker : FirDeclarationSyntaxChecker<Fi
val explicitVisibility = (visibilityModifier?.tokenType as? KtModifierKeywordToken)?.toVisibilityOrNull()
val implicitVisibility = element.implicitVisibility(context)
val containingMemberDeclaration = context.findClosest<FirMemberDeclaration>()
require(containingMemberDeclaration is FirDeclaration?)
val isHidden = explicitVisibility.isEffectivelyHiddenBy(containingMemberDeclaration)
if (explicitVisibility != implicitVisibility && !isHidden) {
@@ -1780,7 +1780,7 @@ class HtmlFirDump internal constructor(private var linkResolver: FirLinkResolver
private fun FlowContent.generate(declaration: FirDeclaration) {
when (declaration) {
is FirAnonymousInitializer -> generate(declaration)
is FirMemberDeclaration -> generate(declaration as FirMemberDeclaration)
is FirMemberDeclaration -> generate(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.lookupSuperTypes
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.typeWithStarProjections
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
@@ -32,10 +33,10 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.types.AbstractTypeChecker
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() {
override fun <T> isInFriendModule(declaration: T): Boolean where T : FirMemberDeclaration, T : FirDeclaration {
override fun isInFriendModule(declaration: FirMemberDeclaration): Boolean {
val useSiteModuleData = session.moduleData
val declarationModuleData = declaration.moduleData
return useSiteModuleData == declarationModuleData || declarationModuleData in useSiteModuleData.friendDependencies
@@ -32,7 +32,6 @@ enum class FirImportingScopeFilter {
if (this == ALL) return true
// TODO: also check DeprecationLevel.HIDDEN and required Kotlin version
val fir = symbol.fir
if (fir !is FirMemberDeclaration) return false
val isVisible = when (fir.status.visibility) {
// 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,
@@ -583,6 +583,7 @@ class DeclarationsConverter(
classKind = ClassKind.OBJECT
scopeProvider = baseScopeProvider
symbol = FirAnonymousObjectSymbol()
status = FirDeclarationStatusImpl(Visibilities.Local, Modality.FINAL)
context.applyToActualCapturedTypeParameters(false) {
typeParameters += buildOuterClassTypeParameterRef { this.symbol = it }
}
@@ -702,6 +703,7 @@ class DeclarationsConverter(
classKind = ClassKind.ENUM_ENTRY
scopeProvider = baseScopeProvider
symbol = FirAnonymousObjectSymbol()
status = FirDeclarationStatusImpl(Visibilities.Local, Modality.FINAL)
val enumClassWrapper = ClassWrapper(
enumEntryName, modifiers, ClassKind.ENUM_ENTRY, this,
hasPrimaryConstructor = true,
@@ -10,10 +10,7 @@ import com.intellij.psi.tree.IElementType
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.builtins.StandardNames.BACKING_FIELD
import org.jetbrains.kotlin.builtins.StandardNames.DEFAULT_VALUE_PARAMETER
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.*
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.contracts.FirContractDescription
@@ -966,6 +963,7 @@ open class RawFirBuilder(
classKind = ClassKind.ENUM_ENTRY
scopeProvider = this@RawFirBuilder.baseScopeProvider
symbol = FirAnonymousObjectSymbol()
status = FirDeclarationStatusImpl(Visibilities.Local, Modality.FINAL)
val delegatedEntrySelfType = buildResolvedTypeRef {
type =
@@ -1158,6 +1156,7 @@ open class RawFirBuilder(
classKind = ClassKind.OBJECT
scopeProvider = baseScopeProvider
symbol = FirAnonymousObjectSymbol()
status = FirDeclarationStatusImpl(Visibilities.Local, Modality.FINAL)
context.applyToActualCapturedTypeParameters(false) {
typeParameters += buildOuterClassTypeParameterRef { symbol = it }
}
@@ -5,8 +5,11 @@
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.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
import org.jetbrains.kotlin.fir.expressions.FirBlock
import org.jetbrains.kotlin.fir.expressions.FirStatement
@@ -316,6 +319,14 @@ abstract class AbstractFirStatusResolveTransformer(
anonymousObject: FirAnonymousObject,
data: FirResolvedDeclarationStatus?
): FirStatement {
anonymousObject.transformStatus(
this,
FirResolvedDeclarationStatusImpl(
anonymousObject.status.visibility,
anonymousObject.status.modality ?: Modality.FINAL,
EffectiveVisibility.Local
)
)
@Suppress("UNCHECKED_CAST")
return transformClass(anonymousObject, data)
}
@@ -48,9 +48,9 @@ class FirStatusResolver(
private val extensionStatusTransformers = session.extensionService.statusTransformerExtensions
private inline fun <T> T.applyExtensionTransformers(
private inline fun FirMemberDeclaration.applyExtensionTransformers(
operation: FirStatusTransformerExtension.(FirDeclarationStatus) -> FirDeclarationStatus
): FirDeclarationStatus where T : FirMemberDeclaration, T : FirAnnotatedDeclaration {
): FirDeclarationStatus {
if (extensionStatusTransformers.isEmpty()) return status
val declaration = this
return extensionStatusTransformers.fold(status) { acc, it ->
@@ -161,7 +161,7 @@ open class FirApplySupertypesTransformer(
}
private fun FirClassLikeDeclaration.typeParametersScope(): FirScope? {
if (this !is FirMemberDeclaration || typeParameters.isEmpty()) return null
if (typeParameters.isEmpty()) return null
return FirMemberTypeParameterScope(this)
}
@@ -605,7 +605,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
if (type.typeArguments.isNotEmpty()) 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 newType = components.computeRepresentativeTypeForBareType(type, originalType) ?: return buildErrorTypeRef {
@@ -20,7 +20,7 @@ fun <F : FirClassLikeDeclaration> F.runAllPhasesForLocalClass(
firTowerDataContextCollector: FirTowerDataContextCollector?,
firProviderInterceptor: FirProviderInterceptor?,
): F {
if (this is FirMemberDeclaration && status is FirResolvedDeclarationStatus) return this
if (status is FirResolvedDeclarationStatus) return this
if (this is FirRegularClass) {
components.context.storeClassIfNotNested(this)
}
@@ -381,7 +381,6 @@ open class FirRenderer(builder: StringBuilder, protected val mode: RenderMode =
memberDeclaration.typeParameters.renderTypeParameters()
}
}
else -> {}
}
}
@@ -24,8 +24,7 @@ private object DanglingTypeConstraintsKey : FirDeclarationDataKey()
var FirProperty.isFromVararg: Boolean? by FirDeclarationDataRegistry.data(IsFromVarargKey)
var FirProperty.isReferredViaField: Boolean? by FirDeclarationDataRegistry.data(IsReferredViaField)
var FirProperty.fromPrimaryConstructor: Boolean? by FirDeclarationDataRegistry.data(IsFromPrimaryConstructor)
var FirTypeAlias.sourceElement: SourceElement? by FirDeclarationDataRegistry.data(SourceElementKey)
var FirRegularClass.sourceElement: SourceElement? by FirDeclarationDataRegistry.data(SourceElementKey)
var FirClassLikeDeclaration.sourceElement: SourceElement? by FirDeclarationDataRegistry.data(SourceElementKey)
var FirRegularClass.moduleName: String? by FirDeclarationDataRegistry.data(ModuleNameKey)
/**
@@ -42,8 +41,7 @@ var <T> T.danglingTypeConstraints: List<DanglingTypeConstraint>?
val FirMemberDeclaration.containerSource: SourceElement?
get() = when (this) {
is FirCallableDeclaration -> containerSource
is FirRegularClass -> sourceElement
is FirTypeAlias -> sourceElement
is FirClassLikeDeclaration -> sourceElement
}
val FirProperty.hasExplicitBackingField: Boolean
@@ -27,13 +27,13 @@ object FirTreeBuilder : AbstractFirTreeBuilder() {
val statement by element(Expression, annotationContainer)
val expression by element(Expression, statement)
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 typeParametersOwner by sealedElement(Declaration, typeParameterRefsOwner)
val memberDeclaration by sealedElement(Declaration, typeParameterRefsOwner)
val callableDeclaration by sealedElement(Declaration, typedDeclaration, memberDeclaration)
val annotatedDeclaration by sealedElement(Declaration, declaration, annotationContainer)
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 typeParameter by element(Declaration, typeParameterRef, annotatedDeclaration)
@@ -43,10 +43,10 @@ object FirTreeBuilder : AbstractFirTreeBuilder() {
val field 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 regularClass by element(Declaration, klass, memberDeclaration, controlFlowGraphOwner)
val typeAlias by element(Declaration, classLikeDeclaration, memberDeclaration, typeParametersOwner)
val regularClass by element(Declaration, klass, controlFlowGraphOwner)
val typeAlias by element(Declaration, classLikeDeclaration, typeParametersOwner)
val function by sealedElement(Declaration, callableDeclaration, targetElement, controlFlowGraphOwner, statement)