jvm-abi-gen: always keep annotation classes

This commit is contained in:
Steven Schäfer
2021-02-09 10:51:57 +01:00
committed by Alexander Udalov
parent c9b0cc5b32
commit c156613141
6 changed files with 104 additions and 1 deletions
@@ -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<out String>) {
// 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<out String>?): 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) {
@@ -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/");
@@ -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/");
@@ -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/");
@@ -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
@@ -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 <init>(): void
}
@test.B3(x=2)
@kotlin.Metadata
@test.B2(x=1)
public final class test/T2 {
// source: 'annotations.kt'
public method <init>(): void
}