FIR checker: apply member checkers to anonymous objects

because they can have member properties/functions too.
This commit is contained in:
Jinseong Jeon
2021-06-22 23:36:34 -07:00
committed by TeamCityServer
parent 64a275cf83
commit cd78a156c5
5 changed files with 28 additions and 23 deletions
@@ -64,6 +64,8 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
FirOpenMemberChecker,
FirClassVarianceChecker,
FirSealedSupertypeChecker,
FirMemberFunctionsChecker,
FirMemberPropertiesChecker,
)
override val regularClassCheckers: Set<FirRegularClassChecker>
@@ -83,8 +85,6 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
FirPrimaryConstructorSuperTypeChecker,
FirTypeParametersInObjectChecker,
FirFunInterfaceDeclarationChecker,
FirMemberFunctionsChecker,
FirMemberPropertiesChecker,
FirNestedClassChecker,
FirInlineClassDeclarationChecker,
)
@@ -25,26 +25,26 @@ import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLookupTagWithFixedSymbol
import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
import org.jetbrains.kotlin.lexer.KtTokens
internal fun isInsideExpectClass(containingClass: FirRegularClass, context: CheckerContext): Boolean {
return isInsideSpecificClass(containingClass, context) { klass -> klass.isExpect }
internal fun isInsideExpectClass(containingClass: FirClass, context: CheckerContext): Boolean {
return isInsideSpecificClass(containingClass, context) { klass -> klass is FirRegularClass && klass.isExpect }
}
internal fun isInsideExternalClass(containingClass: FirRegularClass, context: CheckerContext): Boolean {
return isInsideSpecificClass(containingClass, context) { klass -> klass.isExternal }
internal fun isInsideExternalClass(containingClass: FirClass, context: CheckerContext): Boolean {
return isInsideSpecificClass(containingClass, context) { klass -> klass is FirRegularClass && klass.isExternal }
}
// Note that the class that contains the currently visiting declaration will *not* be in the context's containing declarations *yet*.
private inline fun isInsideSpecificClass(
containingClass: FirRegularClass,
containingClass: FirClass,
context: CheckerContext,
predicate: (FirRegularClass) -> Boolean
predicate: (FirClass) -> Boolean
): Boolean {
return predicate.invoke(containingClass) ||
context.containingDeclarations.asReversed().any { it is FirRegularClass && predicate.invoke(it) }
}
internal fun FirMemberDeclaration.isEffectivelyExpect(
containingClass: FirRegularClass?,
containingClass: FirClass?,
context: CheckerContext,
): Boolean {
if (this.isExpect) return true
@@ -53,7 +53,7 @@ internal fun FirMemberDeclaration.isEffectivelyExpect(
}
internal fun FirMemberDeclaration.isEffectivelyExternal(
containingClass: FirRegularClass?,
containingClass: FirClass?,
context: CheckerContext,
): Boolean {
if (this.isExternal) return true
@@ -93,7 +93,7 @@ internal fun checkExpectDeclarationVisibilityAndBody(
// Matched FE 1.0's [DeclarationsChecker#checkPropertyInitializer].
internal fun checkPropertyInitializer(
containingClass: FirRegularClass?,
containingClass: FirClass?,
property: FirProperty,
modifierList: FirModifierList?,
isInitialized: Boolean,
@@ -18,8 +18,8 @@ import org.jetbrains.kotlin.fir.declarations.utils.*
import org.jetbrains.kotlin.lexer.KtTokens
// See old FE's [DeclarationsChecker]
object FirMemberFunctionsChecker : FirRegularClassChecker() {
override fun check(declaration: FirRegularClass, context: CheckerContext, reporter: DiagnosticReporter) {
object FirMemberFunctionsChecker : FirClassChecker() {
override fun check(declaration: FirClass, context: CheckerContext, reporter: DiagnosticReporter) {
for (member in declaration.declarations) {
if (member is FirSimpleFunction) {
checkFunction(declaration, member, context, reporter)
@@ -28,7 +28,7 @@ object FirMemberFunctionsChecker : FirRegularClassChecker() {
}
private fun checkFunction(
containingDeclaration: FirRegularClass,
containingDeclaration: FirClass,
function: FirSimpleFunction,
context: CheckerContext,
reporter: DiagnosticReporter
@@ -41,7 +41,7 @@ object FirMemberFunctionsChecker : FirRegularClassChecker() {
val hasAbstractModifier = KtTokens.ABSTRACT_KEYWORD in modifierList
val isAbstract = function.isAbstract || hasAbstractModifier
if (isAbstract) {
if (!containingDeclaration.canHaveAbstractDeclaration) {
if (containingDeclaration is FirRegularClass && !containingDeclaration.canHaveAbstractDeclaration) {
reporter.reportOn(
source,
FirErrors.ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS,
@@ -30,8 +30,8 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.lexer.KtTokens
// See old FE's [DeclarationsChecker]
object FirMemberPropertiesChecker : FirRegularClassChecker() {
override fun check(declaration: FirRegularClass, context: CheckerContext, reporter: DiagnosticReporter) {
object FirMemberPropertiesChecker : FirClassChecker() {
override fun check(declaration: FirClass, context: CheckerContext, reporter: DiagnosticReporter) {
val memberPropertySymbols = declaration.declarations.filterIsInstance<FirProperty>().map { it.symbol }.toSet()
val initializedInConstructor =
mutableMapOf<FirPropertySymbol, EventOccurrencesRange>().withDefault { EventOccurrencesRange.ZERO }
@@ -59,7 +59,7 @@ object FirMemberPropertiesChecker : FirRegularClassChecker() {
}
private fun collectPropertyInitialization(
klass: FirRegularClass,
klass: FirClass,
memberPropertySymbols: Set<FirPropertySymbol>,
initializedInConstructor: MutableMap<FirPropertySymbol, EventOccurrencesRange>,
initializedInInitOrOtherProperty: MutableMap<FirPropertySymbol, EventOccurrencesRange>
@@ -144,7 +144,7 @@ object FirMemberPropertiesChecker : FirRegularClassChecker() {
}
private fun checkProperty(
containingDeclaration: FirRegularClass,
containingDeclaration: FirClass,
property: FirProperty,
isInitialized: Boolean,
context: CheckerContext,
@@ -182,7 +182,7 @@ object FirMemberPropertiesChecker : FirRegularClassChecker() {
}
if (isAbstract) {
if (!containingDeclaration.canHaveAbstractDeclaration) {
if (containingDeclaration is FirRegularClass && !containingDeclaration.canHaveAbstractDeclaration) {
property.source?.let {
reporter.reportOn(
it,
@@ -216,7 +216,12 @@ object FirMemberPropertiesChecker : FirRegularClassChecker() {
}
}
private fun FirRegularClass.collectDeadEndDeclarations(): Set<FirElement> {
private fun FirClass.collectDeadEndDeclarations(): Set<FirElement> {
val controlFlowGraphReference = when (this) {
is FirAnonymousObject -> this.controlFlowGraphReference
is FirRegularClass -> this.controlFlowGraphReference
else -> null
}
val cfg = controlFlowGraphReference?.controlFlowGraph ?: return emptySet()
return cfg.exitNode.incomingEdges.keys
.map { it.fir }
@@ -264,7 +264,7 @@ class ClassObject() {
fun foo() {
val a = object {
val x : Int
val y : Int
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>val y : Int<!>
val z : Int
init {
x = 1
@@ -282,7 +282,7 @@ class TestObjectExpression() {
fun foo() {
val a = object {
val x : Int
val y : Int
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>val y : Int<!>
init {
if (true)
x = 12