diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java index ead3aa391b2..cb67e396a17 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java @@ -591,6 +591,37 @@ public class KotlinTypeMapper { return Variance.OUT_VARIANCE; } + //NB: similar platform agnostic code in DescriptorUtils.unwrapFakeOverride + private FunctionDescriptor findSuperDeclaration(@NotNull FunctionDescriptor descriptor, boolean isSuperCall) { + while (descriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { + Collection overridden = descriptor.getOverriddenDescriptors(); + if (overridden.isEmpty()) { + throw new IllegalStateException("Fake override should have at least one overridden descriptor: " + descriptor); + } + + FunctionDescriptor classCallable = null; + for (FunctionDescriptor overriddenFunction : overridden) { + if (!isInterface(overriddenFunction.getContainingDeclaration())) { + classCallable = overriddenFunction; + break; + } + } + + if (classCallable != null) { + //prefer class callable cause of else branch + descriptor = classCallable; + continue; + } + else if (isSuperCall && !isJvm8Target && !isInterface(descriptor.getContainingDeclaration())) { + //Don't unwrap fake overrides from class to interface cause substituted override would be implicitly generated for target 1.6 + return descriptor; + } + + descriptor = overridden.iterator().next(); + } + return descriptor; + } + @NotNull public CallableMethod mapToCallableMethod(@NotNull FunctionDescriptor descriptor, boolean superCall) { if (descriptor instanceof ConstructorDescriptor) { @@ -609,7 +640,7 @@ public class KotlinTypeMapper { DeclarationDescriptor functionParent = descriptor.getOriginal().getContainingDeclaration(); - FunctionDescriptor functionDescriptor = unwrapFakeOverride(descriptor.getOriginal()); + FunctionDescriptor functionDescriptor = findSuperDeclaration(descriptor.getOriginal(), superCall); JvmMethodSignature signature; Type owner; diff --git a/compiler/testData/codegen/box/super/kt14243.kt b/compiler/testData/codegen/box/super/kt14243.kt new file mode 100644 index 00000000000..75d5fcb7ae7 --- /dev/null +++ b/compiler/testData/codegen/box/super/kt14243.kt @@ -0,0 +1,18 @@ +interface Z { + fun test(p: T): T { + return p + } +} + +open class ZImpl : Z + +class ZImpl2 : ZImpl() { + + override fun test(p: String): String { + return super.test(p) + } +} + +fun box(): String { + return ZImpl2().test("OK") +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/super/kt14243_2.kt b/compiler/testData/codegen/box/super/kt14243_2.kt new file mode 100644 index 00000000000..b72bf3dac7c --- /dev/null +++ b/compiler/testData/codegen/box/super/kt14243_2.kt @@ -0,0 +1,20 @@ +interface Z { + fun test(p: T): T { + return p + } +} + +open class ZImpl : Z + +open class ZImpl2 : Z, ZImpl() + +class ZImpl3 : ZImpl2() { + + override fun test(p: String): String { + return super.test(p) + } +} + +fun box(): String { + return ZImpl3().test("OK") +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/super/kt14243_class.kt b/compiler/testData/codegen/box/super/kt14243_class.kt new file mode 100644 index 00000000000..c0ec94be493 --- /dev/null +++ b/compiler/testData/codegen/box/super/kt14243_class.kt @@ -0,0 +1,20 @@ + +open class Z { + open fun test(p: T, z: Y): T { + return p + } +} + +open class ZImpl : Z() + +open class ZImpl2 : ZImpl() + +class ZImpl3 : ZImpl2() { + override fun test(p: String, z: String): String { + return super.test(p, z) + } +} + +fun box(): String { + return ZImpl3().test("OK", "fail") +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/super/kt14243_prop.kt b/compiler/testData/codegen/box/super/kt14243_prop.kt new file mode 100644 index 00000000000..73979c08226 --- /dev/null +++ b/compiler/testData/codegen/box/super/kt14243_prop.kt @@ -0,0 +1,21 @@ +interface Z { + val value: T + + val z: T + get() = value +} + +open class ZImpl : Z { + override val value: String + get() = "OK" +} + +open class ZImpl2 : ZImpl() { + override val z: String + get() = super.z +} + + +fun box(): String { + return ZImpl2().value +} \ No newline at end of file diff --git a/compiler/testData/codegen/java8/box/jvm8/kt14243.kt b/compiler/testData/codegen/java8/box/jvm8/kt14243.kt new file mode 100644 index 00000000000..bd836e9850e --- /dev/null +++ b/compiler/testData/codegen/java8/box/jvm8/kt14243.kt @@ -0,0 +1,20 @@ +// JVM_TARGET: 1.8 + +interface Z { + fun test(p: T): T { + return p + } +} + +open class ZImpl : Z + +class ZImpl2 : ZImpl() { + + override fun test(p: String): String { + return super.test(p) + } +} + +fun box(): String { + return ZImpl2().test("OK") +} \ No newline at end of file diff --git a/compiler/testData/codegen/java8/box/jvm8/kt14243_2.kt b/compiler/testData/codegen/java8/box/jvm8/kt14243_2.kt new file mode 100644 index 00000000000..5983dff22dc --- /dev/null +++ b/compiler/testData/codegen/java8/box/jvm8/kt14243_2.kt @@ -0,0 +1,22 @@ +// JVM_TARGET: 1.8 + +interface Z { + fun test(p: T): T { + return p + } +} + +open class ZImpl : Z + +open class ZImpl2 : Z, ZImpl() + +class ZImpl3 : ZImpl2() { + + override fun test(p: String): String { + return super.test(p) + } +} + +fun box(): String { + return ZImpl3().test("OK") +} \ No newline at end of file diff --git a/compiler/testData/codegen/java8/box/jvm8/kt14243_prop.kt b/compiler/testData/codegen/java8/box/jvm8/kt14243_prop.kt new file mode 100644 index 00000000000..3053ee099b5 --- /dev/null +++ b/compiler/testData/codegen/java8/box/jvm8/kt14243_prop.kt @@ -0,0 +1,23 @@ +// JVM_TARGET: 1.8 + +interface Z { + val value: T + + val z: T + get() = value +} + +open class ZImpl : Z { + override val value: String + get() = "OK" +} + +open class ZImpl2 : ZImpl() { + override val z: String + get() = super.z +} + + +fun box(): String { + return ZImpl2().value +} \ No newline at end of file diff --git a/compiler/tests-java8/tests/org/jetbrains/kotlin/codegen/BlackBoxWithJava8CodegenTestGenerated.java b/compiler/tests-java8/tests/org/jetbrains/kotlin/codegen/BlackBoxWithJava8CodegenTestGenerated.java index 16ef6108147..a7f18d70b1b 100644 --- a/compiler/tests-java8/tests/org/jetbrains/kotlin/codegen/BlackBoxWithJava8CodegenTestGenerated.java +++ b/compiler/tests-java8/tests/org/jetbrains/kotlin/codegen/BlackBoxWithJava8CodegenTestGenerated.java @@ -151,6 +151,24 @@ public class BlackBoxWithJava8CodegenTestGenerated extends AbstractBlackBoxCodeg doTest(fileName); } + @TestMetadata("kt14243.kt") + public void testKt14243() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/java8/box/jvm8/kt14243.kt"); + doTest(fileName); + } + + @TestMetadata("kt14243_2.kt") + public void testKt14243_2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/java8/box/jvm8/kt14243_2.kt"); + doTest(fileName); + } + + @TestMetadata("kt14243_prop.kt") + public void testKt14243_prop() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/java8/box/jvm8/kt14243_prop.kt"); + doTest(fileName); + } + @TestMetadata("oneImplementation.kt") public void testOneImplementation() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/java8/box/jvm8/oneImplementation.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index b397e72bfac..86997128f39 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -15187,6 +15187,30 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("kt14243.kt") + public void testKt14243() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/super/kt14243.kt"); + doTest(fileName); + } + + @TestMetadata("kt14243_2.kt") + public void testKt14243_2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/super/kt14243_2.kt"); + doTest(fileName); + } + + @TestMetadata("kt14243_class.kt") + public void testKt14243_class() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/super/kt14243_class.kt"); + doTest(fileName); + } + + @TestMetadata("kt14243_prop.kt") + public void testKt14243_prop() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/super/kt14243_prop.kt"); + doTest(fileName); + } + @TestMetadata("kt3492ClassFun.kt") public void testKt3492ClassFun() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/super/kt3492ClassFun.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/SuperTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/SuperTestGenerated.java index 8b4fbf5437f..082107d59f3 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/SuperTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/SuperTestGenerated.java @@ -101,6 +101,30 @@ public class SuperTestGenerated extends AbstractSuperTest { doTest(fileName); } + @TestMetadata("kt14243.kt") + public void testKt14243() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/super/kt14243.kt"); + doTest(fileName); + } + + @TestMetadata("kt14243_2.kt") + public void testKt14243_2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/super/kt14243_2.kt"); + doTest(fileName); + } + + @TestMetadata("kt14243_class.kt") + public void testKt14243_class() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/super/kt14243_class.kt"); + doTest(fileName); + } + + @TestMetadata("kt14243_prop.kt") + public void testKt14243_prop() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/super/kt14243_prop.kt"); + doTest(fileName); + } + @TestMetadata("kt3492ClassFun.kt") public void testKt3492ClassFun() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/super/kt3492ClassFun.kt");