From bfa2937fb8f54c9e63ab163323e4f5c2cdcf28ee Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov Date: Wed, 15 Feb 2023 17:23:35 +0100 Subject: [PATCH] FIR2IR: Do not add fake override if the member is overridden #KT-56398 Fixed --- .../FirBlackBoxCodegenTestGenerated.java | 6 ++ .../FirPsiBlackBoxCodegenTestGenerated.java | 6 ++ .../actualizer/MissingFakeOverridesAdder.kt | 57 +++++++++++++------ .../multiModule/expectInterfaceInheritance.kt | 25 ++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 ++ .../IrBlackBoxCodegenTestGenerated.java | 6 ++ .../LightAnalysisModeTestGenerated.java | 5 ++ 7 files changed, 94 insertions(+), 17 deletions(-) create mode 100644 compiler/testData/codegen/box/multiplatform/multiModule/expectInterfaceInheritance.kt diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index 84ef171ce55..332da9cdff5 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -33148,6 +33148,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/multiplatform/multiModule/expectInterfaceInSupertypes.kt"); } + @Test + @TestMetadata("expectInterfaceInheritance.kt") + public void testExpectInterfaceInheritance() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/multiModule/expectInterfaceInheritance.kt"); + } + @Test @TestMetadata("fakeOverridesInPlatformModule.kt") public void testFakeOverridesInPlatformModule() throws Exception { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java index 3179bcf3fcd..340793fe047 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java @@ -33148,6 +33148,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo runTest("compiler/testData/codegen/box/multiplatform/multiModule/expectInterfaceInSupertypes.kt"); } + @Test + @TestMetadata("expectInterfaceInheritance.kt") + public void testExpectInterfaceInheritance() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/multiModule/expectInterfaceInheritance.kt"); + } + @Test @TestMetadata("fakeOverridesInPlatformModule.kt") public void testFakeOverridesInPlatformModule() throws Exception { diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/MissingFakeOverridesAdder.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/MissingFakeOverridesAdder.kt index 412e3754225..2ba3eaa826f 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/MissingFakeOverridesAdder.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/actualizer/MissingFakeOverridesAdder.kt @@ -43,25 +43,48 @@ class MissingFakeOverridesAdder( } for (superType in declaration.superTypes) { - val actualClass = expectActualMap[superType.classifierOrFail]?.owner as? IrClass ?: continue - for (actualMember in actualClass.declarations) { - if (actualMember.isBuiltinMember()) continue - when (actualMember) { - is IrFunctionImpl, - is IrPropertyImpl -> { - if (members[generateIrElementFullName(actualMember, expectActualMap, typeAliasMap)] != null) { - reportManyInterfacesMembersNotImplemented(declaration, actualMember as IrDeclarationWithName) - continue - } + val expectClass = superType.classifierOrFail.owner as? IrClass ?: continue + val added = mutableSetOf() + for (expectMember in expectClass.declarations) { + if (expectMember.isBuiltinMember()) continue + val actualMember = expectActualMap[expectMember.symbol]?.owner as? IrDeclaration ?: continue - val newMember = if (actualMember is IrFunctionImpl) { - createFakeOverrideFunction(actualMember, declaration) - } else { - createFakeOverrideProperty(actualMember as IrPropertyImpl, declaration) - } - declaration.declarations.add(newMember) - } + // Do not add FAKE_OVERRIDE if the subclass already has overridden member + if (declaration.declarations.filterIsInstance>() + .any { expectMember.symbol in it.overriddenSymbols } + ) { + continue } + addFakeOverride(actualMember, members, declaration) + added += actualMember + } + val actualClass = expectActualMap[expectClass.symbol]?.owner as? IrClass ?: continue + for (actualMember in actualClass.declarations) { + if (actualMember.isBuiltinMember() || actualMember in added) continue + addFakeOverride(actualMember, members, declaration) + } + } + } + + private fun addFakeOverride( + actualMember: IrDeclaration, + members: Map, + declaration: IrClass + ) { + when (actualMember) { + is IrFunctionImpl, + is IrPropertyImpl -> { + if (members[generateIrElementFullName(actualMember, expectActualMap, typeAliasMap)] != null) { + reportManyInterfacesMembersNotImplemented(declaration, actualMember as IrDeclarationWithName) + return + } + + val newMember = if (actualMember is IrFunctionImpl) { + createFakeOverrideFunction(actualMember, declaration) + } else { + createFakeOverrideProperty(actualMember as IrPropertyImpl, declaration) + } + declaration.declarations.add(newMember) } } } diff --git a/compiler/testData/codegen/box/multiplatform/multiModule/expectInterfaceInheritance.kt b/compiler/testData/codegen/box/multiplatform/multiModule/expectInterfaceInheritance.kt new file mode 100644 index 00000000000..2b158205b3f --- /dev/null +++ b/compiler/testData/codegen/box/multiplatform/multiModule/expectInterfaceInheritance.kt @@ -0,0 +1,25 @@ +// ISSUE: KT-56398 +// TARGET_BACKEND: JVM +// !LANGUAGE: +MultiPlatformProjects + +// MODULE: common +// TARGET_PLATFORM: Common +// FILE: common.kt + +expect interface Interface { + fun foo(): String +} + +class Klass : Interface { + override fun foo() = "OK" +} + +// MODULE: jvm()()(common) +// TARGET_PLATFORM: JVM +// FILE: main.kt + +actual interface Interface { + actual fun foo(): String +} + +fun box() = Klass().foo() \ No newline at end of file diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index da3c88cae74..045f3c73b74 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -31822,6 +31822,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/multiplatform/multiModule/expectInterfaceInSupertypes.kt"); } + @Test + @TestMetadata("expectInterfaceInheritance.kt") + public void testExpectInterfaceInheritance() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/multiModule/expectInterfaceInheritance.kt"); + } + @Test @TestMetadata("fakeOverridesInPlatformModule.kt") public void testFakeOverridesInPlatformModule() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index cefce102f33..b84153621fc 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -33148,6 +33148,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/multiplatform/multiModule/expectInterfaceInSupertypes.kt"); } + @Test + @TestMetadata("expectInterfaceInheritance.kt") + public void testExpectInterfaceInheritance() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/multiModule/expectInterfaceInheritance.kt"); + } + @Test @TestMetadata("fakeOverridesInPlatformModule.kt") public void testFakeOverridesInPlatformModule() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 66e245599a9..ed83514f264 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -27089,6 +27089,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/multiplatform/multiModule/expectInterfaceInSupertypes.kt"); } + @TestMetadata("expectInterfaceInheritance.kt") + public void testExpectInterfaceInheritance() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/multiModule/expectInterfaceInheritance.kt"); + } + @TestMetadata("fakeOverridesInPlatformModule.kt") public void testFakeOverridesInPlatformModule() throws Exception { runTest("compiler/testData/codegen/box/multiplatform/multiModule/fakeOverridesInPlatformModule.kt");