From 4f3ecedbca9f0220a47b470551c8d013605b4bd4 Mon Sep 17 00:00:00 2001 From: Nikita Bobko Date: Mon, 10 Jul 2023 11:23:25 +0200 Subject: [PATCH] [FE] Stop ignoring ABSTRACT_MEMBER_NOT_IMPLEMENTED for expect classes ^KT-59739 Fixed Review: https://jetbrains.team/p/kt/reviews/11038/timeline --- .../fir/analysis/checkers/FirHelpers.kt | 1 - .../FirNotImplementedOverrideChecker.kt | 2 -- .../kotlin/resolve/OverrideResolver.kt | 10 +++---- .../basic/expectActualIntersectionOverride.kt | 6 +++-- .../modifiers/openInExpectInterface.fir.kt | 4 +-- .../expectAbstractToString.fir.kt | 22 +++++++++++++++ .../multiplatform/expectAbstractToString.kt | 1 - .../expectObjectWithAbstractMember.fir.kt | 17 ++++++++++++ .../expectObjectWithAbstractMember.kt | 3 +-- ...ideMethodsFromInterfaceInCommonCode.fir.kt | 27 +++++++++++++++++++ ...verrideMethodsFromInterfaceInCommonCode.kt | 5 ++-- ...tendExpectedClassWithAbstractMember.fir.kt | 22 ++++++++++----- .../extendExpectedClassWithAbstractMember.kt | 18 ++++++++++--- .../extendExpectedClassWithAbstractMember.txt | 24 +++++++++++++++++ ...lassWithoutExplicitOverrideOfMethod.fir.kt | 2 +- ...tedClassWithoutExplicitOverrideOfMethod.kt | 2 +- .../java/inheritedJavaMembers.kt | 3 ++- .../expectIntersectionOverride.ir.txt | 2 ++ .../expectIntersectionOverride.kt | 1 + .../expectIntersectionOverride.kt.txt | 1 + .../common.kt | 4 ++- .../jvm.kt | 4 +-- .../kotlin/util/ImplementationStatus.kt | 3 +-- .../kotlin/resolve/DescriptorUtils.java | 4 --- .../utils/InlineSourceBuilderImpl.kt | 15 ++++++++++- 25 files changed, 161 insertions(+), 42 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/multiplatform/expectAbstractToString.fir.kt create mode 100644 compiler/testData/diagnostics/tests/multiplatform/expectObjectWithAbstractMember.fir.kt create mode 100644 compiler/testData/diagnostics/tests/multiplatform/headerClass/dontOverrideMethodsFromInterfaceInCommonCode.fir.kt diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt index 07368669337..a8797e14fc8 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt @@ -386,7 +386,6 @@ fun FirCallableSymbol<*>.getImplementationStatus( isFinal -> ImplementationStatus.CANNOT_BE_IMPLEMENTED containingClassSymbol === parentClassSymbol && (origin == FirDeclarationOrigin.Source || origin == FirDeclarationOrigin.Precompiled) -> ImplementationStatus.ALREADY_IMPLEMENTED - containingClassSymbol is FirRegularClassSymbol && containingClassSymbol.isExpect -> ImplementationStatus.CANNOT_BE_IMPLEMENTED isAbstract -> ImplementationStatus.NOT_IMPLEMENTED else -> ImplementationStatus.INHERITED_OR_SYNTHESIZED } 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 f6c4ad44a7a..0bce296e1f3 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 @@ -23,7 +23,6 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAR_IMPLEMENTED_B import org.jetbrains.kotlin.fir.containingClassLookupTag import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin -import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.utils.* import org.jetbrains.kotlin.fir.delegatedWrapperData import org.jetbrains.kotlin.fir.resolve.toSymbol @@ -42,7 +41,6 @@ object FirNotImplementedOverrideChecker : FirClassChecker() { if (sourceKind is KtFakeSourceElementKind && sourceKind != KtFakeSourceElementKind.EnumInitializer) return val modality = declaration.modality() val canHaveAbstractDeclarations = modality == Modality.ABSTRACT || modality == Modality.SEALED - if (declaration is FirRegularClass && declaration.isExpect) return val classKind = declaration.classKind if (classKind == ClassKind.ANNOTATION_CLASS || classKind == ClassKind.ENUM_CLASS) return val classSymbol = declaration.symbol diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverrideResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverrideResolver.kt index 34c56540668..f1357d46785 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverrideResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverrideResolver.kt @@ -36,7 +36,7 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.platform.PlatformSpecificDiagnosticComponents import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.resolve.DescriptorUtils.classCanHaveAbstractFakeOverride +import org.jetbrains.kotlin.resolve.DescriptorUtils.classCanHaveAbstractDeclaration import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE import org.jetbrains.kotlin.resolve.calls.util.isOrOverridesSynthesized import org.jetbrains.kotlin.types.* @@ -132,7 +132,7 @@ class OverrideResolver( this(delegateStrategy.klass, delegateStrategy.classDescriptor) override fun doReportErrors() { - val canHaveAbstractMembers = classCanHaveAbstractFakeOverride(classDescriptor) + val canHaveAbstractMembers = classCanHaveAbstractDeclaration(classDescriptor) if (abstractInBaseClassNoImpl.isNotEmpty() && !canHaveAbstractMembers) { if (languageVersionSettings.supportsFeature(AbstractClassMemberNotImplementedWithIntermediateAbstractClass)) { trace.report(ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED.on(klass, klass, abstractInBaseClassNoImpl.first())) @@ -260,7 +260,7 @@ class OverrideResolver( } open fun doReportErrors() { - val canHaveAbstractMembers = classCanHaveAbstractFakeOverride(classDescriptor) + val canHaveAbstractMembers = classCanHaveAbstractDeclaration(classDescriptor) if (abstractInBaseClassNoImpl.isNotEmpty() && !canHaveAbstractMembers) { trace.report(ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED.on(klass, klass, abstractInBaseClassNoImpl.first())) } else if (abstractNoImpl.isNotEmpty() && !canHaveAbstractMembers) { @@ -708,11 +708,9 @@ class OverrideResolver( for (overridden in relevantDirectlyOverridden) { val containingDeclaration = overridden.containingDeclaration as? ClassDescriptor ?: continue if (containingDeclaration.kind == ClassKind.CLASS) { - if (overridden.kind == FAKE_OVERRIDE && !containingDeclaration.isExpect) { + if (overridden.kind == FAKE_OVERRIDE) { // Fake override in a class in fact can mean an interface member // 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 } overridesClassMember = true diff --git a/compiler/testData/codegen/box/multiplatform/k2/basic/expectActualIntersectionOverride.kt b/compiler/testData/codegen/box/multiplatform/k2/basic/expectActualIntersectionOverride.kt index 6717d0ca04a..84fa38a7914 100644 --- a/compiler/testData/codegen/box/multiplatform/k2/basic/expectActualIntersectionOverride.kt +++ b/compiler/testData/codegen/box/multiplatform/k2/basic/expectActualIntersectionOverride.kt @@ -13,7 +13,9 @@ interface I2 { fun f(): String } -expect class C() : I1, I2 +expect class C() : I1, I2 { + override fun f(): String +} fun test() = C().f() @@ -21,7 +23,7 @@ fun test() = C().f() // FILE: platform.kt actual class C : I1, I2 { - override fun f() = "OK" + actual override fun f() = "OK" } fun box() = test() \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/modifiers/openInExpectInterface.fir.kt b/compiler/testData/diagnostics/tests/modifiers/openInExpectInterface.fir.kt index a92c510d027..42d08cf9b9c 100644 --- a/compiler/testData/diagnostics/tests/modifiers/openInExpectInterface.fir.kt +++ b/compiler/testData/diagnostics/tests/modifiers/openInExpectInterface.fir.kt @@ -19,9 +19,9 @@ expect interface My { val f: Int } -class MyImpl1: My +class MyImpl1: My -class MyImpl2: My { +class MyImpl2: My { override fun foo() {} override val f = 0 override val e = 1 diff --git a/compiler/testData/diagnostics/tests/multiplatform/expectAbstractToString.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/expectAbstractToString.fir.kt new file mode 100644 index 00000000000..33bb99a5dca --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/expectAbstractToString.fir.kt @@ -0,0 +1,22 @@ +// WITH_STDLIB +// MODULE: m1-common +// FILE: common.kt + +interface B { + override fun toString(): String +} + +expect value class C(val s: String) : B + +expect value class D(val s: String) : B + +// MODULE: m1-jvm()()(m1-common) +// FILE: jvm.kt + +@JvmInline +actual value class C(actual val s: String) : B { + override fun toString(): String = s +} + +@JvmInline +actual value class D(actual val s: String) : B diff --git a/compiler/testData/diagnostics/tests/multiplatform/expectAbstractToString.kt b/compiler/testData/diagnostics/tests/multiplatform/expectAbstractToString.kt index cf5926187f9..1bfac5565ff 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/expectAbstractToString.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/expectAbstractToString.kt @@ -1,4 +1,3 @@ -// FIR_IDENTICAL // WITH_STDLIB // MODULE: m1-common // FILE: common.kt diff --git a/compiler/testData/diagnostics/tests/multiplatform/expectObjectWithAbstractMember.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/expectObjectWithAbstractMember.fir.kt new file mode 100644 index 00000000000..409bdae712a --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/expectObjectWithAbstractMember.fir.kt @@ -0,0 +1,17 @@ +// MODULE: m1-common +// FILE: common.kt + +interface Base { + fun foo() +} + +expect object Implementation : Base + +// MODULE: m1-jvm()()(m1-common) +// FILE: jvm.kt + +abstract class RealImplementation : Base { + override fun foo() {} +} + +actual object Implementation : RealImplementation(), Base diff --git a/compiler/testData/diagnostics/tests/multiplatform/expectObjectWithAbstractMember.kt b/compiler/testData/diagnostics/tests/multiplatform/expectObjectWithAbstractMember.kt index b538efc0209..7e62ab590b0 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/expectObjectWithAbstractMember.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/expectObjectWithAbstractMember.kt @@ -1,4 +1,3 @@ -// FIR_IDENTICAL // MODULE: m1-common // FILE: common.kt @@ -6,7 +5,7 @@ interface Base { fun foo() } -expect object Implementation : Base +expect object Implementation : Base // MODULE: m1-jvm()()(m1-common) // FILE: jvm.kt diff --git a/compiler/testData/diagnostics/tests/multiplatform/headerClass/dontOverrideMethodsFromInterfaceInCommonCode.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/headerClass/dontOverrideMethodsFromInterfaceInCommonCode.fir.kt new file mode 100644 index 00000000000..04f030a55b4 --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/headerClass/dontOverrideMethodsFromInterfaceInCommonCode.fir.kt @@ -0,0 +1,27 @@ +// MODULE: m1-common +// FILE: common.kt + +interface Foo { + fun foo() +} + +expect class ImplicitFoo : Foo + +expect class ExplicitFoo : Foo { + override fun foo() +} + +expect class ImplicitFooCheck : Foo + +// MODULE: m2-jvm()()(m1-common) +// FILE: jvm.kt + +actual class ImplicitFoo : Foo { + override fun foo() {} +} + +actual class ExplicitFoo : Foo { + actual override fun foo() {} +} + +actual class ImplicitFooCheck : Foo diff --git a/compiler/testData/diagnostics/tests/multiplatform/headerClass/dontOverrideMethodsFromInterfaceInCommonCode.kt b/compiler/testData/diagnostics/tests/multiplatform/headerClass/dontOverrideMethodsFromInterfaceInCommonCode.kt index 5be5669fa26..c467cc786c1 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/headerClass/dontOverrideMethodsFromInterfaceInCommonCode.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/headerClass/dontOverrideMethodsFromInterfaceInCommonCode.kt @@ -1,4 +1,3 @@ -// FIR_IDENTICAL // MODULE: m1-common // FILE: common.kt @@ -6,13 +5,13 @@ interface Foo { fun foo() } -expect class ImplicitFoo : Foo +expect class ImplicitFoo : Foo expect class ExplicitFoo : Foo { override fun foo() } -expect class ImplicitFooCheck : Foo +expect class ImplicitFooCheck : Foo // MODULE: m2-jvm()()(m1-common) // FILE: jvm.kt diff --git a/compiler/testData/diagnostics/tests/multiplatform/headerClass/extendExpectedClassWithAbstractMember.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/headerClass/extendExpectedClassWithAbstractMember.fir.kt index bc316e9967c..44b93bf4283 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/headerClass/extendExpectedClassWithAbstractMember.fir.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/headerClass/extendExpectedClassWithAbstractMember.fir.kt @@ -4,9 +4,9 @@ expect abstract class BaseA() { abstract fun foo() } -expect open class BaseAImpl() : BaseA +expect open class BaseAImpl() : BaseA -class DerivedA1 : BaseAImpl() +class DerivedA1 : BaseAImpl() class DerivedA2 : BaseAImpl() { override fun foo() = super.foo() } @@ -16,9 +16,9 @@ class DerivedA2 : BaseAImpl() { expect interface BaseB { fun foo() } -expect open class BaseBImpl() : BaseB +expect open class BaseBImpl() : BaseB -class DerivedB1 : BaseBImpl() +class DerivedB1 : BaseBImpl() class DerivedB2 : BaseBImpl() { override fun foo() = super.foo() } @@ -30,7 +30,7 @@ class DerivedB2 : BaseBImpl() { } expect abstract class BaseCImpl() : BaseC -class DerivedC1 : BaseCImpl() +class DerivedC1 : BaseCImpl() class DerivedC2 : BaseCImpl() { override fun foo() = super.foo() } @@ -58,4 +58,14 @@ sealed class BaseEImpl() : BaseE { expect interface BaseF { fun foo() } -expect class BaseFImpl() : BaseF +expect class BaseFImpl() : BaseF + + + +expect abstract class BaseG() { + abstract fun foo() +} +expect open class BaseGImpl() : BaseG { + override fun foo() +} +class DerivedG1 : BaseGImpl() diff --git a/compiler/testData/diagnostics/tests/multiplatform/headerClass/extendExpectedClassWithAbstractMember.kt b/compiler/testData/diagnostics/tests/multiplatform/headerClass/extendExpectedClassWithAbstractMember.kt index f6d270bcc8b..1c39701147c 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/headerClass/extendExpectedClassWithAbstractMember.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/headerClass/extendExpectedClassWithAbstractMember.kt @@ -4,9 +4,9 @@ expect abstract class BaseA() { abstract fun foo() } -expect open class BaseAImpl() : BaseA +expect open class BaseAImpl() : BaseA -class DerivedA1 : BaseAImpl() +class DerivedA1 : BaseAImpl() class DerivedA2 : BaseAImpl() { override fun foo() = super.foo() } @@ -16,7 +16,7 @@ class DerivedA2 : BaseAImpl() { expect interface BaseB { fun foo() } -expect open class BaseBImpl() : BaseB +expect open class BaseBImpl() : BaseB class DerivedB1 : BaseBImpl() class DerivedB2 : BaseBImpl() { @@ -58,4 +58,14 @@ sealed class BaseEImpl() : BaseE { expect interface BaseF { fun foo() } -expect class BaseFImpl() : BaseF +expect class BaseFImpl() : BaseF + + + +expect abstract class BaseG() { + abstract fun foo() +} +expect open class BaseGImpl() : BaseG { + override fun foo() +} +class DerivedG1 : BaseGImpl() diff --git a/compiler/testData/diagnostics/tests/multiplatform/headerClass/extendExpectedClassWithAbstractMember.txt b/compiler/testData/diagnostics/tests/multiplatform/headerClass/extendExpectedClassWithAbstractMember.txt index 390994b22a2..a61e7db4e43 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/headerClass/extendExpectedClassWithAbstractMember.txt +++ b/compiler/testData/diagnostics/tests/multiplatform/headerClass/extendExpectedClassWithAbstractMember.txt @@ -93,6 +93,22 @@ public final expect class BaseFImpl : BaseF { public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } +public abstract expect class BaseG { + public constructor BaseG() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract expect fun foo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public open expect class BaseGImpl : BaseG { + public constructor BaseGImpl() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open expect override /*1*/ fun foo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + public final class DerivedA1 : BaseAImpl { public constructor DerivedA1() public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean @@ -141,3 +157,11 @@ public final class DerivedC2 : BaseCImpl { public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } +public final class DerivedG1 : BaseGImpl { + public constructor DerivedG1() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open expect override /*1*/ /*fake_override*/ fun foo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + diff --git a/compiler/testData/diagnostics/tests/multiplatform/headerClass/extendExpectedClassWithoutExplicitOverrideOfMethod.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/headerClass/extendExpectedClassWithoutExplicitOverrideOfMethod.fir.kt index acc2a467609..d8defb79fdd 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/headerClass/extendExpectedClassWithoutExplicitOverrideOfMethod.fir.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/headerClass/extendExpectedClassWithoutExplicitOverrideOfMethod.fir.kt @@ -5,7 +5,7 @@ expect abstract class Base { abstract fun foo() } -expect class DerivedImplicit : Base +expect class DerivedImplicit : Base expect class DerivedExplicit : Base { override fun foo() diff --git a/compiler/testData/diagnostics/tests/multiplatform/headerClass/extendExpectedClassWithoutExplicitOverrideOfMethod.kt b/compiler/testData/diagnostics/tests/multiplatform/headerClass/extendExpectedClassWithoutExplicitOverrideOfMethod.kt index e49d1b61c91..87275fb43f3 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/headerClass/extendExpectedClassWithoutExplicitOverrideOfMethod.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/headerClass/extendExpectedClassWithoutExplicitOverrideOfMethod.kt @@ -5,7 +5,7 @@ expect abstract class Base { abstract fun foo() } -expect class DerivedImplicit : Base +expect class DerivedImplicit : Base expect class DerivedExplicit : Base { override fun foo() diff --git a/compiler/testData/diagnostics/tests/multiplatform/java/inheritedJavaMembers.kt b/compiler/testData/diagnostics/tests/multiplatform/java/inheritedJavaMembers.kt index 7777c02ce35..f98f608d425 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/java/inheritedJavaMembers.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/java/inheritedJavaMembers.kt @@ -19,6 +19,7 @@ expect class FastArrayList : MutableListEx, RandomAccess { constructor(elements: Collection) fun trimToSize() + override fun removeRange(fromIndex: Int, toIndex: Int) fun ensureCapacity(minCapacity: Int) override val size: Int override fun isEmpty(): Boolean @@ -66,7 +67,7 @@ public actual open class FastArrayList internal constructor( actual override fun addAll(index: Int, elements: Collection): Boolean = true actual override fun remove(element: E): Boolean = true @Suppress("UNCHECKED_CAST") actual override fun removeAt(index: Int): E = array[0] as E - override fun removeRange(fromIndex: Int, toIndex: Int) {} + actual override fun removeRange(fromIndex: Int, toIndex: Int) {} override fun setAll(index: Int, elements: FastArrayList, offset: Int, size: Int) {} override fun addAll(elements: FastArrayList, offset: Int, size: Int) {} actual override fun clear() {} diff --git a/compiler/testData/ir/irText/declarations/multiplatform/expectIntersectionOverride.ir.txt b/compiler/testData/ir/irText/declarations/multiplatform/expectIntersectionOverride.ir.txt index ad00d7ec933..287fb25e64c 100644 --- a/compiler/testData/ir/irText/declarations/multiplatform/expectIntersectionOverride.ir.txt +++ b/compiler/testData/ir/irText/declarations/multiplatform/expectIntersectionOverride.ir.txt @@ -43,6 +43,8 @@ FILE fqName: fileName:/common.kt public open fun toString (): kotlin.String declared in kotlin.Any $this: VALUE_PARAMETER name: type:kotlin.Any CLASS CLASS name:C modality:FINAL visibility:public [expect] superTypes:[.I1; .I2] + annotations: + Suppress(names = ['ABSTRACT_MEMBER_NOT_IMPLEMENTED']) $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.C CONSTRUCTOR visibility:public <> () returnType:.C [primary,expect] FUN FAKE_OVERRIDE name:f visibility:public modality:ABSTRACT <> ($this:.I1) returnType:kotlin.String [expect,fake_override] diff --git a/compiler/testData/ir/irText/declarations/multiplatform/expectIntersectionOverride.kt b/compiler/testData/ir/irText/declarations/multiplatform/expectIntersectionOverride.kt index 8f0734a6660..d3691614b31 100644 --- a/compiler/testData/ir/irText/declarations/multiplatform/expectIntersectionOverride.kt +++ b/compiler/testData/ir/irText/declarations/multiplatform/expectIntersectionOverride.kt @@ -17,6 +17,7 @@ interface I2 { val p: Int } +@Suppress("ABSTRACT_MEMBER_NOT_IMPLEMENTED") // Workaround for KT-60390 expect class C() : I1, I2 // MODULE: platform()()(common) diff --git a/compiler/testData/ir/irText/declarations/multiplatform/expectIntersectionOverride.kt.txt b/compiler/testData/ir/irText/declarations/multiplatform/expectIntersectionOverride.kt.txt index 39ce841460a..8a6074d6cd1 100644 --- a/compiler/testData/ir/irText/declarations/multiplatform/expectIntersectionOverride.kt.txt +++ b/compiler/testData/ir/irText/declarations/multiplatform/expectIntersectionOverride.kt.txt @@ -17,6 +17,7 @@ interface I2 { } +@Suppress(names = ["ABSTRACT_MEMBER_NOT_IMPLEMENTED"]) expect class C : I1, I2 { expect constructor() /* primary */ diff --git a/compiler/testData/multiplatform/explicitActualOnOverrideOfAbstractMethod/common.kt b/compiler/testData/multiplatform/explicitActualOnOverrideOfAbstractMethod/common.kt index 12f11d20a7a..55deb1bbc63 100644 --- a/compiler/testData/multiplatform/explicitActualOnOverrideOfAbstractMethod/common.kt +++ b/compiler/testData/multiplatform/explicitActualOnOverrideOfAbstractMethod/common.kt @@ -2,4 +2,6 @@ expect abstract class Base { abstract fun foo() } -expect class DerivedImplicit : Base \ No newline at end of file +expect class DerivedImplicit : Base { + override fun foo() +} diff --git a/compiler/testData/multiplatform/explicitActualOnOverrideOfAbstractMethod/jvm.kt b/compiler/testData/multiplatform/explicitActualOnOverrideOfAbstractMethod/jvm.kt index 9899d7c14d9..30a58aa9f7d 100644 --- a/compiler/testData/multiplatform/explicitActualOnOverrideOfAbstractMethod/jvm.kt +++ b/compiler/testData/multiplatform/explicitActualOnOverrideOfAbstractMethod/jvm.kt @@ -3,5 +3,5 @@ actual abstract class Base { } actual class DerivedImplicit : Base() { - override fun foo() {} -} \ No newline at end of file + actual override fun foo() {} +} diff --git a/core/compiler.common/src/org/jetbrains/kotlin/util/ImplementationStatus.kt b/core/compiler.common/src/org/jetbrains/kotlin/util/ImplementationStatus.kt index 02d8b554f33..7c02d38565e 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/util/ImplementationStatus.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/util/ImplementationStatus.kt @@ -26,8 +26,7 @@ enum class ImplementationStatus { ALREADY_IMPLEMENTED, /** - * The symbol is not implemented in the class and it cannot be implemented. For example, it's final in super classes or the current - * class is `expect`. + * The symbol is not implemented in the class, and it cannot be implemented. For example, it's final in super classes. */ CANNOT_BE_IMPLEMENTED; diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java index a7b25398cd2..e4d743eaad1 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java @@ -505,10 +505,6 @@ public class DescriptorUtils { UnsignedTypes.INSTANCE.isUnsignedType(type); } - public static boolean classCanHaveAbstractFakeOverride(@NotNull ClassDescriptor classDescriptor) { - return classCanHaveAbstractDeclaration(classDescriptor) || classDescriptor.isExpect(); - } - public static boolean classCanHaveAbstractDeclaration(@NotNull ClassDescriptor classDescriptor) { return classDescriptor.getModality() == Modality.ABSTRACT || isSealedClass(classDescriptor) diff --git a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/InlineSourceBuilderImpl.kt b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/InlineSourceBuilderImpl.kt index 7d11787d621..82229f1a088 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/InlineSourceBuilderImpl.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/commonizer/utils/InlineSourceBuilderImpl.kt @@ -25,13 +25,19 @@ import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.PackageFragmentProvider import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl +import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.diagnostics.Severity +import org.jetbrains.kotlin.lexer.KtToken +import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.platform.CommonPlatforms import org.jetbrains.kotlin.platform.TargetPlatform +import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtPsiFactory import org.jetbrains.kotlin.psi.psiUtil.endOffset +import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier +import org.jetbrains.kotlin.psi.psiUtil.isAbstract import org.jetbrains.kotlin.psi.psiUtil.startOffset import org.jetbrains.kotlin.resolve.CompilerEnvironment import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices @@ -95,7 +101,14 @@ class InlineSourceBuilderImpl(private val disposable: Disposable) : InlineSource environment.createPackagePartProvider(content.moduleContentScope) } - val errorDiagnostics = analysisResult.bindingContext.diagnostics.noSuppression().filter { it.severity == Severity.ERROR } + val errorDiagnostics = analysisResult.bindingContext.diagnostics.noSuppression() + .filter { it.severity == Severity.ERROR } + .filterNot { diagnostic -> + val psiElement = diagnostic.psiElement + // Mute KT-60378 problem + psiElement is KtClass && psiElement.hasExpectModifier() && !psiElement.hasModifier(KtTokens.OPEN_KEYWORD) && + diagnostic.factory in listOf(Errors.ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED, Errors.ABSTRACT_MEMBER_NOT_IMPLEMENTED) + } check(errorDiagnostics.isEmpty()) { val diagnosticInfos = errorDiagnostics.map { diagnostic -> DiagnosticInfo(diagnostic.psiElement, diagnostic.factoryName)