From 95a1c254e1d4721534348e5ecdc80bf8f7f2f838 Mon Sep 17 00:00:00 2001 From: Michael Bogdanov Date: Wed, 28 Sep 2016 12:11:29 +0300 Subject: [PATCH] Added error diagnostic on inheriting target 6 interface --- .../codegen/ImplementationBodyCodegen.java | 12 +++++- .../jetbrains/kotlin/codegen/codegenUtil.kt | 24 +++++++++++- .../diagnostics/DefaultErrorMessagesJvm.java | 6 +++ .../resolve/jvm/diagnostics/ErrorsJvm.java | 8 ++-- .../delegationToDefaultMethodInClass.kt | 18 +++------ .../delegationToDefaultMethodInInterface.kt | 17 +++++---- .../delegationToDefaultMethodInInterface2.kt | 33 ++--------------- .../jvm8against6/delegation/diamond.kt | 37 ++++--------------- .../jvm8against6/delegation/diamond2.kt | 37 ++++--------------- .../jvm8against6/delegation/diamond3.kt | 33 +++-------------- .../jvm8against6/simpleCall.kt | 4 +- .../jvm8against6/simpleCallWithHierarchy.kt | 4 +- .../jvm8against6/simpleProp.kt | 17 +++++++++ .../target6Inheritance/main.kt | 13 +++++++ .../target6Inheritance/output.txt | 10 +++++ .../target6Inheritance/target6.kt | 9 +++++ .../target6MultiInheritance/main.kt | 14 +++++++ .../target6MultiInheritance/output.txt | 13 +++++++ .../target6MultiInheritance/target6.kt | 13 +++++++ ...mpileKotlinAgainstKotlinTestGenerated.java | 6 +++ ...ompileKotlinAgainstCustomBinariesTest.java | 33 +++++++++++++++++ 21 files changed, 217 insertions(+), 144 deletions(-) create mode 100644 compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/simpleProp.kt create mode 100644 compiler/testData/compileKotlinAgainstCustomBinaries/target6Inheritance/main.kt create mode 100644 compiler/testData/compileKotlinAgainstCustomBinaries/target6Inheritance/output.txt create mode 100644 compiler/testData/compileKotlinAgainstCustomBinaries/target6Inheritance/target6.kt create mode 100644 compiler/testData/compileKotlinAgainstCustomBinaries/target6MultiInheritance/main.kt create mode 100644 compiler/testData/compileKotlinAgainstCustomBinaries/target6MultiInheritance/output.txt create mode 100644 compiler/testData/compileKotlinAgainstCustomBinaries/target6MultiInheritance/target6.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java index ccd8d550001..b08a7264fa4 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java @@ -52,6 +52,7 @@ import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument; import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; import org.jetbrains.kotlin.resolve.calls.model.VarargValueArgument; import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt; +import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm; import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin; import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmClassSignature; @@ -63,6 +64,7 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver; import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue; import org.jetbrains.kotlin.types.KotlinType; import org.jetbrains.kotlin.types.checker.KotlinTypeChecker; +import org.jetbrains.kotlin.utils.StringsKt; import org.jetbrains.org.objectweb.asm.FieldVisitor; import org.jetbrains.org.objectweb.asm.Label; import org.jetbrains.org.objectweb.asm.MethodVisitor; @@ -1302,13 +1304,21 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { private void generateTraitMethods() { if (isAnnotationOrJvm6Interface(descriptor, state)) return; + List restrictedInheritance = new ArrayList(); for (Map.Entry entry : CodegenUtil.getNonPrivateTraitMethods(descriptor).entrySet()) { FunctionDescriptor interfaceFun = entry.getKey(); //skip java 8 default methods if (!CodegenUtilKt.isDefinitelyNotDefaultImplsMethod(interfaceFun) && !isJvm8InterfaceMember(interfaceFun, state)) { - generateDelegationToDefaultImpl(interfaceFun, entry.getValue()); + if (state.isJvm8Target() && !JvmCodegenUtil.isJvm8Interface(interfaceFun.getContainingDeclaration(), state)) { + restrictedInheritance.add(interfaceFun); + } + else { + generateDelegationToDefaultImpl(interfaceFun, entry.getValue()); + } } } + + CodegenUtilKt.reportTarget6InheritanceErrorIfNeeded(descriptor, myClass, restrictedInheritance, state); } private void generateDelegationToDefaultImpl(@NotNull final FunctionDescriptor traitFun, @NotNull final FunctionDescriptor inheritedFun) { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/codegenUtil.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/codegenUtil.kt index 8c4427a0bc1..d8fc7aadd3b 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/codegenUtil.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/codegenUtil.kt @@ -26,7 +26,10 @@ import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor +import org.jetbrains.kotlin.diagnostics.rendering.Renderers +import org.jetbrains.kotlin.diagnostics.rendering.RenderingContext import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.SpecialSignatureInfo import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor @@ -36,13 +39,13 @@ import org.jetbrains.kotlin.psi.KtProperty import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin import org.jetbrains.kotlin.serialization.deserialization.PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME import org.jetbrains.kotlin.types.ErrorUtils import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.utils.DFS -import org.jetbrains.org.objectweb.asm.ClassVisitor import org.jetbrains.org.objectweb.asm.Label import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter @@ -213,4 +216,23 @@ fun ClassBuilder.generateMethod( iv.areturn(method.returnType) FunctionCodegen.endVisit(mv, debugString, element) } +} + + +fun reportTarget6InheritanceErrorIfNeeded( + classDescriptor: ClassDescriptor, classElement: KtClassOrObject, restrictedInheritance: List, state:GenerationState +) { + if (!restrictedInheritance.isEmpty()) { + val groupBy = restrictedInheritance.groupBy { descriptor -> descriptor.containingDeclaration as ClassDescriptor } + + for ((key, value) in groupBy) { + state.diagnostics.report( + ErrorsJvm.TARGET6_INTERFACE_INHERITANCE.on( + classElement, classDescriptor, key, + value.map { Renderers.COMPACT.render(JvmCodegenUtil.getDirectMember(it), RenderingContext.Empty) }. + joinToString(separator = "\n", prefix = "\n") + ) + ) + } + } } \ No newline at end of file diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/DefaultErrorMessagesJvm.java b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/DefaultErrorMessagesJvm.java index 8286222f222..76f6ebf8933 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/DefaultErrorMessagesJvm.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/DefaultErrorMessagesJvm.java @@ -106,6 +106,12 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension { MAP.put(ErrorsJvm.STRICTFP_ON_CLASS, "'@Strictfp' annotation on classes is unsupported yet"); MAP.put(ErrorsJvm.SUPER_CALL_WITH_DEFAULT_PARAMETERS, "Super-calls with default arguments are not allowed. Please specify all arguments of ''super.{0}'' explicitly", Renderers.TO_STRING); + + MAP.put(ErrorsJvm.TARGET6_INTERFACE_INHERITANCE, + "Compiling ''{0}'' to JVM 1.8, but its superinterface ''{1}'' was compiled for JVM 1.6. " + + "Method implementation inheritance is restricted for such cases. " + + "Please make explicit overrides (abstract or concrete) for the following non-abstract members of ''{1}’’: {2}", + Renderers.NAME, Renderers.NAME, Renderers.TO_STRING); } @NotNull diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/ErrorsJvm.java b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/ErrorsJvm.java index 282e8571588..b0a34f6334e 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/ErrorsJvm.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/ErrorsJvm.java @@ -17,10 +17,8 @@ package org.jetbrains.kotlin.resolve.jvm.diagnostics; import com.intellij.psi.PsiElement; -import org.jetbrains.kotlin.diagnostics.DiagnosticFactory0; -import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1; -import org.jetbrains.kotlin.diagnostics.DiagnosticFactory2; -import org.jetbrains.kotlin.diagnostics.Errors; +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor; +import org.jetbrains.kotlin.diagnostics.*; import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.psi.KtAnnotationEntry; import org.jetbrains.kotlin.psi.KtDeclaration; @@ -89,6 +87,8 @@ public interface ErrorsJvm { DiagnosticFactory0 WHEN_ENUM_CAN_BE_NULL_IN_JAVA = DiagnosticFactory0.create(WARNING); + DiagnosticFactory3 TARGET6_INTERFACE_INHERITANCE = DiagnosticFactory3.create(ERROR); + @SuppressWarnings("UnusedDeclaration") Object _initializer = new Object() { { diff --git a/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/delegation/delegationToDefaultMethodInClass.kt b/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/delegation/delegationToDefaultMethodInClass.kt index fec660b49cb..f97127e0561 100644 --- a/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/delegation/delegationToDefaultMethodInClass.kt +++ b/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/delegation/delegationToDefaultMethodInClass.kt @@ -1,24 +1,18 @@ -// WITH_REFLECT -// FULL_JDK - // FILE: 1.kt interface Test { - fun test() { + fun test(): String { + return "OK" } } // FILE: 2.kt // JVM_TARGET: 1.8 class TestClass : Test { - + override fun test(): String { + return super.test() + } } fun box(): String { - try { - TestClass::class.java.getDeclaredMethod("test") - } - catch (e: NoSuchMethodException) { - return "fail" - } - return "OK" + return TestClass().test() } diff --git a/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/delegation/delegationToDefaultMethodInInterface.kt b/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/delegation/delegationToDefaultMethodInInterface.kt index 2877b012b1c..de1dba8206b 100644 --- a/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/delegation/delegationToDefaultMethodInInterface.kt +++ b/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/delegation/delegationToDefaultMethodInInterface.kt @@ -1,21 +1,22 @@ // FILE: 1.kt interface Test { - fun test() { + fun test(): String { + return "OK" } } // FILE: 2.kt // JVM_TARGET: 1.8 interface Test2 : Test { + override fun test(): String { + return super.test() + } +} + +class TestClass : Test2 { } fun box(): String { - try { - Test2::class.java.getDeclaredMethod("test") - } - catch (e: NoSuchMethodException) { - return "fail" - } - return "OK" + return TestClass().test() } diff --git a/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/delegation/delegationToDefaultMethodInInterface2.kt b/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/delegation/delegationToDefaultMethodInInterface2.kt index c61b623d1e4..7fb6b0d3c80 100644 --- a/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/delegation/delegationToDefaultMethodInInterface2.kt +++ b/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/delegation/delegationToDefaultMethodInInterface2.kt @@ -1,6 +1,3 @@ -// WITH_REFLECT -// FULL_JDK - // FILE: 1.kt interface Test { fun test(): String { @@ -11,7 +8,9 @@ interface Test { // FILE: 2.kt // JVM_TARGET: 1.8 interface Test2 : Test { - + override fun test(): String { + return super.test() + } } interface Test3 : Test2 { @@ -20,29 +19,5 @@ interface Test3 : Test2 { class TestClass : Test3 fun box(): String { - checkPresent(Test2::class.java, "test") - // TODO: enable this test once the required behavior is specified -// checkNoMethod(Test3::class.java, "test") - return TestClass().test() -} - - - -fun checkNoMethod(clazz: Class<*>, name: String) { - try { - clazz.getDeclaredMethod(name) - } catch (e: NoSuchMethodException) { - return - } - throw java.lang.AssertionError("Method $name exists in $clazz") -} - -fun checkPresent(clazz: Class<*>, name: String) { - try { - clazz.getDeclaredMethod(name) - } catch (e: NoSuchMethodException) { - throw java.lang.AssertionError("Method $name doesn't exist in $clazz") - } - return -} +} \ No newline at end of file diff --git a/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/delegation/diamond.kt b/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/delegation/diamond.kt index fe14b4a46cb..2196db723a3 100644 --- a/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/delegation/diamond.kt +++ b/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/delegation/diamond.kt @@ -1,6 +1,3 @@ -// WITH_REFLECT -// FULL_JDK - // FILE: 1.kt interface Test { fun test(): String { @@ -11,16 +8,20 @@ interface Test { // FILE: 2.kt // JVM_TARGET: 1.8 interface Test2 : Test { - + override fun test(): String { + return super.test() + } } interface Test3 : Test { - + override fun test(): String } interface Test4 : Test2, Test3 { - + override fun test(): String { + return super.test() + } } class TestClass : Test4 { @@ -29,29 +30,5 @@ class TestClass : Test4 { fun box(): String { - checkPresent(Test2::class.java, "test") - checkPresent(Test3::class.java, "test") - // TODO: enable this test once the required behavior is specified - //checkNoMethod(Test4::class.java, "test") - return TestClass().test() } - - -fun checkNoMethod(clazz: Class<*>, name: String) { - try { - clazz.getDeclaredMethod(name) - } catch (e: NoSuchMethodException) { - return - } - throw java.lang.AssertionError("Method $name exists in $clazz") -} - -fun checkPresent(clazz: Class<*>, name: String) { - try { - clazz.getDeclaredMethod(name) - } catch (e: NoSuchMethodException) { - throw java.lang.AssertionError("Method $name doesn't exist in $clazz") - } - return -} diff --git a/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/delegation/diamond2.kt b/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/delegation/diamond2.kt index 88369d0c923..becdbfbd562 100644 --- a/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/delegation/diamond2.kt +++ b/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/delegation/diamond2.kt @@ -1,6 +1,3 @@ -// WITH_REFLECT -// FULL_JDK - // FILE: 1.kt interface Test { fun test(): String { @@ -11,40 +8,22 @@ interface Test { // FILE: 2.kt // JVM_TARGET: 1.8 open class TestClass : Test { - + override fun test(): String { + return super.test() + } } interface Test2 : Test { - + override fun test(): String } class TestClass2 : TestClass(), Test2 { - + override fun test(): String { + return super.test() + } } fun box(): String { - checkPresent(TestClass::class.java, "test") - checkPresent(Test2::class.java, "test") - checkNoMethod(TestClass2::class.java, "test") - return TestClass().test() -} - -fun checkNoMethod(clazz: Class<*>, name: String) { - try { - clazz.getDeclaredMethod(name) - } catch (e: NoSuchMethodException) { - return - } - throw java.lang.AssertionError("Method $name exists in $clazz") -} - -fun checkPresent(clazz: Class<*>, name: String) { - try { - clazz.getDeclaredMethod(name) - } catch (e: NoSuchMethodException) { - throw java.lang.AssertionError("Method $name doesn't exist in $clazz") - } - return -} +} \ No newline at end of file diff --git a/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/delegation/diamond3.kt b/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/delegation/diamond3.kt index be4b052e35b..a4c4705b07e 100644 --- a/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/delegation/diamond3.kt +++ b/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/delegation/diamond3.kt @@ -1,6 +1,3 @@ -// WITH_REFLECT -// FULL_JDK - // FILE: 1.kt interface Test { fun test(): String { @@ -10,8 +7,8 @@ interface Test { // FILE: 2.kt // JVM_TARGET: 1.8 -open class TestClass : Test { - +abstract class TestClass : Test { + abstract override fun test(): String } interface Test2 : Test { @@ -22,31 +19,11 @@ interface Test2 : Test { class TestClass2 : TestClass(), Test2 { - + override fun test(): String { + return super.test() + } } fun box(): String { - checkPresent(TestClass::class.java, "test") - checkPresent(Test2::class.java, "test") - checkPresent(TestClass2::class.java, "test") - return TestClass2().test() } - -fun checkNoMethod(clazz: Class<*>, name: String) { - try { - clazz.getDeclaredMethod(name) - } catch (e: NoSuchMethodException) { - return - } - throw java.lang.AssertionError("Method $name exists in $clazz") -} - -fun checkPresent(clazz: Class<*>, name: String) { - try { - clazz.getDeclaredMethod(name) - } catch (e: NoSuchMethodException) { - throw java.lang.AssertionError("Method $name doesn't exist in $clazz") - } - return -} diff --git a/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/simpleCall.kt b/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/simpleCall.kt index b34afdc269c..eceedef8df0 100644 --- a/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/simpleCall.kt +++ b/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/simpleCall.kt @@ -9,7 +9,9 @@ interface Test { // FILE: 2.kt // JVM_TARGET: 1.8 class TestClass : Test { - + override fun test(): String { + return super.test() + } } fun box(): String { diff --git a/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/simpleCallWithHierarchy.kt b/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/simpleCallWithHierarchy.kt index 85d5c83c5c1..08bb16c4aba 100644 --- a/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/simpleCallWithHierarchy.kt +++ b/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/simpleCallWithHierarchy.kt @@ -9,7 +9,9 @@ interface Test { // FILE: 2.kt // JVM_TARGET: 1.8 interface Test2 : Test { - + override fun test(): String { + return super.test() + } } diff --git a/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/simpleProp.kt b/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/simpleProp.kt new file mode 100644 index 00000000000..ce7cdd97a93 --- /dev/null +++ b/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/simpleProp.kt @@ -0,0 +1,17 @@ +// FILE: 1.kt + +interface Test { + val test: String + get() = "OK" +} + +// FILE: 2.kt +// JVM_TARGET: 1.8 +class TestClass : Test { + override val test: String + get() = super.test +} + +fun box(): String { + return TestClass().test +} diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/target6Inheritance/main.kt b/compiler/testData/compileKotlinAgainstCustomBinaries/target6Inheritance/main.kt new file mode 100644 index 00000000000..26fd28a41ed --- /dev/null +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/target6Inheritance/main.kt @@ -0,0 +1,13 @@ +interface Z2 : Z { + +} + +class Z2Class : Z { + override fun test() { + + } +} + +fun main(args: Array) { + +} diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/target6Inheritance/output.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/target6Inheritance/output.txt new file mode 100644 index 00000000000..2d559532336 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/target6Inheritance/output.txt @@ -0,0 +1,10 @@ +compiler/testData/compileKotlinAgainstCustomBinaries/target6Inheritance/main.kt:1:1: error: compiling 'Z2' to JVM 1.8, but its superinterface 'Z' was compiled for JVM 1.6. Method implementation inheritance is restricted for such cases. Please make explicit overrides (abstract or concrete) for the following non-abstract members of 'Z’’: +val z: String +fun test(): Unit +interface Z2 : Z { +^ +compiler/testData/compileKotlinAgainstCustomBinaries/target6Inheritance/main.kt:5:1: error: compiling 'Z2Class' to JVM 1.8, but its superinterface 'Z' was compiled for JVM 1.6. Method implementation inheritance is restricted for such cases. Please make explicit overrides (abstract or concrete) for the following non-abstract members of 'Z’’: +val z: String +class Z2Class : Z { +^ +COMPILATION_ERROR \ No newline at end of file diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/target6Inheritance/target6.kt b/compiler/testData/compileKotlinAgainstCustomBinaries/target6Inheritance/target6.kt new file mode 100644 index 00000000000..99accaebed7 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/target6Inheritance/target6.kt @@ -0,0 +1,9 @@ +interface Z { + + fun test() { + + } + + val z: String + get() = "OK" +} \ No newline at end of file diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/target6MultiInheritance/main.kt b/compiler/testData/compileKotlinAgainstCustomBinaries/target6MultiInheritance/main.kt new file mode 100644 index 00000000000..a7a366f9219 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/target6MultiInheritance/main.kt @@ -0,0 +1,14 @@ +interface Z3 : Z, Z2 { + +} + +class Z3Class : Z, Z2 { + override fun test() { + + } +} + + +fun main(args: Array) { + +} diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/target6MultiInheritance/output.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/target6MultiInheritance/output.txt new file mode 100644 index 00000000000..9a43127ecdd --- /dev/null +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/target6MultiInheritance/output.txt @@ -0,0 +1,13 @@ +compiler/testData/compileKotlinAgainstCustomBinaries/target6MultiInheritance/main.kt:1:1: error: compiling 'Z3' to JVM 1.8, but its superinterface 'Z' was compiled for JVM 1.6. Method implementation inheritance is restricted for such cases. Please make explicit overrides (abstract or concrete) for the following non-abstract members of 'Z’’: +fun test(): Unit +interface Z3 : Z, Z2 { +^ +compiler/testData/compileKotlinAgainstCustomBinaries/target6MultiInheritance/main.kt:1:1: error: compiling 'Z3' to JVM 1.8, but its superinterface 'Z2' was compiled for JVM 1.6. Method implementation inheritance is restricted for such cases. Please make explicit overrides (abstract or concrete) for the following non-abstract members of 'Z2’’: +val z: String +interface Z3 : Z, Z2 { +^ +compiler/testData/compileKotlinAgainstCustomBinaries/target6MultiInheritance/main.kt:5:1: error: compiling 'Z3Class' to JVM 1.8, but its superinterface 'Z2' was compiled for JVM 1.6. Method implementation inheritance is restricted for such cases. Please make explicit overrides (abstract or concrete) for the following non-abstract members of 'Z2’’: +val z: String +class Z3Class : Z, Z2 { +^ +COMPILATION_ERROR \ No newline at end of file diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/target6MultiInheritance/target6.kt b/compiler/testData/compileKotlinAgainstCustomBinaries/target6MultiInheritance/target6.kt new file mode 100644 index 00000000000..1b8eee9b4da --- /dev/null +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/target6MultiInheritance/target6.kt @@ -0,0 +1,13 @@ +interface Z { + + fun test() { + + } + +} + +interface Z2 { + + val z: String + get() = "OK" +} \ No newline at end of file diff --git a/compiler/tests-java8/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstKotlinTestGenerated.java b/compiler/tests-java8/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstKotlinTestGenerated.java index b4ccaea711c..c3880f613a8 100644 --- a/compiler/tests-java8/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstKotlinTestGenerated.java +++ b/compiler/tests-java8/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstKotlinTestGenerated.java @@ -70,6 +70,12 @@ public class CompileKotlinAgainstKotlinTestGenerated extends AbstractCompileKotl doTest(fileName); } + @TestMetadata("simpleProp.kt") + public void testSimpleProp() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/simpleProp.kt"); + doTest(fileName); + } + @TestMetadata("compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8against6/delegation") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.java b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.java index 4e5a1774330..dc3db0287ed 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.java +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.java @@ -183,10 +183,19 @@ public class CompileKotlinAgainstCustomBinariesTest extends TestCaseWithTmpdir { return library; } + private Pair compileKotlin( + @NotNull String fileName, + @NotNull File output, + @NotNull File... classpath + ) { + return compileKotlin(fileName, output, false, classpath); + } + @NotNull private Pair compileKotlin( @NotNull String fileName, @NotNull File output, + boolean jvm8Target, @NotNull File... classpath ) { List args = new ArrayList(); @@ -199,6 +208,10 @@ public class CompileKotlinAgainstCustomBinariesTest extends TestCaseWithTmpdir { } args.add("-d"); args.add(output.getPath()); + if (jvm8Target) { + args.add("-jvm-target"); + args.add("1.8"); + } return AbstractCliTest.executeCompilerGrabOutput(new K2JVMCompiler(), args); } @@ -402,4 +415,24 @@ public class CompileKotlinAgainstCustomBinariesTest extends TestCaseWithTmpdir { new File(getTestDataDirectory(), "output.txt"), normalizeOutput(outputMain) ); } + + public void testTarget6Inheritance() throws Exception { + target6Inheritance(); + } + + public void testTarget6MultiInheritance() throws Exception { + target6Inheritance(); + } + + private void target6Inheritance() { + compileKotlin("target6.kt", tmpdir); + + compileKotlin("main.kt", tmpdir, true, tmpdir); + + Pair outputMain = compileKotlin("main.kt", tmpdir, true, tmpdir); + + KotlinTestUtils.assertEqualsToFile( + new File(getTestDataDirectory(), "output.txt"), normalizeOutput(outputMain) + ); + } }