[FIR] Unity FirCallableDeclaration and FirCallableMemberDeclaration

After removal of all diamonds in FirDeclaration hierarchy
  FirCallableMemberDeclaration was only one inheritor of
  FirCallableDeclaration, so there is no need to keep them both
This commit is contained in:
Dmitriy Novozhilov
2021-07-12 11:11:29 +03:00
committed by teamcityserver
parent adc45fd3dd
commit 51fc2e453f
103 changed files with 403 additions and 516 deletions
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClass
import org.jetbrains.kotlin.fir.analysis.checkers.unsubstitutedScope
import org.jetbrains.kotlin.fir.containingClass
import org.jetbrains.kotlin.fir.declarations.FirCallableMemberDeclaration
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
@@ -56,7 +55,7 @@ object FirJvmOverridesBackwardCompatibilityHelper : FirOverridesBackwardCompatib
visitedSymbols: MutableSet<FirCallableSymbol<*>>,
context: CheckerContext
): Boolean {
val fir = symbol.fir as? FirCallableMemberDeclaration ?: return false
val fir = symbol.fir
if (fir.isFinal) return false
if (symbol in visitedSymbols) return true
@@ -135,7 +135,7 @@ inline fun <reified T : Any> FirQualifiedAccessExpression.getDeclaration(): T? {
* or null if no proper declaration has been found.
*/
fun FirDeclaration.getContainingClass(context: CheckerContext): FirClassLikeDeclaration? =
this.safeAs<FirCallableMemberDeclaration>()?.containingClass()?.toSymbol(context.session)?.fir
this.safeAs<FirCallableDeclaration>()?.containingClass()?.toSymbol(context.session)?.fir
fun FirClassLikeSymbol<*>.outerClass(context: CheckerContext): FirClassLikeSymbol<*>? {
if (this !is FirClassSymbol<*>) return null
@@ -417,7 +417,7 @@ private fun isSubtypeOfForFunctionalTypeReturningUnit(
return false
}
fun FirCallableMemberDeclaration.isVisibleInClass(parentClass: FirClass): Boolean {
fun FirCallableDeclaration.isVisibleInClass(parentClass: FirClass): Boolean {
val classPackage = parentClass.symbol.classId.packageFqName
if (visibility == Visibilities.Private ||
!visibility.visibleFromPackage(classPackage, symbol.callableId.packageName)
@@ -434,7 +434,7 @@ fun FirCallableMemberDeclaration.isVisibleInClass(parentClass: FirClass): Boolea
*
* @param parentClass the contextual class for this query.
*/
fun FirCallableMemberDeclaration.getImplementationStatus(sessionHolder: SessionHolder, parentClass: FirClass): ImplementationStatus {
fun FirCallableDeclaration.getImplementationStatus(sessionHolder: SessionHolder, parentClass: FirClass): ImplementationStatus {
val containingClass = getContainingClass(sessionHolder)
val symbol = this.symbol
@@ -449,13 +449,13 @@ fun FirCallableMemberDeclaration.getImplementationStatus(sessionHolder: SessionH
// In Java 8, non-abstract intersection overrides having abstract symbol from base class
// still should be implemented in current class (even when they have default interface implementation)
if (symbol.intersections.any {
val fir = (it.fir as FirCallableMemberDeclaration).unwrapFakeOverrides()
val fir = it.fir.unwrapFakeOverrides()
fir.isAbstract && (fir.getContainingClass(sessionHolder) as? FirRegularClass)?.classKind == ClassKind.CLASS
}
) {
// Exception from the rule above: interface implementation via delegation
if (symbol.intersections.none {
val fir = (it.fir as FirCallableMemberDeclaration)
val fir = it.fir
fir.origin == FirDeclarationOrigin.Delegated && !fir.isAbstract
}
) {
@@ -487,7 +487,7 @@ private fun FirIntersectionCallableSymbol.subjectToManyNotImplemented(sessionHol
var nonAbstractCountInInterface = 0
var abstractCountInInterface = 0
for (intersectionSymbol in intersections) {
val intersection = intersectionSymbol.fir as FirCallableMemberDeclaration
val intersection = intersectionSymbol.fir
val containingClass = intersection.getContainingClass(sessionHolder) as? FirRegularClass
val hasInterfaceContainer = containingClass?.classKind == ClassKind.INTERFACE
if (intersection.modality != Modality.ABSTRACT) {
@@ -515,7 +515,7 @@ private val FirSimpleFunction.matchesDataClassSyntheticMemberSignatures: Boolean
(this.name == OperatorNameConventions.TO_STRING && matchesToStringSignature)
private fun FirDeclaration.getContainingClass(sessionHolder: SessionHolder): FirClassLikeDeclaration? =
this.safeAs<FirCallableMemberDeclaration>()?.containingClass()?.toSymbol(sessionHolder.session)?.fir
this.safeAs<FirCallableDeclaration>()?.containingClass()?.toSymbol(sessionHolder.session)?.fir
// NB: we intentionally do not check return types
private val FirSimpleFunction.matchesEqualsSignature: Boolean
@@ -207,7 +207,7 @@ internal val FirDeclaration.isLocalMember: Boolean
else -> false
}
internal val FirCallableMemberDeclaration.isExtensionMember: Boolean
internal val FirCallableDeclaration.isExtensionMember: Boolean
get() {
return receiverTypeRef != null && dispatchReceiverType != null
}
@@ -141,7 +141,7 @@ object FirExposedVisibilityDeclarationChecker : FirBasicDeclarationChecker() {
}
}
}
checkMemberReceiver(declaration.receiverTypeRef, declaration as? FirCallableMemberDeclaration, reporter, context)
checkMemberReceiver(declaration.receiverTypeRef, declaration as? FirCallableDeclaration, reporter, context)
}
private fun checkProperty(declaration: FirProperty, reporter: DiagnosticReporter, context: CheckerContext) {
@@ -172,7 +172,7 @@ object FirExposedVisibilityDeclarationChecker : FirBasicDeclarationChecker() {
private fun checkMemberReceiver(
typeRef: FirTypeRef?,
memberDeclaration: FirCallableMemberDeclaration?,
memberDeclaration: FirCallableDeclaration?,
reporter: DiagnosticReporter,
context: CheckerContext
) {
@@ -175,7 +175,7 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
) {
val source = qualifiedAccess.source ?: return
if (targetSymbol == null) return
val targetFir = targetSymbol.fir as? FirCallableMemberDeclaration
val targetFir = targetSymbol.fir as? FirCallableDeclaration
if (targetSymbol.fir in inlinableParameters) {
if (!qualifiedAccess.partOfCall(context)) {
@@ -199,7 +199,7 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
private fun checkVisibilityAndAccess(
accessExpression: FirQualifiedAccess,
calledDeclaration: FirCallableMemberDeclaration?,
calledDeclaration: FirCallableDeclaration?,
source: FirSourceElement,
context: CheckerContext
) {
@@ -248,7 +248,7 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
}
private fun checkPrivateClassMemberAccess(
calledDeclaration: FirCallableMemberDeclaration,
calledDeclaration: FirCallableDeclaration,
source: FirSourceElement,
context: CheckerContext
) {
@@ -266,7 +266,7 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
}
private fun checkSuperCalls(
calledDeclaration: FirCallableMemberDeclaration,
calledDeclaration: FirCallableDeclaration,
callExpression: FirQualifiedAccess,
context: CheckerContext
) {
@@ -305,7 +305,7 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
}
}
private fun FirCallableMemberDeclaration.isInsidePrivateClass(): Boolean {
private fun FirCallableDeclaration.isInsidePrivateClass(): Boolean {
val containingClass = this.containingClass()?.toSymbol(session)?.fir ?: return false
val containingClassVisibility = when (containingClass) {
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirCallableMemberDeclaration
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeTypeParameterInQualifiedAccess
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.fir.types.*
object FirKClassWithIncorrectTypeArgumentChecker : FirFileChecker() {
override fun check(declaration: FirFile, context: CheckerContext, reporter: DiagnosticReporter) {
for (topLevelDeclaration in declaration.declarations) {
if (topLevelDeclaration is FirCallableMemberDeclaration) {
if (topLevelDeclaration is FirCallableDeclaration) {
checkTopLevelDeclaration(topLevelDeclaration, context, reporter)
}
}
@@ -33,7 +33,7 @@ object FirKClassWithIncorrectTypeArgumentChecker : FirFileChecker() {
// bad: fun <T> test1() = T::class
// okay: fun <T: Any> test2() = T::class
private fun checkTopLevelDeclaration(
declaration: FirCallableMemberDeclaration,
declaration: FirCallableDeclaration,
context: CheckerContext,
reporter: DiagnosticReporter
) {
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OVERRIDING_FINAL_
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.containingClass
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirCallableMemberDeclaration
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.utils.*
@@ -59,7 +58,7 @@ object FirNotImplementedOverrideChecker : FirClassChecker() {
val invisibleSymbols = mutableListOf<FirCallableSymbol<*>>()
fun collectSymbol(symbol: FirCallableSymbol<*>) {
val fir = symbol.fir as? FirCallableMemberDeclaration ?: return
val fir = symbol.fir
val delegatedWrapperData = fir.delegatedWrapperData
if (delegatedWrapperData != null) {
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.hasModifier
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirCallableMemberDeclaration
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirConstructor
import org.jetbrains.kotlin.fir.declarations.utils.isOpen
@@ -24,7 +24,7 @@ object FirOpenMemberChecker : FirClassChecker() {
override fun check(declaration: FirClass, context: CheckerContext, reporter: DiagnosticReporter) {
if (declaration.canHaveOpenMembers) return
for (memberDeclaration in declaration.declarations) {
if (memberDeclaration !is FirCallableMemberDeclaration ||
if (memberDeclaration !is FirCallableDeclaration ||
// Marking a constructor `open` is an error covered by diagnostic code WRONG_MODIFIER_TARGET
memberDeclaration is FirConstructor
) continue
@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.overridesBackwardCompatibilityHelper
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.isFinal
import org.jetbrains.kotlin.fir.declarations.utils.isOverride
import org.jetbrains.kotlin.fir.declarations.utils.visibility
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
@@ -46,12 +45,12 @@ object FirOverrideChecker : FirClassChecker() {
for (it in declaration.declarations) {
if (it is FirSimpleFunction || it is FirProperty) {
checkMember(it as FirCallableMemberDeclaration, declaration, reporter, typeCheckerContext, firTypeScope, context)
checkMember(it as FirCallableDeclaration, declaration, reporter, typeCheckerContext, firTypeScope, context)
}
}
}
private fun FirTypeScope.retrieveDirectOverriddenOf(member: FirCallableMemberDeclaration): List<FirCallableSymbol<*>> {
private fun FirTypeScope.retrieveDirectOverriddenOf(member: FirCallableDeclaration): List<FirCallableSymbol<*>> {
return when (member) {
is FirSimpleFunction -> {
processFunctionsByName(member.name) {}
@@ -66,7 +65,7 @@ object FirOverrideChecker : FirClassChecker() {
}
private fun ConeKotlinType.substituteAllTypeParameters(
overrideDeclaration: FirCallableMemberDeclaration,
overrideDeclaration: FirCallableDeclaration,
baseDeclaration: FirCallableDeclaration,
context: CheckerContext
): ConeKotlinType {
@@ -94,7 +93,6 @@ object FirOverrideChecker : FirClassChecker() {
overriddenSymbols: List<FirCallableSymbol<*>>,
): FirCallableDeclaration? {
for (overridden in overriddenSymbols) {
if (overridden.fir !is FirMemberDeclaration) continue
val modality = (overridden.fir as FirMemberDeclaration).status.modality
val isEffectivelyFinal = modality == null || modality == Modality.FINAL
if (isEffectivelyFinal) {
@@ -111,14 +109,13 @@ object FirOverrideChecker : FirClassChecker() {
return overriddenSymbols.find { (it.fir as? FirProperty)?.isVar == true }?.fir as? FirMemberDeclaration?
}
private fun FirCallableMemberDeclaration.checkVisibility(
private fun FirCallableDeclaration.checkVisibility(
containingClass: FirClass,
reporter: DiagnosticReporter,
overriddenSymbols: List<FirCallableSymbol<*>>,
context: CheckerContext
) {
val visibilities = overriddenSymbols.mapNotNull {
if (it.fir !is FirMemberDeclaration) return@mapNotNull null
val visibilities = overriddenSymbols.map {
it to (it.fir as FirMemberDeclaration).visibility
}.sortedBy { pair ->
// Regard `null` compare as Int.MIN so that we can report CANNOT_CHANGE_... first deterministically
@@ -140,7 +137,7 @@ object FirOverrideChecker : FirClassChecker() {
val containingDeclarations = context.containingDeclarations + containingClass
val visibilityChecker = context.session.visibilityChecker
val hasVisibleBase = overriddenSymbols.any {
val fir = it.fir as? FirCallableMemberDeclaration ?: return@any true
val fir = it.fir as? FirCallableDeclaration ?: return@any true
visibilityChecker.isVisible(fir, context.session, file, containingDeclarations, null)
}
if (!hasVisibleBase) {
@@ -152,7 +149,7 @@ object FirOverrideChecker : FirClassChecker() {
}
// See [OverrideResolver#isReturnTypeOkForOverride]
private fun FirCallableMemberDeclaration.checkReturnType(
private fun FirCallableDeclaration.checkReturnType(
overriddenSymbols: List<FirCallableSymbol<*>>,
typeCheckerContext: AbstractTypeCheckerContext,
context: CheckerContext,
@@ -186,12 +183,12 @@ object FirOverrideChecker : FirClassChecker() {
}
private fun checkMember(
member: FirCallableMemberDeclaration,
member: FirCallableDeclaration,
containingClass: FirClass,
reporter: DiagnosticReporter,
typeCheckerContext: AbstractTypeCheckerContext,
firTypeScope: FirTypeScope,
context: CheckerContext
context: CheckerContext,
) {
val overriddenMemberSymbols = firTypeScope.retrieveDirectOverriddenOf(member)
@@ -203,29 +200,15 @@ object FirOverrideChecker : FirClassChecker() {
}
val kind = member.source?.kind
// Only report if the current member has real source or it's a member property declared inside the primary constructor.
if (kind is FirFakeSourceElementKind.DataClassGeneratedMembers) {
overriddenMemberSymbols.find { (it.fir as? FirCallableMemberDeclaration)?.isFinal == true }?.let { base ->
reporter.reportOn(
containingClass.source,
FirErrors.DATA_CLASS_OVERRIDE_CONFLICT,
member,
base.fir,
context
)
}
return
}
if (kind !is FirRealSourceElementKind && kind !is FirFakeSourceElementKind.PropertyFromParameter) return
val overridden = overriddenMemberSymbols.first().originalOrSelf()
val overriddenClass = overridden.containingClass()?.toFirRegularClass(context.session) ?: return
val originalContainigClass = overridden.containingClass()?.toFirRegularClass(context.session) ?: return
reporter.reportOn(
member.source,
FirErrors.VIRTUAL_MEMBER_HIDDEN,
member,
overriddenClass,
originalContainigClass,
context
)
return
@@ -265,8 +248,10 @@ object FirOverrideChecker : FirClassChecker() {
}
}
@Suppress("UNUSED_PARAMETER") // TODO: delete me after implementing body
private fun DiagnosticReporter.reportNothingToOverride(declaration: FirMemberDeclaration, context: CheckerContext) {
reportOn(declaration.source, FirErrors.NOTHING_TO_OVERRIDE, declaration, context)
// TODO: not ready yet, e.g., Collections
// reportOn(declaration.source, FirErrors.NOTHING_TO_OVERRIDE, declaration, context)
}
private fun DiagnosticReporter.reportOverridingFinalMember(
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.getDeclaration
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirCallableMemberDeclaration
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.utils.modality
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
@@ -33,7 +33,7 @@ object FirAbstractSuperCallChecker : FirQualifiedAccessExpressionChecker() {
if (closestClass.classKind == ClassKind.CLASS) {
// handles all the FirSimpleFunction/FirProperty/etc.
val item = expression.getDeclaration<FirCallableMemberDeclaration>()
val item = expression.getDeclaration<FirCallableDeclaration>()
?: return
val declaration = item.getContainingClass(context).safeAs<FirRegularClass>()
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.declaration.isLocalMember
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirCallableMemberDeclaration
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirConstructor
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
@@ -49,7 +49,7 @@ object FirCallableReferenceChecker : FirQualifiedAccessExpressionChecker() {
if (referredDeclaration is FirConstructor && referredDeclaration.getContainingClass(context.session)?.classKind == ClassKind.ANNOTATION_CLASS) {
reporter.reportOn(source, FirErrors.CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR, context)
}
if ((referredDeclaration as? FirCallableMemberDeclaration)?.isExtensionMember == true &&
if ((referredDeclaration as? FirCallableDeclaration)?.isExtensionMember == true &&
!referredDeclaration.isLocalMember
) {
reporter.reportOn(source, FirErrors.EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED, referredDeclaration, context)