diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java index 169fb7cbce2..54accf962a3 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java @@ -719,8 +719,14 @@ public class FunctionCodegen { @NotNull JvmDefaultMode jvmDefaultMode ) { return OwnerKind.DEFAULT_IMPLS == context.getContextKind() && - jvmDefaultMode.isCompatibility() && - JvmAnnotationUtilKt.checkIsImplementationCompiledToJvmDefault(functionDescriptor, jvmDefaultMode); + isCompiledInCompatibilityMode(jvmDefaultMode, functionDescriptor) && + JvmAnnotationUtilKt.checkIsImplementationCompiledToJvmDefault(functionDescriptor, jvmDefaultMode); + } + + private static boolean isCompiledInCompatibilityMode(JvmDefaultMode mode, CallableMemberDescriptor descriptor) { + return mode.isCompatibility() || + (mode == JvmDefaultMode.ALL_INCOMPATIBLE && + JvmAnnotationUtilKt.hasJvmDefaultWithCompatibilityAnnotation(descriptor.getContainingDeclaration())); } private static void generateLocalVariableTable( @@ -1683,11 +1689,12 @@ public class FunctionCodegen { // Fake overrides in interfaces should be expanded to implementation to make proper default check if (JvmAnnotationUtilKt.checkIsImplementationCompiledToJvmDefault(memberDescriptor, mode)) { - boolean isSyntheticInCompatibilityOrJvmDefault = isSynthetic && (mode.isCompatibility() || mode == JvmDefaultMode.ENABLE); + boolean isCompatibilityMode = isCompiledInCompatibilityMode(mode, memberDescriptor); + boolean isSyntheticInCompatibilityOrJvmDefault = isSynthetic && (isCompatibilityMode || mode == JvmDefaultMode.ENABLE); return (kind != OwnerKind.DEFAULT_IMPLS && !isSyntheticInCompatibilityOrJvmDefault) || (kind == OwnerKind.DEFAULT_IMPLS && (isSyntheticInCompatibilityOrJvmDefault || - (mode.isCompatibility() && !JvmAnnotationUtilKt.hasJvmDefaultNoCompatibilityAnnotation(containingDeclaration))) && !DescriptorVisibilities.isPrivate(memberDescriptor.getVisibility())); + (isCompatibilityMode && !JvmAnnotationUtilKt.hasJvmDefaultNoCompatibilityAnnotation(containingDeclaration))) && !DescriptorVisibilities.isPrivate(memberDescriptor.getVisibility())); } else { switch (kind) { case DEFAULT_IMPLS: return true; diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index bec43f4c0d9..91cd48ef7bb 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -25803,11 +25803,29 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/defaultArgs.kt"); } + @Test + @TestMetadata("differentCases.kt") + public void testDifferentCases() throws Exception { + runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/differentCases.kt"); + } + + @Test + @TestMetadata("propertyAnnotation.kt") + public void testPropertyAnnotation() throws Exception { + runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/propertyAnnotation.kt"); + } + @Test @TestMetadata("simple.kt") public void testSimple() throws Exception { runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/simple.kt"); } + + @Test + @TestMetadata("suspend.kt") + public void testSuspend() throws Exception { + runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/suspend.kt"); + } } } diff --git a/compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/defaultArgs.kt b/compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/defaultArgs.kt index be440c80e13..f6621b7c8c9 100644 --- a/compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/defaultArgs.kt +++ b/compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/defaultArgs.kt @@ -1,9 +1,7 @@ // !JVM_DEFAULT_MODE: all // TARGET_BACKEND: JVM -// IGNORE_BACKEND: JVM // JVM_TARGET: 1.8 // WITH_RUNTIME -// FULL_JDK // CHECK_BYTECODE_LISTING @JvmDefaultWithCompatibility diff --git a/compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/differentCases.kt b/compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/differentCases.kt new file mode 100644 index 00000000000..61378652318 --- /dev/null +++ b/compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/differentCases.kt @@ -0,0 +1,26 @@ +// !JVM_DEFAULT_MODE: all +// TARGET_BACKEND: JVM +// JVM_TARGET: 1.8 +// WITH_RUNTIME +// CHECK_BYTECODE_LISTING + +@JvmDefaultWithCompatibility +interface Test { + fun test(): String = privateFun() + + private fun privateFun() = "O" + + val prop: String + get() = "K" + + var varProp: String + get() = "K" + set(value) {} +} + +class TestClass : Test + +fun box(): String { + val testClass = TestClass() + return testClass.test() + testClass.varProp +} diff --git a/compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/differentCases.txt b/compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/differentCases.txt new file mode 100644 index 00000000000..d98f8d34a3a --- /dev/null +++ b/compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/differentCases.txt @@ -0,0 +1,37 @@ +@kotlin.Metadata +public final class DifferentCasesKt { + // source: 'differentCases.kt' + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String +} + +@kotlin.Metadata +public final class Test$DefaultImpls { + // source: 'differentCases.kt' + public deprecated static @java.lang.Deprecated @org.jetbrains.annotations.NotNull method getProp(@org.jetbrains.annotations.NotNull p0: Test): java.lang.String + public deprecated static @java.lang.Deprecated @org.jetbrains.annotations.NotNull method getVarProp(@org.jetbrains.annotations.NotNull p0: Test): java.lang.String + public deprecated static @java.lang.Deprecated method setVarProp(@org.jetbrains.annotations.NotNull p0: Test, @org.jetbrains.annotations.NotNull p1: java.lang.String): void + public deprecated static @java.lang.Deprecated @org.jetbrains.annotations.NotNull method test(@org.jetbrains.annotations.NotNull p0: Test): java.lang.String + public final inner class Test$DefaultImpls +} + +@kotlin.jvm.JvmDefaultWithCompatibility +@kotlin.Metadata +public interface Test { + // source: 'differentCases.kt' + public synthetic static method access$getProp$jd(p0: Test): java.lang.String + public synthetic static method access$getVarProp$jd(p0: Test): java.lang.String + public synthetic static method access$setVarProp$jd(p0: Test, p1: java.lang.String): void + public synthetic static method access$test$jd(p0: Test): java.lang.String + public @org.jetbrains.annotations.NotNull method getProp(): java.lang.String + public @org.jetbrains.annotations.NotNull method getVarProp(): java.lang.String + private method privateFun(): java.lang.String + public method setVarProp(@org.jetbrains.annotations.NotNull p0: java.lang.String): void + public @org.jetbrains.annotations.NotNull method test(): java.lang.String + public final inner class Test$DefaultImpls +} + +@kotlin.Metadata +public final class TestClass { + // source: 'differentCases.kt' + public method (): void +} diff --git a/compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/propertyAnnotation.kt b/compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/propertyAnnotation.kt new file mode 100644 index 00000000000..3eb4d0814b9 --- /dev/null +++ b/compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/propertyAnnotation.kt @@ -0,0 +1,21 @@ +// !JVM_DEFAULT_MODE: all +// TARGET_BACKEND: JVM +// JVM_TARGET: 1.8 +// WITH_RUNTIME +// CHECK_BYTECODE_LISTING + +annotation class MyAnn + +@JvmDefaultWithCompatibility +interface Test { + @MyAnn + val prop: String + get() = "OK" +} + +class TestClass : Test + +fun box(): String { + val testClass = TestClass() + return testClass.prop +} diff --git a/compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/propertyAnnotation.txt b/compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/propertyAnnotation.txt new file mode 100644 index 00000000000..2c2ddd69842 --- /dev/null +++ b/compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/propertyAnnotation.txt @@ -0,0 +1,34 @@ +@java.lang.annotation.Retention(value=RUNTIME) +@kotlin.Metadata +public annotation class MyAnn { + // source: 'propertyAnnotation.kt' +} + +@kotlin.Metadata +public final class PropertyAnnotationKt { + // source: 'propertyAnnotation.kt' + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String +} + +@kotlin.Metadata +public final class Test$DefaultImpls { + // source: 'propertyAnnotation.kt' + public synthetic deprecated static @MyAnn method getProp$annotations(): void + public deprecated static @java.lang.Deprecated @org.jetbrains.annotations.NotNull method getProp(@org.jetbrains.annotations.NotNull p0: Test): java.lang.String + public final inner class Test$DefaultImpls +} + +@kotlin.jvm.JvmDefaultWithCompatibility +@kotlin.Metadata +public interface Test { + // source: 'propertyAnnotation.kt' + public synthetic static method access$getProp$jd(p0: Test): java.lang.String + public @org.jetbrains.annotations.NotNull method getProp(): java.lang.String + public final inner class Test$DefaultImpls +} + +@kotlin.Metadata +public final class TestClass { + // source: 'propertyAnnotation.kt' + public method (): void +} diff --git a/compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/simple.kt b/compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/simple.kt index 092399e3c0c..57e7eb18311 100644 --- a/compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/simple.kt +++ b/compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/simple.kt @@ -1,7 +1,6 @@ // !JVM_DEFAULT_MODE: all // TARGET_BACKEND: JVM // JVM_TARGET: 1.8 -// IGNORE_BACKEND: JVM // WITH_RUNTIME // FILE: Simple.java diff --git a/compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/suspend.kt b/compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/suspend.kt new file mode 100644 index 00000000000..8ab64481993 --- /dev/null +++ b/compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/suspend.kt @@ -0,0 +1,33 @@ +// !JVM_DEFAULT_MODE: all +// TARGET_BACKEND: JVM +// IGNORE_BACKEND: JVM +// JVM_TARGET: 1.8 +// CHECK_BYTECODE_LISTING +// WITH_COROUTINES +// WITH_STDLIB +import helpers.* +import kotlin.coroutines.* + +@JvmDefaultWithCompatibility +interface Test { + + suspend fun suspendFun() = privateSuspendFun() + + private suspend fun privateSuspendFun() = "OK" + +} + +class TestClass : Test + +fun builder(c: suspend () -> Unit) { + c.startCoroutine(EmptyContinuation) +} + +fun box(): String { + var result = "FAIL" + builder { + val testClass = TestClass() + result = testClass.suspendFun() + } + return result +} diff --git a/compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/suspend.txt b/compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/suspend.txt new file mode 100644 index 00000000000..f0de6d546ff --- /dev/null +++ b/compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/suspend.txt @@ -0,0 +1,48 @@ +@kotlin.coroutines.jvm.internal.DebugMetadata +@kotlin.Metadata +final class SuspendKt$box$1 { + // source: 'suspend.kt' + enclosing method SuspendKt.box()Ljava/lang/String; + synthetic final field $result: kotlin.jvm.internal.Ref$ObjectRef + field L$0: java.lang.Object + field label: int + inner (anonymous) class SuspendKt$box$1 + method (p0: kotlin.jvm.internal.Ref$ObjectRef, p1: kotlin.coroutines.Continuation): void + public final @org.jetbrains.annotations.NotNull method create(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): kotlin.coroutines.Continuation + public final @org.jetbrains.annotations.Nullable method invoke(@org.jetbrains.annotations.Nullable p0: kotlin.coroutines.Continuation): java.lang.Object + public synthetic bridge method invoke(p0: java.lang.Object): java.lang.Object + public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object +} + +@kotlin.Metadata +public final class SuspendKt { + // source: 'suspend.kt' + inner (anonymous) class SuspendKt$box$1 + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String + public final static method builder(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): void +} + +@kotlin.Metadata +public final class Test$DefaultImpls { + // source: 'suspend.kt' + public deprecated static @java.lang.Deprecated @org.jetbrains.annotations.Nullable method suspendFun(@org.jetbrains.annotations.NotNull p0: Test, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object + public final inner class Test$DefaultImpls +} + +@kotlin.jvm.JvmDefaultWithCompatibility +@kotlin.Metadata +public interface Test { + // source: 'suspend.kt' + public synthetic static method access$privateSuspendFun(p0: Test, p1: kotlin.coroutines.Continuation): java.lang.Object + public synthetic static method access$suspendFun$jd(p0: Test, p1: kotlin.coroutines.Continuation): java.lang.Object + private method privateSuspendFun(p0: kotlin.coroutines.Continuation): java.lang.Object + public synthetic static method suspendFun$suspendImpl(p0: Test, p1: kotlin.coroutines.Continuation): java.lang.Object + public @org.jetbrains.annotations.Nullable method suspendFun(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): java.lang.Object + public final inner class Test$DefaultImpls +} + +@kotlin.Metadata +public final class TestClass { + // source: 'suspend.kt' + public method (): void +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index 0089a9e3d4e..76904e42aa0 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -25425,11 +25425,29 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/defaultArgs.kt"); } + @Test + @TestMetadata("differentCases.kt") + public void testDifferentCases() throws Exception { + runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/differentCases.kt"); + } + + @Test + @TestMetadata("propertyAnnotation.kt") + public void testPropertyAnnotation() throws Exception { + runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/propertyAnnotation.kt"); + } + @Test @TestMetadata("simple.kt") public void testSimple() throws Exception { runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/simple.kt"); } + + @Test + @TestMetadata("suspend.kt") + public void testSuspend() throws Exception { + runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/suspend.kt"); + } } } diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index b9c6aaefe4c..efe5f34c284 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -25803,11 +25803,29 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/defaultArgs.kt"); } + @Test + @TestMetadata("differentCases.kt") + public void testDifferentCases() throws Exception { + runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/differentCases.kt"); + } + + @Test + @TestMetadata("propertyAnnotation.kt") + public void testPropertyAnnotation() throws Exception { + runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/propertyAnnotation.kt"); + } + @Test @TestMetadata("simple.kt") public void testSimple() throws Exception { runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/simple.kt"); } + + @Test + @TestMetadata("suspend.kt") + public void testSuspend() throws Exception { + runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/suspend.kt"); + } } } diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index f9b1f4c2bbb..f03d4cfc757 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -21438,14 +21438,9 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) public static class WithCompatibility extends AbstractLightAnalysisModeTest { - @TestMetadata("defaultArgs.kt") - public void ignoreDefaultArgs() throws Exception { - runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/defaultArgs.kt"); - } - - @TestMetadata("simple.kt") - public void ignoreSimple() throws Exception { - runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/simple.kt"); + @TestMetadata("suspend.kt") + public void ignoreSuspend() throws Exception { + runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/suspend.kt"); } private void runTest(String testDataFilePath) throws Exception { @@ -21455,6 +21450,26 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes public void testAllFilesPresentInWithCompatibility() throws Exception { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); } + + @TestMetadata("defaultArgs.kt") + public void testDefaultArgs() throws Exception { + runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/defaultArgs.kt"); + } + + @TestMetadata("differentCases.kt") + public void testDifferentCases() throws Exception { + runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/differentCases.kt"); + } + + @TestMetadata("propertyAnnotation.kt") + public void testPropertyAnnotation() throws Exception { + runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/propertyAnnotation.kt"); + } + + @TestMetadata("simple.kt") + public void testSimple() throws Exception { + runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/withCompatibility/simple.kt"); + } } }