From 06cb64bb5153644e3b931abca3524ebd609990f7 Mon Sep 17 00:00:00 2001 From: "sebastian.sellmair" Date: Fri, 6 Nov 2020 17:03:30 +0100 Subject: [PATCH] Allow open callable members in expect interfaces #KT-42094 fixed --- ...irOldFrontendDiagnosticsTestGenerated.java | 10 +++ .../kotlin/resolve/DeclarationsChecker.kt | 2 +- .../kotlin/resolve/ModifiersChecker.java | 16 ++++- .../modifiers/openInExpectInterface.fir.kt | 37 +++++++++++ .../tests/modifiers/openInExpectInterface.kt | 37 +++++++++++ .../tests/modifiers/openInExpectInterface.txt | 64 +++++++++++++++++++ .../expectInterfaceApplicability.fir.kt | 25 ++++++++ .../expectInterfaceApplicability.kt | 25 ++++++++ .../expectInterfaceApplicability.txt | 30 +++++++++ .../checkers/DiagnosticsTestGenerated.java | 10 +++ .../DiagnosticsUsingJavacTestGenerated.java | 10 +++ .../MultiplatformAnalysisTestGenerated.java | 2 +- .../commonizer/cir/CirFunctionOrProperty.kt | 3 - .../AbstractFunctionOrPropertyCommonizer.kt | 3 +- .../commonized/common/package_root.kt | 3 + .../commonized/js/package_root.kt | 5 ++ .../commonized/jvm/package_root.kt | 5 ++ .../original/js/package_root.kt | 5 ++ .../original/jvm/package_root.kt | 5 ++ ...lableMemberCommonizationFromSourcesTest.kt | 2 + 20 files changed, 289 insertions(+), 10 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/modifiers/openInExpectInterface.fir.kt create mode 100644 compiler/testData/diagnostics/tests/modifiers/openInExpectInterface.kt create mode 100644 compiler/testData/diagnostics/tests/modifiers/openInExpectInterface.txt create mode 100644 compiler/testData/diagnostics/tests/multiplatform/expectInterfaceApplicability.fir.kt create mode 100644 compiler/testData/diagnostics/tests/multiplatform/expectInterfaceApplicability.kt create mode 100644 compiler/testData/diagnostics/tests/multiplatform/expectInterfaceApplicability.txt create mode 100644 native/commonizer/testData/callableMemberCommonization/openCallableMemberInInterface/commonized/common/package_root.kt create mode 100644 native/commonizer/testData/callableMemberCommonization/openCallableMemberInInterface/commonized/js/package_root.kt create mode 100644 native/commonizer/testData/callableMemberCommonization/openCallableMemberInInterface/commonized/jvm/package_root.kt create mode 100644 native/commonizer/testData/callableMemberCommonization/openCallableMemberInInterface/original/js/package_root.kt create mode 100644 native/commonizer/testData/callableMemberCommonization/openCallableMemberInInterface/original/jvm/package_root.kt diff --git a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java index e29daf48860..3053f16d46f 100644 --- a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java @@ -14556,6 +14556,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte runTest("compiler/testData/diagnostics/tests/modifiers/NoLocalVisibility.kt"); } + @TestMetadata("openInExpectInterface.kt") + public void testOpenInExpectInterface() throws Exception { + runTest("compiler/testData/diagnostics/tests/modifiers/openInExpectInterface.kt"); + } + @TestMetadata("openInInterface.kt") public void testOpenInInterface() throws Exception { runTest("compiler/testData/diagnostics/tests/modifiers/openInInterface.kt"); @@ -15015,6 +15020,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/multiplatform"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); } + @TestMetadata("expectInterfaceApplicability.kt") + public void testExpectInterfaceApplicability() throws Exception { + runTest("compiler/testData/diagnostics/tests/multiplatform/expectInterfaceApplicability.kt"); + } + @TestMetadata("headerFunInNonHeaderClass.kt") public void testHeaderFunInNonHeaderClass() throws Exception { runTest("compiler/testData/diagnostics/tests/multiplatform/headerFunInNonHeaderClass.kt"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt index 1ab509d1023..42fea2834eb 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt @@ -772,7 +772,7 @@ class DeclarationsChecker( if (function.hasModifier(KtTokens.PRIVATE_KEYWORD)) { trace.report(PRIVATE_FUNCTION_WITH_NO_BODY.on(function, functionDescriptor)) } - if (!hasAbstractModifier && function.hasModifier(KtTokens.OPEN_KEYWORD)) { + if (!containingDescriptor.isExpect && !hasAbstractModifier && function.hasModifier(KtTokens.OPEN_KEYWORD)) { trace.report(REDUNDANT_OPEN_IN_INTERFACE.on(function)) } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.java index 7c29ab39f7e..0dc196429ab 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.java @@ -80,7 +80,7 @@ public class ModifiersChecker { boolean allowSealed ) { KtModifierList modifierList = (modifierListOwner != null) ? modifierListOwner.getModifierList() : null; - Modality modality = resolveModalityFromModifiers(modifierList, defaultModality, allowSealed); + Modality modality = resolveModalityFromModifiers(containingDescriptor, modifierList, defaultModality, allowSealed); if (modifierListOwner != null) { Collection extensions = @@ -103,6 +103,7 @@ public class ModifiersChecker { @NotNull private static Modality resolveModalityFromModifiers( + @Nullable DeclarationDescriptor containingDescriptor, @Nullable KtModifierList modifierList, @NotNull Modality defaultModality, boolean allowSealed @@ -115,6 +116,12 @@ public class ModifiersChecker { return Modality.SEALED; } if (modifierList.hasModifier(OPEN_KEYWORD)) { + if (containingDescriptor instanceof ClassDescriptor) { + ClassDescriptor classOrInterface = (ClassDescriptor) containingDescriptor; + if (classOrInterface.getKind() == ClassKind.INTERFACE && classOrInterface.isExpect()) { + return Modality.OPEN; + } + } if (hasAbstractModifier || defaultModality == Modality.ABSTRACT) { return Modality.ABSTRACT; } @@ -141,7 +148,10 @@ public class ModifiersChecker { return resolveVisibilityFromModifiers(modifierListOwner.getModifierList(), defaultVisibility); } - public static DescriptorVisibility resolveVisibilityFromModifiers(@Nullable KtModifierList modifierList, @NotNull DescriptorVisibility defaultVisibility) { + public static DescriptorVisibility resolveVisibilityFromModifiers( + @Nullable KtModifierList modifierList, + @NotNull DescriptorVisibility defaultVisibility + ) { if (modifierList == null) return defaultVisibility; if (modifierList.hasModifier(PRIVATE_KEYWORD)) return DescriptorVisibilities.PRIVATE; if (modifierList.hasModifier(PUBLIC_KEYWORD)) return DescriptorVisibilities.PUBLIC; @@ -226,7 +236,7 @@ public class ModifiersChecker { public void checkModifiersForDestructuringDeclaration(@NotNull KtDestructuringDeclaration multiDeclaration) { annotationChecker.check(multiDeclaration, trace, null); ModifierCheckerCore.INSTANCE.check(multiDeclaration, trace, null, languageVersionSettings); - for (KtDestructuringDeclarationEntry multiEntry: multiDeclaration.getEntries()) { + for (KtDestructuringDeclarationEntry multiEntry : multiDeclaration.getEntries()) { annotationChecker.check(multiEntry, trace, null); ModifierCheckerCore.INSTANCE.check(multiEntry, trace, null, languageVersionSettings); UnderscoreChecker.INSTANCE.checkNamed(multiEntry, trace, languageVersionSettings, /* allowSingleUnderscore = */ true); diff --git a/compiler/testData/diagnostics/tests/modifiers/openInExpectInterface.fir.kt b/compiler/testData/diagnostics/tests/modifiers/openInExpectInterface.fir.kt new file mode 100644 index 00000000000..9e7525245ad --- /dev/null +++ b/compiler/testData/diagnostics/tests/modifiers/openInExpectInterface.fir.kt @@ -0,0 +1,37 @@ +// !LANGUAGE: +MultiPlatformProjects +// MODULE: m1-common +// FILE: common.kt +// TODO: .fir.kt version is just a stub. + +expect interface My { + open fun bar() + open fun bas() {} + open abstract fun bat(): Int + + fun foo() + + + open val a: Int + open val b: String + open val c: String get() = "" + open abstract val e: Int + + val f: Int +} + +class MyImpl1: My + +class MyImpl2: My { + override fun foo() {} + override val f = 0 + override val e = 1 +} + +expect interface Outer { + interface Inner { + open fun bar() + open fun bas() {} + open abstract fun bat(): Int + fun foo() + } +} diff --git a/compiler/testData/diagnostics/tests/modifiers/openInExpectInterface.kt b/compiler/testData/diagnostics/tests/modifiers/openInExpectInterface.kt new file mode 100644 index 00000000000..c55f44d63ab --- /dev/null +++ b/compiler/testData/diagnostics/tests/modifiers/openInExpectInterface.kt @@ -0,0 +1,37 @@ +// !LANGUAGE: +MultiPlatformProjects +// MODULE: m1-common +// FILE: common.kt +// TODO: .fir.kt version is just a stub. + +expect interface My { + open fun bar() + open fun bas() {} + open abstract fun bat(): Int + + fun foo() + + + open val a: Int + open val b: String + open val c: String get() = "" + open abstract val e: Int + + val f: Int +} + +class MyImpl1: My + +class MyImpl2: My { + override fun foo() {} + override val f = 0 + override val e = 1 +} + +expect interface Outer { + interface Inner { + open fun bar() + open fun bas() {} + open abstract fun bat(): Int + fun foo() + } +} diff --git a/compiler/testData/diagnostics/tests/modifiers/openInExpectInterface.txt b/compiler/testData/diagnostics/tests/modifiers/openInExpectInterface.txt new file mode 100644 index 00000000000..5e5244be796 --- /dev/null +++ b/compiler/testData/diagnostics/tests/modifiers/openInExpectInterface.txt @@ -0,0 +1,64 @@ +package + +public expect interface My { + public expect open val a: kotlin.Int + public expect open val b: kotlin.String + public expect open val c: kotlin.String + public expect open val e: kotlin.Int + public expect abstract val f: kotlin.Int + public open expect fun bar(): kotlin.Unit + public open expect fun bas(): kotlin.Unit + public open expect fun bat(): kotlin.Int + 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 final class MyImpl1 : My { + public constructor MyImpl1() + public expect open override /*1*/ /*fake_override*/ val a: kotlin.Int + public expect open override /*1*/ /*fake_override*/ val b: kotlin.String + public expect open override /*1*/ /*fake_override*/ val c: kotlin.String + public expect open override /*1*/ /*fake_override*/ val e: kotlin.Int + public expect abstract override /*1*/ /*fake_override*/ val f: kotlin.Int + public open expect override /*1*/ /*fake_override*/ fun bar(): kotlin.Unit + public open expect override /*1*/ /*fake_override*/ fun bas(): kotlin.Unit + public open expect override /*1*/ /*fake_override*/ fun bat(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract 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 +} + +public final class MyImpl2 : My { + public constructor MyImpl2() + public expect open override /*1*/ /*fake_override*/ val a: kotlin.Int + public expect open override /*1*/ /*fake_override*/ val b: kotlin.String + public expect open override /*1*/ /*fake_override*/ val c: kotlin.String + public open override /*1*/ val e: kotlin.Int = 1 + public open override /*1*/ val f: kotlin.Int = 0 + public open expect override /*1*/ /*fake_override*/ fun bar(): kotlin.Unit + public open expect override /*1*/ /*fake_override*/ fun bas(): kotlin.Unit + public open expect override /*1*/ /*fake_override*/ fun bat(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open 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 expect interface Outer { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public expect interface Inner { + public open expect fun bar(): kotlin.Unit + public open expect fun bas(): kotlin.Unit + public open expect fun bat(): kotlin.Int + 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 + } +} diff --git a/compiler/testData/diagnostics/tests/multiplatform/expectInterfaceApplicability.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/expectInterfaceApplicability.fir.kt new file mode 100644 index 00000000000..14ed539ef7f --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/expectInterfaceApplicability.fir.kt @@ -0,0 +1,25 @@ +// !LANGUAGE: +MultiPlatformProjects +// MODULE: m1-common +// FILE: common.kt +// TODO: .fir.kt version is just a stub. +expect interface My { + open fun openFunPositive() + open fun openFunNegative() + abstract fun abstractFun() + + open val openValPositive: Int + open val openValNegative: Int + abstract val abstractVal: Int +} + +// MODULE: m1-jvm(m1-common) +// FILE: jvm.kt +actual interface My { + actual fun openFunPositive() = Unit + actual fun openFunNegative() + actual fun abstractFun() + + actual val openValPositive: Int get() = 0 + actual val openValNegative: Int + actual val abstractVal: Int +} diff --git a/compiler/testData/diagnostics/tests/multiplatform/expectInterfaceApplicability.kt b/compiler/testData/diagnostics/tests/multiplatform/expectInterfaceApplicability.kt new file mode 100644 index 00000000000..5c42615b114 --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/expectInterfaceApplicability.kt @@ -0,0 +1,25 @@ +// !LANGUAGE: +MultiPlatformProjects +// MODULE: m1-common +// FILE: common.kt +// TODO: .fir.kt version is just a stub. +expect interface My { + open fun openFunPositive() + open fun openFunNegative() + abstract fun abstractFun() + + open val openValPositive: Int + open val openValNegative: Int + abstract val abstractVal: Int +} + +// MODULE: m1-jvm(m1-common) +// FILE: jvm.kt +actual interface My { + actual fun openFunPositive() = Unit + actual fun openFunNegative() + actual fun abstractFun() + + actual val openValPositive: Int get() = 0 + actual val openValNegative: Int + actual val abstractVal: Int +} diff --git a/compiler/testData/diagnostics/tests/multiplatform/expectInterfaceApplicability.txt b/compiler/testData/diagnostics/tests/multiplatform/expectInterfaceApplicability.txt new file mode 100644 index 00000000000..9b270da5a3b --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/expectInterfaceApplicability.txt @@ -0,0 +1,30 @@ +// -- Module: -- +package + +public expect interface My { + public expect abstract val abstractVal: kotlin.Int + public expect open val openValNegative: kotlin.Int + public expect open val openValPositive: kotlin.Int + public abstract expect fun abstractFun(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open expect fun openFunNegative(): kotlin.Unit + public open expect fun openFunPositive(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + + +// -- Module: -- +package + +public actual interface My { + public actual abstract val abstractVal: kotlin.Int + public actual abstract val openValNegative: kotlin.Int + public actual open val openValPositive: kotlin.Int + public abstract actual fun abstractFun(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public abstract actual fun openFunNegative(): kotlin.Unit + public open actual fun openFunPositive(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 65c2b18fc0a..8bc1276f43e 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -14563,6 +14563,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTestWithFirVali runTest("compiler/testData/diagnostics/tests/modifiers/NoLocalVisibility.kt"); } + @TestMetadata("openInExpectInterface.kt") + public void testOpenInExpectInterface() throws Exception { + runTest("compiler/testData/diagnostics/tests/modifiers/openInExpectInterface.kt"); + } + @TestMetadata("openInInterface.kt") public void testOpenInInterface() throws Exception { runTest("compiler/testData/diagnostics/tests/modifiers/openInInterface.kt"); @@ -15022,6 +15027,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTestWithFirVali KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/multiplatform"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); } + @TestMetadata("expectInterfaceApplicability.kt") + public void testExpectInterfaceApplicability() throws Exception { + runTest("compiler/testData/diagnostics/tests/multiplatform/expectInterfaceApplicability.kt"); + } + @TestMetadata("headerFunInNonHeaderClass.kt") public void testHeaderFunInNonHeaderClass() throws Exception { runTest("compiler/testData/diagnostics/tests/multiplatform/headerFunInNonHeaderClass.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index 39d7c9033e0..69aee9d9d3e 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -14558,6 +14558,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing runTest("compiler/testData/diagnostics/tests/modifiers/NoLocalVisibility.kt"); } + @TestMetadata("openInExpectInterface.kt") + public void testOpenInExpectInterface() throws Exception { + runTest("compiler/testData/diagnostics/tests/modifiers/openInExpectInterface.kt"); + } + @TestMetadata("openInInterface.kt") public void testOpenInInterface() throws Exception { runTest("compiler/testData/diagnostics/tests/modifiers/openInInterface.kt"); @@ -15017,6 +15022,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/multiplatform"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); } + @TestMetadata("expectInterfaceApplicability.kt") + public void testExpectInterfaceApplicability() throws Exception { + runTest("compiler/testData/diagnostics/tests/multiplatform/expectInterfaceApplicability.kt"); + } + @TestMetadata("headerFunInNonHeaderClass.kt") public void testHeaderFunInNonHeaderClass() throws Exception { runTest("compiler/testData/diagnostics/tests/multiplatform/headerFunInNonHeaderClass.kt"); diff --git a/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/MultiplatformAnalysisTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/MultiplatformAnalysisTestGenerated.java index 10c882c18af..28b76bd5015 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/MultiplatformAnalysisTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/MultiplatformAnalysisTestGenerated.java @@ -208,7 +208,7 @@ public class MultiplatformAnalysisTestGenerated extends AbstractMultiplatformAna runTest("idea/testData/multiplatform/simple/"); } - @TestMetadata("simple") + @TestMetadata("smartCastOnPropertyFromDependentModule") public void testSmartCastOnPropertyFromDependentModule() throws Exception { runTest("idea/testData/multiplatform/smartCastOnPropertyFromDependentModule/"); } diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirFunctionOrProperty.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirFunctionOrProperty.kt index 24eee73dbe8..e407bf3129e 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirFunctionOrProperty.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirFunctionOrProperty.kt @@ -23,9 +23,6 @@ interface CirFunctionOrProperty : val returnType: CirType val kind: CallableMemberDescriptor.Kind - fun isNonAbstractMemberInInterface(): Boolean = - modality != Modality.ABSTRACT && containingClassDetails?.kind == ClassKind.INTERFACE - fun isVirtual(): Boolean = visibility != DescriptorVisibilities.PRIVATE && modality != Modality.FINAL diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/AbstractFunctionOrPropertyCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/AbstractFunctionOrPropertyCommonizer.kt index cad31c5d08d..818b66989a3 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/AbstractFunctionOrPropertyCommonizer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/AbstractFunctionOrPropertyCommonizer.kt @@ -29,8 +29,7 @@ abstract class AbstractFunctionOrPropertyCommonizer( } override fun doCommonizeWith(next: T): Boolean = - !next.isNonAbstractMemberInInterface() // non-abstract callable members declared in interface can't be commonized - && next.kind != DELEGATION // delegated members should not be commonized + next.kind != DELEGATION // delegated members should not be commonized && (next.kind != SYNTHESIZED || next.containingClassDetails?.isData != true) // synthesized members of data classes should not be commonized && kind == next.kind && modality.commonizeWith(next.modality) diff --git a/native/commonizer/testData/callableMemberCommonization/openCallableMemberInInterface/commonized/common/package_root.kt b/native/commonizer/testData/callableMemberCommonization/openCallableMemberInInterface/commonized/common/package_root.kt new file mode 100644 index 00000000000..797de95d8cf --- /dev/null +++ b/native/commonizer/testData/callableMemberCommonization/openCallableMemberInInterface/commonized/common/package_root.kt @@ -0,0 +1,3 @@ +expect interface Interface { + open fun openFun() +} diff --git a/native/commonizer/testData/callableMemberCommonization/openCallableMemberInInterface/commonized/js/package_root.kt b/native/commonizer/testData/callableMemberCommonization/openCallableMemberInInterface/commonized/js/package_root.kt new file mode 100644 index 00000000000..99b9d92f63f --- /dev/null +++ b/native/commonizer/testData/callableMemberCommonization/openCallableMemberInInterface/commonized/js/package_root.kt @@ -0,0 +1,5 @@ +actual interface Interface { + actual fun openFun() = Unit + fun openFunWithOtherParams(param: Int) = Unit + fun openInJs_abstractInJvm() = Unit +} diff --git a/native/commonizer/testData/callableMemberCommonization/openCallableMemberInInterface/commonized/jvm/package_root.kt b/native/commonizer/testData/callableMemberCommonization/openCallableMemberInInterface/commonized/jvm/package_root.kt new file mode 100644 index 00000000000..afb2a58fabf --- /dev/null +++ b/native/commonizer/testData/callableMemberCommonization/openCallableMemberInInterface/commonized/jvm/package_root.kt @@ -0,0 +1,5 @@ +actual interface Interface { + actual fun openFun() = Unit + fun openFunWithOtherParams(param: Double) = Unit + fun openInJs_abstractInJvm() +} diff --git a/native/commonizer/testData/callableMemberCommonization/openCallableMemberInInterface/original/js/package_root.kt b/native/commonizer/testData/callableMemberCommonization/openCallableMemberInInterface/original/js/package_root.kt new file mode 100644 index 00000000000..d344e96a346 --- /dev/null +++ b/native/commonizer/testData/callableMemberCommonization/openCallableMemberInInterface/original/js/package_root.kt @@ -0,0 +1,5 @@ +interface Interface { + fun openFun() = Unit + fun openFunWithOtherParams(param: Int) = Unit + fun openInJs_abstractInJvm() = Unit +} diff --git a/native/commonizer/testData/callableMemberCommonization/openCallableMemberInInterface/original/jvm/package_root.kt b/native/commonizer/testData/callableMemberCommonization/openCallableMemberInInterface/original/jvm/package_root.kt new file mode 100644 index 00000000000..39e18dc61c6 --- /dev/null +++ b/native/commonizer/testData/callableMemberCommonization/openCallableMemberInInterface/original/jvm/package_root.kt @@ -0,0 +1,5 @@ +interface Interface { + fun openFun() = Unit + fun openFunWithOtherParams(param: Double) = Unit + fun openInJs_abstractInJvm() +} diff --git a/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/CallableMemberCommonizationFromSourcesTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/CallableMemberCommonizationFromSourcesTest.kt index e99cc407631..cf4409d281f 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/CallableMemberCommonizationFromSourcesTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/CallableMemberCommonizationFromSourcesTest.kt @@ -15,4 +15,6 @@ class CallableMemberCommonizationFromSourcesTest : AbstractCommonizationFromSour fun testReturnTypes() = doTestSuccessfulCommonization() fun testExtensionReceivers() = doTestSuccessfulCommonization() + + fun testOpenCallableMemberInInterface() = doTestSuccessfulCommonization() }