I am creating a Kotlin compiler plugin in which I need to check if a property of a data class has an annotation:
data class User(
@MyAnnotation
val name: String
)
I override DelegatingClassBuilder.newField in the following way:
internal class MyClassBuilder(
delegateBuilder: ClassBuilder
) : DelegatingClassBuilder(delegateBuilder) {
override fun newField(
origin: JvmDeclarationOrigin,
access: Int,
name: String,
desc: String,
signature: String?,
value: Any?
): FieldVisitor {
val visitor = super.newField(origin, access, name, desc, signature, value)
val descriptor = origin.descriptor as? PropertyDescriptor ?: return visitor
if (descriptor.annotations.hasAnnotation(FqName("com.example.MyAnnotation"))) {
// I never get here
}
return visitor
}
}
Problem: No matter if my property is annotated or not descriptor.annotations would not contain my annotation. If I change the annotations use target to anything else I still don't get the annotation.
At the same time, if I annotate a function and override newMethod, I can get annotations of of this function with pretty similar code.
Question: How to get annotations of a property in a data class?
I guess my answer won't help you, but for anyone with a future problem. For field annotations without a Target the compiler will generate a function that has the annotation. So,
data class User(@MyAnnotation val name: String)
will compile to the following functions:
getNamegetName$annotationsAs the name suggests, the annotation @MyAnnotation is located in getName$annotations.
You can avoid this by specifying a Target:
data class User(@field:MyAnnotation val name: String)
With the target, you can reference it directly via newField function; otherwise you have to access it via the newMethod function and extract the field. If you develop a plugin for end-user you probably should implement both methods, as the end-user might(not) add a target
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With