K2: make not implemented checker more close to K1 logic
#KT-54049 Fixed
This commit is contained in:
+16
-11
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.descriptors.Modality
|
|||||||
import org.jetbrains.kotlin.fir.analysis.checkers.*
|
import org.jetbrains.kotlin.fir.analysis.checkers.*
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
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_CLASS_MEMBER_NOT_IMPLEMENTED
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ABSTRACT_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
|
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.MANY_IMPL_MEMBER_NOT_IMPLEMENTED
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OVERRIDING_FINAL_MEMBER_BY_DELEGATION
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OVERRIDING_FINAL_MEMBER_BY_DELEGATION
|
||||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
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.containingClass
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||||
@@ -92,6 +92,7 @@ object FirNotImplementedOverrideChecker : FirClassChecker() {
|
|||||||
symbol.isVisibleInClass(classSymbol) -> notImplementedSymbols.add(symbol)
|
symbol.isVisibleInClass(classSymbol) -> notImplementedSymbols.add(symbol)
|
||||||
else -> invisibleSymbols.add(symbol)
|
else -> invisibleSymbols.add(symbol)
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
// nothing to do
|
// nothing to do
|
||||||
}
|
}
|
||||||
@@ -104,7 +105,8 @@ object FirNotImplementedOverrideChecker : FirClassChecker() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!canHaveAbstractDeclarations && notImplementedSymbols.isNotEmpty()) {
|
if (!canHaveAbstractDeclarations && notImplementedSymbols.isNotEmpty()) {
|
||||||
val notImplemented = notImplementedSymbols.first().unwrapFakeOverrides()
|
val notImplemented = (notImplementedSymbols.firstOrNull { !it.isFromInterfaceOrEnum(context) } ?: notImplementedSymbols.first())
|
||||||
|
.unwrapFakeOverrides()
|
||||||
if (notImplemented.isFromInterfaceOrEnum(context)) {
|
if (notImplemented.isFromInterfaceOrEnum(context)) {
|
||||||
reporter.reportOn(source, ABSTRACT_MEMBER_NOT_IMPLEMENTED, classSymbol, notImplemented, context)
|
reporter.reportOn(source, ABSTRACT_MEMBER_NOT_IMPLEMENTED, classSymbol, notImplemented, context)
|
||||||
} else {
|
} else {
|
||||||
@@ -142,20 +144,23 @@ object FirNotImplementedOverrideChecker : FirClassChecker() {
|
|||||||
|
|
||||||
if (manyImplementationsDelegationSymbols.isEmpty() && notImplementedIntersectionSymbols.isNotEmpty()) {
|
if (manyImplementationsDelegationSymbols.isEmpty() && notImplementedIntersectionSymbols.isNotEmpty()) {
|
||||||
val notImplementedIntersectionSymbol = notImplementedIntersectionSymbols.first()
|
val notImplementedIntersectionSymbol = notImplementedIntersectionSymbols.first()
|
||||||
val intersections = (notImplementedIntersectionSymbol as FirIntersectionCallableSymbol).intersections
|
val (abstractIntersections, implIntersections) =
|
||||||
if (intersections.any {
|
(notImplementedIntersectionSymbol as FirIntersectionCallableSymbol).intersections.partition {
|
||||||
|
it.modality == Modality.ABSTRACT
|
||||||
|
}
|
||||||
|
if (implIntersections.any {
|
||||||
(it.containingClass()?.toSymbol(context.session) as? FirRegularClassSymbol)?.classKind == ClassKind.CLASS
|
(it.containingClass()?.toSymbol(context.session) as? FirRegularClassSymbol)?.classKind == ClassKind.CLASS
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
reporter.reportOn(source, MANY_IMPL_MEMBER_NOT_IMPLEMENTED, classSymbol, notImplementedIntersectionSymbol, context)
|
reporter.reportOn(source, MANY_IMPL_MEMBER_NOT_IMPLEMENTED, classSymbol, notImplementedIntersectionSymbol, context)
|
||||||
} else {
|
} else {
|
||||||
reporter.reportOn(
|
if (canHaveAbstractDeclarations && abstractIntersections.any {
|
||||||
source,
|
(it.containingClass()?.toSymbol(context.session) as? FirRegularClassSymbol)?.classKind == ClassKind.CLASS
|
||||||
FirErrors.MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED,
|
}
|
||||||
classSymbol,
|
) {
|
||||||
notImplementedIntersectionSymbol,
|
return
|
||||||
context
|
}
|
||||||
)
|
reporter.reportOn(source, MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED, classSymbol, notImplementedIntersectionSymbol, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
-13
@@ -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
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
abstract class ClassEmpty {
|
abstract class ClassEmpty {
|
||||||
abstract fun foo()
|
abstract fun foo()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ open class MyClass() : MyTrait, MyAbstractClass() {
|
|||||||
|
|
||||||
class MyChildClass() : MyClass() {}
|
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() {
|
<!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class MyIllegalClass2<!>() : MyTrait, MyAbstractClass() {
|
||||||
override fun foo() {}
|
override fun foo() {}
|
||||||
|
|||||||
Reference in New Issue
Block a user