diff --git a/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/bridges/bridges.kt b/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/bridges/bridges.kt index e2a5a0b0962..ebf4aa03ddc 100644 --- a/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/bridges/bridges.kt +++ b/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/bridges/bridges.kt @@ -23,6 +23,12 @@ interface FunctionHandle { val isDeclaration: Boolean val isAbstract: Boolean + /** On finding concrete super declaration we should distinguish non-abstract java8/js default methods from + * class ones (see [findConcreteSuperDeclaration] method in bridges.kt). + * Note that interface methods with body compiled to jvm 8 target are assumed to be non-abstract in bridges method calculation + * (more details in [DescriptorBasedFunctionHandle.isBodyOwner] comment).*/ + val isInterfaceDeclaration: Boolean + fun getOverridden(): Iterable } @@ -108,7 +114,7 @@ fun findConcreteSuperDeclaration(function: Function) } result.removeAll(toRemove) - val concreteRelevantDeclarations = result.filter { !it.isAbstract } + val concreteRelevantDeclarations = result.filter { !it.isAbstract && !it.isInterfaceDeclaration } if (concreteRelevantDeclarations.size != 1) { error("Concrete fake override $function should have exactly one concrete super-declaration: $concreteRelevantDeclarations") } diff --git a/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/bridges/impl.kt b/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/bridges/impl.kt index 35034288dfb..cae1d6581fb 100644 --- a/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/bridges/impl.kt +++ b/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/bridges/impl.kt @@ -72,6 +72,9 @@ class DescriptorBasedFunctionHandle( descriptor.modality == Modality.ABSTRACT || isBodyOwner(descriptor.containingDeclaration) + override val isInterfaceDeclaration: Boolean + get() = DescriptorUtils.isInterface(descriptor.containingDeclaration) + override fun getOverridden() = overridden override fun hashCode(): Int { diff --git a/compiler/testData/codegen/java8/box/jvm8/oneImplementation.kt b/compiler/testData/codegen/java8/box/jvm8/oneImplementation.kt new file mode 100644 index 00000000000..54c1c1856c9 --- /dev/null +++ b/compiler/testData/codegen/java8/box/jvm8/oneImplementation.kt @@ -0,0 +1,19 @@ +// JVM_TARGET: 1.8 +interface KCallable { + val returnType: String +} + +interface KCallableImpl : KCallable { + override val returnType: String + get() = "OK" +} + +interface KCallableImpl2 : KCallableImpl + +open class DescriptorBasedProperty : KCallableImpl +open class KProperty1Impl : DescriptorBasedProperty(), KCallableImpl2 +open class KMutableProperty1Impl : KProperty1Impl(), KCallable + +fun box(): String { + return KMutableProperty1Impl().returnType +} \ No newline at end of file diff --git a/compiler/testData/codegen/java8/box/jvm8/oneImplementation2.kt b/compiler/testData/codegen/java8/box/jvm8/oneImplementation2.kt new file mode 100644 index 00000000000..d589a769929 --- /dev/null +++ b/compiler/testData/codegen/java8/box/jvm8/oneImplementation2.kt @@ -0,0 +1,24 @@ +// JVM_TARGET: 1.8 +interface KCallable { + val returnType: String +} + +interface KCallableImpl : KCallable { + override val returnType: String + get() = "OK" +} + +interface KProperty : KCallable +interface KPropertyImpl : KProperty, KCallableImpl +interface KMutableProperty : KProperty +interface KProperty1 : KProperty +interface KMutableProperty1 : KProperty1, KMutableProperty +interface KMutablePropertyImpl : KPropertyImpl + +open class DescriptorBasedProperty : KCallableImpl +open class KProperty1Impl : DescriptorBasedProperty(), KProperty1, KPropertyImpl +open class KMutableProperty1Impl : KProperty1Impl(), KMutableProperty1, KMutablePropertyImpl + +fun box(): String { + return KMutableProperty1Impl().returnType +} \ 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 c6ddbfdd80d..cff6c718f70 100644 --- a/compiler/tests-java8/tests/org/jetbrains/kotlin/codegen/BlackBoxWithJava8CodegenTestGenerated.java +++ b/compiler/tests-java8/tests/org/jetbrains/kotlin/codegen/BlackBoxWithJava8CodegenTestGenerated.java @@ -145,6 +145,18 @@ public class BlackBoxWithJava8CodegenTestGenerated extends AbstractBlackBoxCodeg doTest(fileName); } + @TestMetadata("oneImplementation.kt") + public void testOneImplementation() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/java8/box/jvm8/oneImplementation.kt"); + doTest(fileName); + } + + @TestMetadata("oneImplementation2.kt") + public void testOneImplementation2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/java8/box/jvm8/oneImplementation2.kt"); + doTest(fileName); + } + @TestMetadata("simpleCall.kt") public void testSimpleCall() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/java8/box/jvm8/simpleCall.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BridgeTest.kt b/compiler/tests/org/jetbrains/kotlin/codegen/BridgeTest.kt index a380293f359..ed07b7cf06c 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BridgeTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BridgeTest.kt @@ -28,7 +28,7 @@ class BridgeTest : TestCase() { private class Fun(val text: String) : FunctionHandle { override val isDeclaration: Boolean get() = text[1] == 'D' override val isAbstract: Boolean get() = text[0] == '-' - + override val isInterfaceDeclaration: Boolean get() = false val signature: Char get() = text[2] val overriddenFunctions: MutableList = arrayListOf()