diff --git a/plugins/jvm-abi-gen/src/org/jetbrains/kotlin/jvm/abi/JvmAbiClassBuilderInterceptor.kt b/plugins/jvm-abi-gen/src/org/jetbrains/kotlin/jvm/abi/JvmAbiClassBuilderInterceptor.kt index 12f719f231b..176168c7c8e 100644 --- a/plugins/jvm-abi-gen/src/org/jetbrains/kotlin/jvm/abi/JvmAbiClassBuilderInterceptor.kt +++ b/plugins/jvm-abi-gen/src/org/jetbrains/kotlin/jvm/abi/JvmAbiClassBuilderInterceptor.kt @@ -79,6 +79,11 @@ class JvmAbiClassBuilderInterceptor : ClassBuilderInterceptorExtension { override fun getDelegate(): ClassBuilder = delegate override fun defineClass(origin: PsiElement?, version: Int, access: Int, name: String, signature: String?, superName: String, interfaces: Array) { + // Always keep annotation classes + if (access and Opcodes.ACC_ANNOTATION != 0) { + publicAbi = true + } + internalName = name super.defineClass(origin, version, access, name, signature, superName, interfaces) } @@ -89,6 +94,10 @@ class JvmAbiClassBuilderInterceptor : ClassBuilderInterceptorExtension { } override fun newMethod(origin: JvmDeclarationOrigin, access: Int, name: String, desc: String, signature: String?, exceptions: Array?): MethodVisitor { + if (publicAbi) { + return super.newMethod(origin, access, name, desc, signature, exceptions) + } + // inline suspend functions are a special case: Unless they use reified type parameters, // we will transform the original method and generate a $$forInline method for the inliner. // Only the latter needs to be kept, the former can be stripped. Unfortunately, there is no @@ -121,7 +130,7 @@ class JvmAbiClassBuilderInterceptor : ClassBuilderInterceptorExtension { // Parse the public ABI flag from the Kotlin metadata annotation override fun newAnnotation(desc: String, visible: Boolean): AnnotationVisitor { val delegate = super.newAnnotation(desc, visible) - if (desc != JvmAnnotationNames.METADATA_DESC) + if (publicAbi || desc != JvmAnnotationNames.METADATA_DESC) return delegate return object : AnnotationVisitor(Opcodes.API_VERSION, delegate) { diff --git a/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/IrJvmAbiContentTestGenerated.java b/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/IrJvmAbiContentTestGenerated.java index 556368ab15a..be4cade3dc3 100644 --- a/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/IrJvmAbiContentTestGenerated.java +++ b/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/IrJvmAbiContentTestGenerated.java @@ -30,6 +30,11 @@ public class IrJvmAbiContentTestGenerated extends AbstractIrJvmAbiContentTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/jvm-abi-gen/testData/content"), Pattern.compile("^([^\\.]+)$"), null, TargetBackend.JVM_IR, false); } + @TestMetadata("annotation") + public void testAnnotation() throws Exception { + runTest("plugins/jvm-abi-gen/testData/content/annotation/"); + } + @TestMetadata("class") public void testClass() throws Exception { runTest("plugins/jvm-abi-gen/testData/content/class/"); diff --git a/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/JvmAbiContentTestGenerated.java b/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/JvmAbiContentTestGenerated.java index f2fa70a5799..df6e09403a0 100644 --- a/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/JvmAbiContentTestGenerated.java +++ b/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/JvmAbiContentTestGenerated.java @@ -30,6 +30,11 @@ public class JvmAbiContentTestGenerated extends AbstractJvmAbiContentTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/jvm-abi-gen/testData/content"), Pattern.compile("^([^\\.]+)$"), null, TargetBackend.JVM, false); } + @TestMetadata("annotation") + public void testAnnotation() throws Exception { + runTest("plugins/jvm-abi-gen/testData/content/annotation/"); + } + @TestMetadata("class") public void testClass() throws Exception { runTest("plugins/jvm-abi-gen/testData/content/class/"); diff --git a/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/LegacyJvmAbiContentTestGenerated.java b/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/LegacyJvmAbiContentTestGenerated.java index c044efed66b..3749be04ccd 100644 --- a/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/LegacyJvmAbiContentTestGenerated.java +++ b/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/LegacyJvmAbiContentTestGenerated.java @@ -30,6 +30,11 @@ public class LegacyJvmAbiContentTestGenerated extends AbstractLegacyJvmAbiConten KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/jvm-abi-gen/testData/content"), Pattern.compile("^([^\\.]+)$"), null, TargetBackend.JVM, false); } + @TestMetadata("annotation") + public void testAnnotation() throws Exception { + runTest("plugins/jvm-abi-gen/testData/content/annotation/"); + } + @TestMetadata("class") public void testClass() throws Exception { runTest("plugins/jvm-abi-gen/testData/content/class/"); diff --git a/plugins/jvm-abi-gen/testData/content/annotation/annotations.kt b/plugins/jvm-abi-gen/testData/content/annotation/annotations.kt new file mode 100644 index 00000000000..7ae3ad8540d --- /dev/null +++ b/plugins/jvm-abi-gen/testData/content/annotation/annotations.kt @@ -0,0 +1,23 @@ +package test + +@Retention(AnnotationRetention.SOURCE) +private annotation class A1(val x: Int) + +@Retention(AnnotationRetention.BINARY) +private annotation class A2(val x: Int) + +@Retention(AnnotationRetention.RUNTIME) +private annotation class A3(val x: Int) + +@Retention(AnnotationRetention.SOURCE) +annotation class B1(val x: Int) + +@Retention(AnnotationRetention.BINARY) +annotation class B2(val x: Int) + +@Retention(AnnotationRetention.RUNTIME) +annotation class B3(val x: Int) + +@A1(0) @A2(1) @A3(2) class T1 + +@B1(0) @B2(1) @B3(2) class T2 diff --git a/plugins/jvm-abi-gen/testData/content/annotation/signatures.txt b/plugins/jvm-abi-gen/testData/content/annotation/signatures.txt new file mode 100644 index 00000000000..e320b12b737 --- /dev/null +++ b/plugins/jvm-abi-gen/testData/content/annotation/signatures.txt @@ -0,0 +1,56 @@ +@kotlin.annotation.Retention(value=SOURCE) +@java.lang.annotation.Retention(value=SOURCE) +@kotlin.Metadata +annotation class test/A1 { + // source: 'annotations.kt' + public abstract method x(): int +} +@kotlin.annotation.Retention(value=BINARY) +@java.lang.annotation.Retention(value=CLASS) +@kotlin.Metadata +annotation class test/A2 { + // source: 'annotations.kt' + public abstract method x(): int +} +@kotlin.annotation.Retention(value=RUNTIME) +@java.lang.annotation.Retention(value=RUNTIME) +@kotlin.Metadata +annotation class test/A3 { + // source: 'annotations.kt' + public abstract method x(): int +} +@kotlin.annotation.Retention(value=SOURCE) +@java.lang.annotation.Retention(value=SOURCE) +@kotlin.Metadata +public annotation class test/B1 { + // source: 'annotations.kt' + public abstract method x(): int +} +@kotlin.annotation.Retention(value=BINARY) +@java.lang.annotation.Retention(value=CLASS) +@kotlin.Metadata +public annotation class test/B2 { + // source: 'annotations.kt' + public abstract method x(): int +} +@kotlin.annotation.Retention(value=RUNTIME) +@java.lang.annotation.Retention(value=RUNTIME) +@kotlin.Metadata +public annotation class test/B3 { + // source: 'annotations.kt' + public abstract method x(): int +} +@test.A3(x=2) +@kotlin.Metadata +@test.A2(x=1) +public final class test/T1 { + // source: 'annotations.kt' + public method (): void +} +@test.B3(x=2) +@kotlin.Metadata +@test.B2(x=1) +public final class test/T2 { + // source: 'annotations.kt' + public method (): void +} \ No newline at end of file