Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin Compiler Plugin: How to check if a property has an annotation?

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?

like image 883
Sasha Shpota Avatar asked Dec 06 '25 11:12

Sasha Shpota


1 Answers

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:

  • getName
  • getName$annotations
  • ...

As 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

like image 86
MrGewurz Avatar answered Dec 09 '25 00:12

MrGewurz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!