FIR checker: apply member checkers to anonymous objects
because they can have member properties/functions too.
This commit is contained in:
committed by
TeamCityServer
parent
64a275cf83
commit
cd78a156c5
+2
-2
@@ -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,
|
||||
)
|
||||
|
||||
+9
-9
@@ -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,
|
||||
|
||||
+4
-4
@@ -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,
|
||||
|
||||
+11
-6
@@ -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 }
|
||||
|
||||
Vendored
+2
-2
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user