diff --git a/compiler/testData/codegen/box/defaultArguments/inheritedFromInterfaceViaAbstractSuperclass.kt b/compiler/testData/codegen/box/defaultArguments/inheritedFromInterfaceViaAbstractSuperclass.kt new file mode 100644 index 00000000000..b74007df30e --- /dev/null +++ b/compiler/testData/codegen/box/defaultArguments/inheritedFromInterfaceViaAbstractSuperclass.kt @@ -0,0 +1,17 @@ +interface I { + fun foo(x: Int = 23): String +} + +abstract class Base : I + +class C : Base(), I { + override fun foo(x: Int) = "C:$x" +} + +fun box(): String { + val x: I = C() + val r = x.foo() + ";" + x.foo(42) + if (r != "C:23;C:42") return "fail: $r" + + return "OK" +} \ No newline at end of file diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 80800891a98..432c90eac09 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -6479,6 +6479,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); } + @TestMetadata("inheritedFromInterfaceViaAbstractSuperclass.kt") + public void testInheritedFromInterfaceViaAbstractSuperclass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/defaultArguments/inheritedFromInterfaceViaAbstractSuperclass.kt"); + doTest(fileName); + } + @TestMetadata("kt6382.kt") public void testKt6382() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/defaultArguments/kt6382.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index cca5d666cd8..76893a87724 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -6479,6 +6479,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); } + @TestMetadata("inheritedFromInterfaceViaAbstractSuperclass.kt") + public void testInheritedFromInterfaceViaAbstractSuperclass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/defaultArguments/inheritedFromInterfaceViaAbstractSuperclass.kt"); + doTest(fileName); + } + @TestMetadata("kt6382.kt") public void testKt6382() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/defaultArguments/kt6382.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index a97ded3eadf..93dee7c4d1f 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -6479,6 +6479,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/defaultArguments"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); } + @TestMetadata("inheritedFromInterfaceViaAbstractSuperclass.kt") + public void testInheritedFromInterfaceViaAbstractSuperclass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/defaultArguments/inheritedFromInterfaceViaAbstractSuperclass.kt"); + doTest(fileName); + } + @TestMetadata("kt6382.kt") public void testKt6382() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/defaultArguments/kt6382.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 7a0d53e6ca3..f7196604228 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -7151,6 +7151,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { doTest(fileName); } + @TestMetadata("inheritedFromInterfaceViaAbstractSuperclass.kt") + public void testInheritedFromInterfaceViaAbstractSuperclass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/defaultArguments/inheritedFromInterfaceViaAbstractSuperclass.kt"); + doTest(fileName); + } + @TestMetadata("kt6382.kt") public void testKt6382() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/defaultArguments/kt6382.kt"); diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/ClassModelGenerator.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/ClassModelGenerator.kt index 83b68ab0bc7..241ed123c7b 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/ClassModelGenerator.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/ClassModelGenerator.kt @@ -54,7 +54,7 @@ class ClassModelGenerator(val context: TranslationContext) { // Traverse fake non-abstract member. Current class does not provide their implementation, // it can be inherited from interface. - for (member in members.filter { !it.kind.isReal && it.modality != Modality.ABSTRACT }) { + for (member in members.filter { !it.kind.isReal }) { if (member is FunctionDescriptor) { tryCopyWhenImplementingInterfaceWithDefaultArgs(member, model) } @@ -63,7 +63,7 @@ class ClassModelGenerator(val context: TranslationContext) { // Copy *implementation* functions (i.e. those ones which end with `$default` suffix) // of Kotlin functions with optional parameters. - if (member is FunctionDescriptor && !hasImplementationInPrototype(member)) { + if (member is FunctionDescriptor && !hasImplementationInPrototype(member) && member.modality != Modality.ABSTRACT) { copyMemberWithOptionalArgs(descriptor, member, model, Namer.DEFAULT_PARAMETER_IMPLEMENTOR_SUFFIX) } } @@ -155,7 +155,10 @@ class ClassModelGenerator(val context: TranslationContext) { // When none found, we have nothing to copy, ignore. // When multiple found, our current class should provide implementation, ignore. val memberToCopy = member.findNonRepeatingOverriddenDescriptors({ overriddenDescriptors }, { original }) - .singleOrNull { it.modality != Modality.ABSTRACT } ?: return null + .singleOrNull { + it.modality != Modality.ABSTRACT || + (it is FunctionDescriptor && it.hasOwnParametersWithDefaultValue()) + } ?: return null // If found member is not from interface, we don't need to copy it, it's already in prototype if ((memberToCopy.containingDeclaration as ClassDescriptor).kind != ClassKind.INTERFACE) return null