lundi 20 juillet 2020

Kotlin annoation multiple targets

I have an annotation like:

@Target(AnnotationTarget.FIELD, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.PROPERTY)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class Foo(val bar: Int)

And using some reflection I read this annotation like:

for (prop in myClass.memberProperties) {
   val foo = prop.findAnnotation<Foo>() ?: continue
   // Do something with foo
}

This works fine when the class is defined like

class MyClass {
   @Foo(bar = 1)
   var myProp: Int = 0
}
// prop.findAnnotation<Foo>() => { bar: 1 }

but when the class is defined like a data class with the property in the constructor the annotation is targeted as VALUE_PARAMETER and I cannot get it on my memberProperties:

data class MyOtherClass (
   @Foo(bar = 1)
   val myProp: Int
)
// prop.findAnnotation<Foo>() => null

I can of course explicitly target it with @property:Foo(bar = 1) but I would like to use it without worrying about this, much like @JsonProperty from jackson does. When searching for the annotations I can of course check for the memberProperties as well as parameters in constructors... But KParameter and KProperty only have KAnnotated as a common parent, making a bit hard to work with both interchangeably since I also need the type and name for the property, not only the annotation. Is that a better way to do it?





Aucun commentaire:

Enregistrer un commentaire