K2: make not implemented checker more close to K1 logic

#KT-54049 Fixed
This commit is contained in:
Mikhail Glukhikh
2022-09-15 10:04:52 +02:00
committed by Space
parent fe38089205
commit a70c4f15d6
4 changed files with 18 additions and 25 deletions
@@ -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)
}
}
}
@@ -1,13 +0,0 @@
abstract class ClassEmpty {
abstract fun foo()
}
interface BaseEmpty {
fun foo()
}
interface BaseDefault {
fun foo() {}
}
abstract <!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class ClassEmpty_BaseEmpty_BaseDefault<!> : ClassEmpty(), BaseEmpty, BaseDefault
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
abstract class ClassEmpty {
abstract fun foo()
}
@@ -21,7 +21,7 @@ open class MyClass() : MyTrait, MyAbstractClass() {
class MyChildClass() : MyClass() {}
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class MyIllegalClass<!> : MyTrait, MyAbstractClass() {}
<!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class MyIllegalClass<!> : MyTrait, MyAbstractClass() {}
<!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class MyIllegalClass2<!>() : MyTrait, MyAbstractClass() {
override fun foo() {}