Partially revert "[FE] Stop ignoring ABSTRACT_MEMBER_NOT_IMPLEMENTED for expect classes"

^KT-61039 Fixed
KT-59739 is now open for K1 (but fixed in K2)
Review: https://jetbrains.team/p/kt/reviews/11867/timeline

This partially reverts commit 4f3ecedbca.
Only K1 part is reverted.

Motivation for revert: KT-59739 cannot be properly fixed in K1 because
of the bug it causes - KT-61039

We just accepted that we will have one more "green in K1 -> red in K2"
case
This commit is contained in:
Nikita Bobko
2023-08-24 18:55:49 +02:00
committed by teamcity
parent 3534a4b7a9
commit 373abbde5d
9 changed files with 22 additions and 16 deletions
@@ -36,7 +36,7 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.platform.PlatformSpecificDiagnosticComponents import org.jetbrains.kotlin.platform.PlatformSpecificDiagnosticComponents
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.DescriptorUtils.classCanHaveAbstractDeclaration import org.jetbrains.kotlin.resolve.DescriptorUtils.classCanHaveAbstractFakeOverride
import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE
import org.jetbrains.kotlin.resolve.calls.util.isOrOverridesSynthesized import org.jetbrains.kotlin.resolve.calls.util.isOrOverridesSynthesized
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
@@ -132,7 +132,7 @@ class OverrideResolver(
this(delegateStrategy.klass, delegateStrategy.classDescriptor) this(delegateStrategy.klass, delegateStrategy.classDescriptor)
override fun doReportErrors() { override fun doReportErrors() {
val canHaveAbstractMembers = classCanHaveAbstractDeclaration(classDescriptor) val canHaveAbstractMembers = classCanHaveAbstractFakeOverride(classDescriptor)
if (abstractInBaseClassNoImpl.isNotEmpty() && !canHaveAbstractMembers) { if (abstractInBaseClassNoImpl.isNotEmpty() && !canHaveAbstractMembers) {
if (languageVersionSettings.supportsFeature(AbstractClassMemberNotImplementedWithIntermediateAbstractClass)) { if (languageVersionSettings.supportsFeature(AbstractClassMemberNotImplementedWithIntermediateAbstractClass)) {
trace.report(ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED.on(klass, klass, abstractInBaseClassNoImpl.first())) trace.report(ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED.on(klass, klass, abstractInBaseClassNoImpl.first()))
@@ -260,7 +260,7 @@ class OverrideResolver(
} }
open fun doReportErrors() { open fun doReportErrors() {
val canHaveAbstractMembers = classCanHaveAbstractDeclaration(classDescriptor) val canHaveAbstractMembers = classCanHaveAbstractFakeOverride(classDescriptor)
if (abstractInBaseClassNoImpl.isNotEmpty() && !canHaveAbstractMembers) { if (abstractInBaseClassNoImpl.isNotEmpty() && !canHaveAbstractMembers) {
trace.report(ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED.on(klass, klass, abstractInBaseClassNoImpl.first())) trace.report(ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED.on(klass, klass, abstractInBaseClassNoImpl.first()))
} else if (abstractNoImpl.isNotEmpty() && !canHaveAbstractMembers) { } else if (abstractNoImpl.isNotEmpty() && !canHaveAbstractMembers) {
@@ -708,9 +708,11 @@ class OverrideResolver(
for (overridden in relevantDirectlyOverridden) { for (overridden in relevantDirectlyOverridden) {
val containingDeclaration = overridden.containingDeclaration as? ClassDescriptor ?: continue val containingDeclaration = overridden.containingDeclaration as? ClassDescriptor ?: continue
if (containingDeclaration.kind == ClassKind.CLASS) { if (containingDeclaration.kind == ClassKind.CLASS) {
if (overridden.kind == FAKE_OVERRIDE) { if (overridden.kind == FAKE_OVERRIDE && !containingDeclaration.isExpect) {
// Fake override in a class in fact can mean an interface member // Fake override in a class in fact can mean an interface member
// We will process it at the end // We will process it at the end
// Note: with expect containing class, the situation is unclear, so we miss this case
// See extendExpectedClassWithAbstractMember.kt (BaseA, BaseAImpl, DerivedA1)
fakeOverrideInBaseClass = overridden fakeOverrideInBaseClass = overridden
} }
overridesClassMember = true overridesClassMember = true
@@ -5,7 +5,7 @@ interface Base {
fun foo() fun foo()
} }
expect open <!ABSTRACT_MEMBER_NOT_IMPLEMENTED, ABSTRACT_MEMBER_NOT_IMPLEMENTED{JVM}!>class Foo<!> : Base expect open class Foo : Base
// MODULE: m2-jvm()()(m1-common) // MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt // FILE: jvm.kt
@@ -11,7 +11,7 @@ interface Base {
// Mismatched scope must be reported here. But it's false negative checker in K1. // Mismatched scope must be reported here. But it's false negative checker in K1.
// For some reason, K1 says that modality of `exect_Foo.foo` is `abstract`. // For some reason, K1 says that modality of `exect_Foo.foo` is `abstract`.
// Luckily, we report ABSTRACT_MEMBER_NOT_IMPLEMENTED additionally. // https://youtrack.jetbrains.com/issue/KT-59739
actual open class Foo : Base { actual open class Foo : Base {
override fun foo() {} override fun foo() {}
} }
@@ -3,7 +3,7 @@
interface Base { interface Base {
fun foo() fun foo()
} }
expect open <!ABSTRACT_MEMBER_NOT_IMPLEMENTED, ABSTRACT_MEMBER_NOT_IMPLEMENTED{JVM}!>class Foo<!>() : Base expect open class Foo() : Base
// MODULE: m2-jvm()()(m1-common) // MODULE: m2-jvm()()(m1-common)
@@ -11,7 +11,7 @@ expect open <!ABSTRACT_MEMBER_NOT_IMPLEMENTED, ABSTRACT_MEMBER_NOT_IMPLEMENTED{J
// Mismatched scope must be reported here. But it's false negative checker in K1. // Mismatched scope must be reported here. But it's false negative checker in K1.
// For some reason, K1 says that modality of `exect_Foo.foo` is `abstract`. // For some reason, K1 says that modality of `exect_Foo.foo` is `abstract`.
// Luckily, we report ABSTRACT_MEMBER_NOT_IMPLEMENTED additionally. // https://youtrack.jetbrains.com/issue/KT-59739
actual open class Foo : Base { actual open class Foo : Base {
override fun foo() {} override fun foo() {}
} }
@@ -5,7 +5,7 @@ interface Base {
fun foo() fun foo()
} }
expect <!ABSTRACT_MEMBER_NOT_IMPLEMENTED, ABSTRACT_MEMBER_NOT_IMPLEMENTED{JVM}!>object Implementation<!> : Base expect object Implementation : Base
// MODULE: m1-jvm()()(m1-common) // MODULE: m1-jvm()()(m1-common)
// FILE: jvm.kt // FILE: jvm.kt
@@ -5,13 +5,13 @@ interface Foo {
fun foo() fun foo()
} }
expect <!ABSTRACT_MEMBER_NOT_IMPLEMENTED, ABSTRACT_MEMBER_NOT_IMPLEMENTED{JVM}!>class ImplicitFoo<!> : Foo expect class ImplicitFoo : Foo
expect class ExplicitFoo : Foo { expect class ExplicitFoo : Foo {
override fun foo() override fun foo()
} }
expect <!ABSTRACT_MEMBER_NOT_IMPLEMENTED, ABSTRACT_MEMBER_NOT_IMPLEMENTED{JVM}!>class ImplicitFooCheck<!> : Foo expect class ImplicitFooCheck : Foo
// MODULE: m2-jvm()()(m1-common) // MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt // FILE: jvm.kt
@@ -4,9 +4,9 @@
expect abstract class BaseA() { expect abstract class BaseA() {
abstract fun foo() abstract fun foo()
} }
expect open <!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class BaseAImpl<!>() : BaseA expect open class BaseAImpl() : BaseA
<!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class DerivedA1<!> : BaseAImpl() class DerivedA1 : BaseAImpl()
class DerivedA2 : BaseAImpl() { class DerivedA2 : BaseAImpl() {
override fun foo() = super.foo() override fun foo() = super.foo()
} }
@@ -16,7 +16,7 @@ class DerivedA2 : BaseAImpl() {
expect interface BaseB { expect interface BaseB {
fun foo() fun foo()
} }
expect open <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class BaseBImpl<!>() : BaseB expect open class BaseBImpl() : BaseB
class DerivedB1 : BaseBImpl() class DerivedB1 : BaseBImpl()
class DerivedB2 : BaseBImpl() { class DerivedB2 : BaseBImpl() {
@@ -58,7 +58,7 @@ sealed class BaseEImpl() : BaseE {
expect interface BaseF { expect interface BaseF {
fun foo() fun foo()
} }
expect <!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class BaseFImpl<!>() : BaseF expect class BaseFImpl() : BaseF
@@ -5,7 +5,7 @@ expect abstract class Base {
abstract fun foo() abstract fun foo()
} }
expect <!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED, ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED{JVM}!>class DerivedImplicit<!> : Base expect class DerivedImplicit : Base
expect class DerivedExplicit : Base { expect class DerivedExplicit : Base {
override fun foo() override fun foo()
@@ -505,6 +505,10 @@ public class DescriptorUtils {
UnsignedTypes.INSTANCE.isUnsignedType(type); UnsignedTypes.INSTANCE.isUnsignedType(type);
} }
public static boolean classCanHaveAbstractFakeOverride(@NotNull ClassDescriptor classDescriptor) {
return classCanHaveAbstractDeclaration(classDescriptor) || classDescriptor.isExpect();
}
public static boolean classCanHaveAbstractDeclaration(@NotNull ClassDescriptor classDescriptor) { public static boolean classCanHaveAbstractDeclaration(@NotNull ClassDescriptor classDescriptor) {
return classDescriptor.getModality() == Modality.ABSTRACT return classDescriptor.getModality() == Modality.ABSTRACT
|| isSealedClass(classDescriptor) || isSealedClass(classDescriptor)