Add JvmSynthetic annotation
This commit is contained in:
@@ -41,6 +41,7 @@ import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.annotations.AnnotationsPackage;
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage;
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil;
|
||||
@@ -212,7 +213,9 @@ public class AsmUtil {
|
||||
flags |= ACC_ABSTRACT;
|
||||
}
|
||||
|
||||
if (JetTypeMapper.isAccessor(functionDescriptor) || functionDescriptor.getVisibility() == Visibilities.INTERNAL) {
|
||||
if (JetTypeMapper.isAccessor(functionDescriptor)
|
||||
|| functionDescriptor.getVisibility() == Visibilities.INTERNAL
|
||||
|| AnnotationUtilKt.hasJvmSyntheticAnnotation(functionDescriptor)) {
|
||||
flags |= ACC_SYNTHETIC;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.psi.psiUtil.PsiUtilPackage;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorFactory;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||
import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.annotations.AnnotationsPackage;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
||||
@@ -293,6 +294,10 @@ public class PropertyCodegen {
|
||||
modifiers |= ACC_FINAL;
|
||||
}
|
||||
|
||||
if (AnnotationUtilKt.hasJvmSyntheticAnnotation(propertyDescriptor)) {
|
||||
modifiers |= ACC_SYNTHETIC;
|
||||
}
|
||||
|
||||
Type type = typeMapper.mapType(jetType);
|
||||
|
||||
ClassBuilder builder = v;
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.lexer.JetTokens
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -40,6 +41,12 @@ public fun DeclarationDescriptor.findPublicFieldAnnotation(): AnnotationDescript
|
||||
return getAnnotations().findAnnotation(FqName("kotlin.jvm.publicField"))
|
||||
}
|
||||
|
||||
public fun DeclarationDescriptor.hasJvmSyntheticAnnotation(): Boolean {
|
||||
val jvmSyntheticName = FqName("kotlin.jvm.JvmSynthetic")
|
||||
return annotations.findAnnotation(jvmSyntheticName) != null ||
|
||||
Annotations.findUseSiteTargetedAnnotation(annotations, AnnotationUseSiteTarget.FIELD, jvmSyntheticName) != null
|
||||
}
|
||||
|
||||
public fun DeclarationDescriptor.hasIntrinsicAnnotation(): Boolean {
|
||||
return getAnnotations().findAnnotation(FqName("kotlin.jvm.internal.Intrinsic")) != null
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
class Example {
|
||||
@JvmSynthetic
|
||||
val prop: String = "ABC"
|
||||
|
||||
var prop2 = 5
|
||||
@JvmSynthetic public get
|
||||
@JvmSynthetic public set
|
||||
|
||||
@field:JvmSynthetic
|
||||
val useSite = 0
|
||||
|
||||
@get:JvmSynthetic @set:JvmSynthetic
|
||||
var useSite2 = 0
|
||||
|
||||
@JvmSynthetic
|
||||
fun job() {}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
@kotlin.jvm.internal.KotlinClass Example {
|
||||
public synthetic field $kotlinClass: kotlin.reflect.KClass
|
||||
private synthetic @org.jetbrains.annotations.NotNull field prop: java.lang.String
|
||||
private field prop2: int
|
||||
private synthetic field useSite: int
|
||||
private field useSite2: int
|
||||
method <clinit>(): void
|
||||
public @org.jetbrains.annotations.NotNull method getProp(): java.lang.String
|
||||
public synthetic method getProp2(): int
|
||||
public synthetic method setProp2(p0: int): void
|
||||
public method getUseSite(): int
|
||||
public method getUseSite2(): int
|
||||
public method setUseSite2(p0: int): void
|
||||
public synthetic method job(): void
|
||||
public method <init>(): void
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
@kotlin.jvm.internal.KotlinClass A {
|
||||
field $kotlinClass: kotlin.reflect.KClass
|
||||
@AnnField @AnnParameterField @AnnTypeField field a: int
|
||||
@AnnField @AnnTypeField field x: int
|
||||
public synthetic field $kotlinClass: kotlin.reflect.KClass
|
||||
private @AnnField @AnnParameterField @AnnTypeField field a: int
|
||||
private @AnnField @AnnTypeField field x: int
|
||||
method <clinit>(): void
|
||||
@AnnProperty @AnnFieldProperty @AnnParameterProperty method a$annotations(): void
|
||||
method getA(): int
|
||||
@AnnProperty @AnnFieldProperty method x$annotations(): void
|
||||
method getX(): int
|
||||
method <init>(@AnnParameterProperty @AnnParameterField p0: int): void
|
||||
private synthetic deprecated @AnnProperty @AnnFieldProperty @AnnParameterProperty method a$annotations(): void
|
||||
public method getA(): int
|
||||
private synthetic deprecated @AnnProperty @AnnFieldProperty method x$annotations(): void
|
||||
public method getX(): int
|
||||
public method <init>(@AnnParameterProperty @AnnParameterField p0: int): void
|
||||
}
|
||||
|
||||
@kotlin.annotation.Target @java.lang.annotation.Retention @java.lang.annotation.Target @kotlin.jvm.internal.KotlinClass AnnField
|
||||
|
||||
@@ -6,32 +6,32 @@
|
||||
|
||||
@kotlin.jvm.internal.KotlinSyntheticClass @kotlin.jvm.internal.KotlinCallable LiteralsKt$foo$1 {
|
||||
inner class LiteralsKt$foo$1
|
||||
field $arg: int
|
||||
method invoke(): java.lang.Object
|
||||
@FunAnn method invoke(): int
|
||||
synthetic field $arg: int
|
||||
public method invoke(): java.lang.Object
|
||||
public @FunAnn method invoke(): int
|
||||
method <init>(p0: int): void
|
||||
}
|
||||
|
||||
@kotlin.jvm.internal.KotlinSyntheticClass @kotlin.jvm.internal.KotlinCallable LiteralsKt$foo$2 {
|
||||
inner class LiteralsKt$foo$2
|
||||
field $arg: int
|
||||
method invoke(): java.lang.Object
|
||||
method invoke(): int
|
||||
synthetic field $arg: int
|
||||
public method invoke(): java.lang.Object
|
||||
public method invoke(): int
|
||||
method <init>(p0: int): void
|
||||
}
|
||||
|
||||
@kotlin.jvm.internal.KotlinLocalClass @kotlin.jvm.internal.KotlinClass LiteralsKt$foo$3 {
|
||||
inner class LiteralsKt$foo$3
|
||||
field $kotlinClass: kotlin.reflect.KClass
|
||||
public synthetic field $kotlinClass: kotlin.reflect.KClass
|
||||
method <clinit>(): void
|
||||
method <init>(): void
|
||||
}
|
||||
|
||||
@kotlin.jvm.internal.KotlinSyntheticClass @kotlin.jvm.internal.KotlinCallable LiteralsKt$foo$x$1 {
|
||||
inner class LiteralsKt$foo$x$1
|
||||
field $arg: int
|
||||
method invoke(): java.lang.Object
|
||||
@FunAnn method invoke(): int
|
||||
synthetic field $arg: int
|
||||
public method invoke(): java.lang.Object
|
||||
public @FunAnn method invoke(): int
|
||||
method <init>(p0: int): void
|
||||
}
|
||||
|
||||
@@ -40,20 +40,20 @@
|
||||
inner class LiteralsKt$foo$2
|
||||
inner class LiteralsKt$foo$x$1
|
||||
inner class LiteralsKt$foo$3
|
||||
method bar(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function0): int
|
||||
@org.jetbrains.annotations.NotNull method foo(p0: int): My
|
||||
public method bar(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function0): int
|
||||
public @org.jetbrains.annotations.NotNull method foo(p0: int): My
|
||||
}
|
||||
|
||||
@kotlin.jvm.internal.KotlinClass My {
|
||||
field $kotlinClass: kotlin.reflect.KClass
|
||||
public synthetic field $kotlinClass: kotlin.reflect.KClass
|
||||
method <clinit>(): void
|
||||
method <init>(): void
|
||||
public method <init>(): void
|
||||
}
|
||||
|
||||
@java.lang.Deprecated @kotlin.jvm.internal.KotlinPackage _DefaultPackage {
|
||||
field $kotlinPackage: kotlin.reflect.KPackage
|
||||
field $moduleName: java.lang.String
|
||||
public synthetic field $kotlinPackage: kotlin.reflect.KPackage
|
||||
public synthetic field $moduleName: java.lang.String
|
||||
method <clinit>(): void
|
||||
@kotlin.jvm.internal.KotlinDelegatedMethod method bar(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function0): int
|
||||
@kotlin.jvm.internal.KotlinDelegatedMethod @org.jetbrains.annotations.NotNull method foo(p0: int): My
|
||||
}
|
||||
public @kotlin.jvm.internal.KotlinDelegatedMethod method bar(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function0): int
|
||||
public @kotlin.jvm.internal.KotlinDelegatedMethod @org.jetbrains.annotations.NotNull method foo(p0: int): My
|
||||
}
|
||||
@@ -1,17 +1,17 @@
|
||||
@kotlin.jvm.internal.KotlinClass A {
|
||||
field $kotlinClass: kotlin.reflect.KClass
|
||||
@AnnField field p: int
|
||||
@AnnField field x: int
|
||||
field y: int
|
||||
public synthetic field $kotlinClass: kotlin.reflect.KClass
|
||||
private @AnnField field p: int
|
||||
private @AnnField field x: int
|
||||
private field y: int
|
||||
method <clinit>(): void
|
||||
@AnnProp @AnnProp2 method p$annotations(): void
|
||||
@AnnGetter method getP(): int
|
||||
@AnnSetter method setP(@AnnParam p0: int): void
|
||||
@AnnProp2 method x$annotations(): void
|
||||
method getX(): int
|
||||
@AnnGetter method getY(): int
|
||||
@AnnSetter method setY(p0: int): void
|
||||
method <init>(@AnnParam p0: int, @AnnParam p1: int): void
|
||||
private synthetic deprecated @AnnProp @AnnProp2 method p$annotations(): void
|
||||
public @AnnGetter method getP(): int
|
||||
public @AnnSetter method setP(@AnnParam p0: int): void
|
||||
private synthetic deprecated @AnnProp2 method x$annotations(): void
|
||||
public method getX(): int
|
||||
public @AnnGetter method getY(): int
|
||||
public @AnnSetter method setY(p0: int): void
|
||||
public method <init>(@AnnParam p0: int, @AnnParam p1: int): void
|
||||
}
|
||||
|
||||
@java.lang.annotation.Retention @kotlin.jvm.internal.KotlinClass AnnField
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
@kotlin.jvm.internal.KotlinClass A {
|
||||
field $kotlinClass: kotlin.reflect.KClass
|
||||
public synthetic field $kotlinClass: kotlin.reflect.KClass
|
||||
method <clinit>(): void
|
||||
@org.jetbrains.annotations.NotNull method f(@Ann p0: java.lang.String): java.lang.String
|
||||
@org.jetbrains.annotations.NotNull method getP(@Ann p0: java.lang.String): java.lang.String
|
||||
method <init>(): void
|
||||
public @org.jetbrains.annotations.NotNull method f(@Ann p0: java.lang.String): java.lang.String
|
||||
public @org.jetbrains.annotations.NotNull method getP(@Ann p0: java.lang.String): java.lang.String
|
||||
public method <init>(): void
|
||||
}
|
||||
|
||||
@java.lang.annotation.Retention @kotlin.jvm.internal.KotlinClass Ann
|
||||
|
||||
@kotlin.jvm.internal.KotlinFileFacade OnReceiverKt {
|
||||
@org.jetbrains.annotations.NotNull method topLevelF(@Ann p0: java.lang.String): java.lang.String
|
||||
@org.jetbrains.annotations.NotNull method getTopLevelP(@Ann p0: java.lang.String): java.lang.String
|
||||
public @org.jetbrains.annotations.NotNull method topLevelF(@Ann p0: java.lang.String): java.lang.String
|
||||
public @org.jetbrains.annotations.NotNull method getTopLevelP(@Ann p0: java.lang.String): java.lang.String
|
||||
}
|
||||
|
||||
@java.lang.Deprecated @kotlin.jvm.internal.KotlinPackage _DefaultPackage {
|
||||
field $kotlinPackage: kotlin.reflect.KPackage
|
||||
field $moduleName: java.lang.String
|
||||
public synthetic field $kotlinPackage: kotlin.reflect.KPackage
|
||||
public synthetic field $moduleName: java.lang.String
|
||||
method <clinit>(): void
|
||||
@kotlin.jvm.internal.KotlinDelegatedMethod @org.jetbrains.annotations.NotNull method getTopLevelP(@Ann p0: java.lang.String): java.lang.String
|
||||
@kotlin.jvm.internal.KotlinDelegatedMethod @org.jetbrains.annotations.NotNull method topLevelF(@Ann p0: java.lang.String): java.lang.String
|
||||
public @kotlin.jvm.internal.KotlinDelegatedMethod @org.jetbrains.annotations.NotNull method getTopLevelP(@Ann p0: java.lang.String): java.lang.String
|
||||
public @kotlin.jvm.internal.KotlinDelegatedMethod @org.jetbrains.annotations.NotNull method topLevelF(@Ann p0: java.lang.String): java.lang.String
|
||||
}
|
||||
@@ -48,9 +48,22 @@ public abstract class AbstractBytecodeListingTest : CodegenTestCase() {
|
||||
private val classAnnotations = arrayListOf<String>()
|
||||
private var className = ""
|
||||
|
||||
private fun addAnnotation(desc: String) {
|
||||
private fun addAnnotation(desc: String, list: MutableList<String> = declarationsInsideClass.last().annotations) {
|
||||
val name = Type.getType(desc).className
|
||||
declarationsInsideClass.last().annotations.add("@$name ")
|
||||
list.add("@$name ")
|
||||
}
|
||||
|
||||
private fun addModifier(text: String, list: MutableList<String>) {
|
||||
list.add("$text ")
|
||||
}
|
||||
|
||||
private fun handleModifiers(access: Int, list: MutableList<String> = declarationsInsideClass.last().annotations) {
|
||||
if ((access and Opcodes.ACC_PUBLIC) != 0) addModifier("public", list)
|
||||
if ((access and Opcodes.ACC_PROTECTED) != 0) addModifier("protected", list)
|
||||
if ((access and Opcodes.ACC_PRIVATE) != 0) addModifier("private", list)
|
||||
|
||||
if ((access and Opcodes.ACC_SYNTHETIC) != 0) addModifier("synthetic", list)
|
||||
if ((access and Opcodes.ACC_DEPRECATED) != 0) addModifier("deprecated", list)
|
||||
}
|
||||
|
||||
public val text: String
|
||||
@@ -78,6 +91,8 @@ public abstract class AbstractBytecodeListingTest : CodegenTestCase() {
|
||||
val methodAnnotations = arrayListOf<String>()
|
||||
val parameterAnnotations = hashMapOf<Int, MutableList<String>>()
|
||||
|
||||
handleModifiers(access, methodAnnotations)
|
||||
|
||||
return object : MethodVisitor(Opcodes.ASM5) {
|
||||
override fun visitAnnotation(desc: String, visible: Boolean): AnnotationVisitor? {
|
||||
val type = Type.getType(desc).className
|
||||
@@ -105,6 +120,8 @@ public abstract class AbstractBytecodeListingTest : CodegenTestCase() {
|
||||
override fun visitField(access: Int, name: String, desc: String, signature: String?, value: Any?): FieldVisitor? {
|
||||
val type = Type.getType(desc).className
|
||||
declarationsInsideClass.add(Declaration("field $name: $type"))
|
||||
handleModifiers(access)
|
||||
|
||||
return object : FieldVisitor(Opcodes.ASM5) {
|
||||
override fun visitAnnotation(desc: String, visible: Boolean): AnnotationVisitor? {
|
||||
addAnnotation(desc)
|
||||
|
||||
@@ -49,6 +49,12 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("JvmSynthetic.kt")
|
||||
public void testJvmSynthetic() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeListing/annotations/JvmSynthetic.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("literals.kt")
|
||||
public void testLiterals() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeListing/annotations/literals.kt");
|
||||
|
||||
@@ -61,6 +61,10 @@ public annotation class JvmName(public val name: String)
|
||||
@MustBeDocumented
|
||||
public annotation class JvmMultifileClass
|
||||
|
||||
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.FIELD)
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
public annotation class JvmSynthetic
|
||||
|
||||
/**
|
||||
* Instructs the Kotlin compiler to generate a public backing field for this property.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user