diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java index b3b66e3128d..0040217e165 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java @@ -181,7 +181,7 @@ public class FunctionCodegen { OwnerKind contextKind = methodContext.getContextKind(); DeclarationDescriptor containingDeclaration = functionDescriptor.getContainingDeclaration(); if (isInterface(containingDeclaration) && - !processInterfaceMethod(functionDescriptor, contextKind, false, state.getJvmDefaultMode())) { + !processInterfaceMethod(functionDescriptor, contextKind, false, false, state.getJvmDefaultMode())) { return; } @@ -1149,7 +1149,7 @@ public class FunctionCodegen { DeclarationDescriptor contextClass = owner.getContextDescriptor().getContainingDeclaration(); if (isInterface(contextClass) && - !processInterfaceMethod(functionDescriptor, kind, true, state.getJvmDefaultMode())) { + !processInterfaceMethod(functionDescriptor, kind, true, false, state.getJvmDefaultMode())) { return; } @@ -1579,7 +1579,8 @@ public class FunctionCodegen { public static boolean processInterfaceMethod( @NotNull CallableMemberDescriptor memberDescriptor, @NotNull OwnerKind kind, - boolean isDefaultOrSynthetic, + boolean isDefault, + boolean isSynthetic, JvmDefaultMode mode ) { DeclarationDescriptor containingDeclaration = memberDescriptor.getContainingDeclaration(); @@ -1587,11 +1588,12 @@ public class FunctionCodegen { containingDeclaration; if (hasJvmDefaultAnnotation(memberDescriptor)) { - return kind != OwnerKind.DEFAULT_IMPLS || mode.isCompatibility(); + return (kind != OwnerKind.DEFAULT_IMPLS && !isSynthetic) || + (kind == OwnerKind.DEFAULT_IMPLS && (isSynthetic || mode.isCompatibility())); } else { switch (kind) { case DEFAULT_IMPLS: return true; - case IMPLEMENTATION: return !Visibilities.isPrivate(memberDescriptor.getVisibility()) && !isDefaultOrSynthetic; + case IMPLEMENTATION: return !Visibilities.isPrivate(memberDescriptor.getVisibility()) && !isDefault && !isSynthetic; default: return false; } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java index 46d49aa263b..30ae78f00da 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java @@ -353,7 +353,7 @@ public class PropertyCodegen { if (annotations.getAllAnnotations().isEmpty()) return; DeclarationDescriptor contextDescriptor = context.getContextDescriptor(); - if (!isInterface(contextDescriptor) || processInterfaceMethod(descriptor, kind, true, state.getJvmDefaultMode())) { + if (!isInterface(contextDescriptor) || processInterfaceMethod(descriptor, kind, false, true, state.getJvmDefaultMode())) { memberCodegen.generateSyntheticAnnotationsMethod( descriptor, getSyntheticMethodSignature(descriptor), annotations, AnnotationUseSiteTarget.PROPERTY ); diff --git a/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8/defaults/superCallFromInterface2.kt b/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8/defaults/superCallFromInterface2.kt new file mode 100644 index 00000000000..7e95726b42c --- /dev/null +++ b/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8/defaults/superCallFromInterface2.kt @@ -0,0 +1,28 @@ +// !API_VERSION: 1.3 +// !JVM_DEFAULT_MODE: enable +// JVM_TARGET: 1.8 +// WITH_RUNTIME +// FILE: 1.kt +interface Test { + @JvmDefault + fun test(): String { + return "OK" + } + + fun defaultImplTrigger(): String { + return "OK" + } +} + +// FILE: 2.kt + +interface Test2 : Test { + @JvmDefault + override fun test(): String { + return super.test() + } +} + +fun box(): String { + return object : Test2 {}.test() +} diff --git a/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8/defaults/superPropAccessFromInterface2.kt b/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8/defaults/superPropAccessFromInterface2.kt new file mode 100644 index 00000000000..a98d5393429 --- /dev/null +++ b/compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8/defaults/superPropAccessFromInterface2.kt @@ -0,0 +1,24 @@ +// !API_VERSION: 1.3 +// !JVM_DEFAULT_MODE: enable +// JVM_TARGET: 1.8 +// WITH_RUNTIME +// FILE: 1.kt +interface Test { + @JvmDefault + val prop: String + get() = "OK" + + val defaultImplTrigger: String + get() = "OK" +} + +// FILE: 2.kt +interface Test2 : Test { + @JvmDefault + override val prop: String + get() = super.prop +} + +fun box(): String { + return object : Test2 {}.prop +} diff --git a/compiler/testData/codegen/java8/writeFlags/defaults/compatibility/propertyAnnotation.kt b/compiler/testData/codegen/java8/writeFlags/defaults/compatibility/propertyAnnotation.kt new file mode 100644 index 00000000000..1d1f8255883 --- /dev/null +++ b/compiler/testData/codegen/java8/writeFlags/defaults/compatibility/propertyAnnotation.kt @@ -0,0 +1,21 @@ +// !API_VERSION: 1.3 +// !JVM_DEFAULT_MODE: compatibility +// JVM_TARGET: 1.8 +// WITH_RUNTIME + +annotation class Property(val value: String) + +interface Test { + @Property("OK") + @JvmDefault + val test: String + get() = "OK" +} + +// TESTED_OBJECT_KIND: function +// TESTED_OBJECTS: Test, test$annotations +// ABSENT: TRUE + +// TESTED_OBJECT_KIND: function +// TESTED_OBJECTS: Test$DefaultImpls, test$annotations +// FLAGS: ACC_PUBLIC, ACC_STATIC, ACC_SYNTHETIC, ACC_DEPRECATED \ No newline at end of file diff --git a/compiler/testData/codegen/java8/writeFlags/defaults/propertyAnnotation.kt b/compiler/testData/codegen/java8/writeFlags/defaults/propertyAnnotation.kt new file mode 100644 index 00000000000..51b162afafc --- /dev/null +++ b/compiler/testData/codegen/java8/writeFlags/defaults/propertyAnnotation.kt @@ -0,0 +1,23 @@ +// !API_VERSION: 1.3 +// !JVM_DEFAULT_MODE: enable +// JVM_TARGET: 1.8 +// WITH_RUNTIME + +annotation class Property(val value: String) + +interface Test { + @Property("OK") + @JvmDefault + val test: String + get() = "OK" + + fun stub() {} +} + +// TESTED_OBJECT_KIND: function +// TESTED_OBJECTS: Test, test$annotations +// ABSENT: TRUE + +// TESTED_OBJECT_KIND: function +// TESTED_OBJECTS: Test$DefaultImpls, test$annotations +// FLAGS: ACC_PUBLIC, ACC_STATIC, ACC_SYNTHETIC, ACC_DEPRECATED \ 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 4de304651a0..073b6dbb3c5 100644 --- a/compiler/tests-java8/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstKotlinTestGenerated.java +++ b/compiler/tests-java8/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstKotlinTestGenerated.java @@ -81,6 +81,11 @@ public class CompileKotlinAgainstKotlinTestGenerated extends AbstractCompileKotl runTest("compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8/defaults/superCallFromInterface.kt"); } + @TestMetadata("superCallFromInterface2.kt") + public void testSuperCallFromInterface2() throws Exception { + runTest("compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8/defaults/superCallFromInterface2.kt"); + } + @TestMetadata("superPropAccess.kt") public void testSuperPropAccess() throws Exception { runTest("compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8/defaults/superPropAccess.kt"); @@ -90,6 +95,11 @@ public class CompileKotlinAgainstKotlinTestGenerated extends AbstractCompileKotl public void testSuperPropAccessFromInterface() throws Exception { runTest("compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8/defaults/superPropAccessFromInterface.kt"); } + + @TestMetadata("superPropAccessFromInterface2.kt") + public void testSuperPropAccessFromInterface2() throws Exception { + runTest("compiler/testData/codegen/java8/compileKotlinAgainstKotlin/jvm8/defaults/superPropAccessFromInterface2.kt"); + } } } diff --git a/compiler/tests-java8/tests/org/jetbrains/kotlin/codegen/flags/WriteFlagsTestGenerated.java b/compiler/tests-java8/tests/org/jetbrains/kotlin/codegen/flags/WriteFlagsTestGenerated.java index 9f0b9e69eda..e18cd27b064 100644 --- a/compiler/tests-java8/tests/org/jetbrains/kotlin/codegen/flags/WriteFlagsTestGenerated.java +++ b/compiler/tests-java8/tests/org/jetbrains/kotlin/codegen/flags/WriteFlagsTestGenerated.java @@ -61,6 +61,11 @@ public class WriteFlagsTestGenerated extends AbstractWriteFlagsTest { runTest("compiler/testData/codegen/java8/writeFlags/defaults/defaultProperty.kt"); } + @TestMetadata("propertyAnnotation.kt") + public void testPropertyAnnotation() throws Exception { + runTest("compiler/testData/codegen/java8/writeFlags/defaults/propertyAnnotation.kt"); + } + @TestMetadata("compiler/testData/codegen/java8/writeFlags/defaults/compatibility") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) @@ -77,6 +82,11 @@ public class WriteFlagsTestGenerated extends AbstractWriteFlagsTest { public void testPropertyAccessors() throws Exception { runTest("compiler/testData/codegen/java8/writeFlags/defaults/compatibility/propertyAccessors.kt"); } + + @TestMetadata("propertyAnnotation.kt") + public void testPropertyAnnotation() throws Exception { + runTest("compiler/testData/codegen/java8/writeFlags/defaults/compatibility/propertyAnnotation.kt"); + } } } }