From a70c4f15d6ccc8f6738eeac809bcb26e081ecc3f Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Thu, 15 Sep 2022 10:04:52 +0200 Subject: [PATCH] K2: make not implemented checker more close to K1 logic #KT-54049 Fixed --- .../FirNotImplementedOverrideChecker.kt | 27 +++++++++++-------- .../falseManyImplementations.fir.kt | 13 --------- .../falseManyImplementations.kt | 1 + .../tests/override/NonGenerics.fir.kt | 2 +- 4 files changed, 18 insertions(+), 25 deletions(-) delete mode 100644 compiler/testData/diagnostics/tests/java8Overrides/falseManyImplementations.fir.kt diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirNotImplementedOverrideChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirNotImplementedOverrideChecker.kt index 270491654b6..aa73bd6e5eb 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirNotImplementedOverrideChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirNotImplementedOverrideChecker.kt @@ -11,7 +11,6 @@ import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.fir.analysis.checkers.* import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.diagnostics.DiagnosticReporter -import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ABSTRACT_MEMBER_NOT_IMPLEMENTED import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE @@ -19,6 +18,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVISIBLE_ABSTRAC import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MANY_IMPL_MEMBER_NOT_IMPLEMENTED import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OVERRIDING_FINAL_MEMBER_BY_DELEGATION import org.jetbrains.kotlin.diagnostics.reportOn +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED import org.jetbrains.kotlin.fir.containingClass import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirRegularClass @@ -92,6 +92,7 @@ object FirNotImplementedOverrideChecker : FirClassChecker() { symbol.isVisibleInClass(classSymbol) -> notImplementedSymbols.add(symbol) else -> invisibleSymbols.add(symbol) } + else -> { // nothing to do } @@ -104,7 +105,8 @@ object FirNotImplementedOverrideChecker : FirClassChecker() { } if (!canHaveAbstractDeclarations && notImplementedSymbols.isNotEmpty()) { - val notImplemented = notImplementedSymbols.first().unwrapFakeOverrides() + val notImplemented = (notImplementedSymbols.firstOrNull { !it.isFromInterfaceOrEnum(context) } ?: notImplementedSymbols.first()) + .unwrapFakeOverrides() if (notImplemented.isFromInterfaceOrEnum(context)) { reporter.reportOn(source, ABSTRACT_MEMBER_NOT_IMPLEMENTED, classSymbol, notImplemented, context) } else { @@ -142,20 +144,23 @@ object FirNotImplementedOverrideChecker : FirClassChecker() { if (manyImplementationsDelegationSymbols.isEmpty() && notImplementedIntersectionSymbols.isNotEmpty()) { val notImplementedIntersectionSymbol = notImplementedIntersectionSymbols.first() - val intersections = (notImplementedIntersectionSymbol as FirIntersectionCallableSymbol).intersections - if (intersections.any { + val (abstractIntersections, implIntersections) = + (notImplementedIntersectionSymbol as FirIntersectionCallableSymbol).intersections.partition { + it.modality == Modality.ABSTRACT + } + if (implIntersections.any { (it.containingClass()?.toSymbol(context.session) as? FirRegularClassSymbol)?.classKind == ClassKind.CLASS } ) { reporter.reportOn(source, MANY_IMPL_MEMBER_NOT_IMPLEMENTED, classSymbol, notImplementedIntersectionSymbol, context) } else { - reporter.reportOn( - source, - FirErrors.MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED, - classSymbol, - notImplementedIntersectionSymbol, - context - ) + if (canHaveAbstractDeclarations && abstractIntersections.any { + (it.containingClass()?.toSymbol(context.session) as? FirRegularClassSymbol)?.classKind == ClassKind.CLASS + } + ) { + return + } + reporter.reportOn(source, MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED, classSymbol, notImplementedIntersectionSymbol, context) } } } diff --git a/compiler/testData/diagnostics/tests/java8Overrides/falseManyImplementations.fir.kt b/compiler/testData/diagnostics/tests/java8Overrides/falseManyImplementations.fir.kt deleted file mode 100644 index 082506b4c2b..00000000000 --- a/compiler/testData/diagnostics/tests/java8Overrides/falseManyImplementations.fir.kt +++ /dev/null @@ -1,13 +0,0 @@ -abstract class ClassEmpty { - abstract fun foo() -} - -interface BaseEmpty { - fun foo() -} - -interface BaseDefault { - fun foo() {} -} - -abstract class ClassEmpty_BaseEmpty_BaseDefault : ClassEmpty(), BaseEmpty, BaseDefault diff --git a/compiler/testData/diagnostics/tests/java8Overrides/falseManyImplementations.kt b/compiler/testData/diagnostics/tests/java8Overrides/falseManyImplementations.kt index f109502bcf3..58f345b72cd 100644 --- a/compiler/testData/diagnostics/tests/java8Overrides/falseManyImplementations.kt +++ b/compiler/testData/diagnostics/tests/java8Overrides/falseManyImplementations.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL abstract class ClassEmpty { abstract fun foo() } diff --git a/compiler/testData/diagnostics/tests/override/NonGenerics.fir.kt b/compiler/testData/diagnostics/tests/override/NonGenerics.fir.kt index 3bbd774aae6..bb64f28b59d 100644 --- a/compiler/testData/diagnostics/tests/override/NonGenerics.fir.kt +++ b/compiler/testData/diagnostics/tests/override/NonGenerics.fir.kt @@ -21,7 +21,7 @@ open class MyClass() : MyTrait, MyAbstractClass() { class MyChildClass() : MyClass() {} -class MyIllegalClass : MyTrait, MyAbstractClass() {} +class MyIllegalClass : MyTrait, MyAbstractClass() {} class MyIllegalClass2() : MyTrait, MyAbstractClass() { override fun foo() {}