jbunting
jbunting

Reputation: 901

How to annotate an annotation property in kotlin?

I am attempting to place an annotation on an annotation property. My understanding is that I should be able to access it in code -- but I am not able to. What am I missing?

package com.example.annotations

import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import kotlin.reflect.full.findAnnotation

class AnnotationIssueTest {
    @Test
    fun testAnnotations() {
        Assertions.assertNotNull(MyTestAnnotation::value.findAnnotation<PropertyMarker>())
    }

    @Test
    fun testRegularClass() {
        Assertions.assertNotNull(MyTestClass::value.findAnnotation<PropertyMarker>())
    }
}


@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.PROPERTY)
annotation class PropertyMarker

annotation class MyTestAnnotation(
        @PropertyMarker val value: String
)

class MyTestClass(
        @PropertyMarker val value: String
)

When I run the given test, testAnnotations fails while testRegularClass passes. Is this a bug or am I doing something wrong?

Upvotes: 1

Views: 1481

Answers (2)

skadush
skadush

Reputation: 1

You can also add a site-tagret to the annotation like so:

data class MyTestClass( // not sure if data classes will work for you use case
        @property:PropertyMarker val value: String // <-- add property site-target
)

This worked for me when creating a KSP plugin and I was not able to pick up annotations when looking at a data class' properties.

Upvotes: 0

Joe Bloggs
Joe Bloggs

Reputation: 1671

For some reason annotations of annotation properties don't make their way into the bytecode. However, you can annotate property getters instead:

class AnnotationIssueTest {
    @Test
    fun testAnnotations() {
        Assertions.assertNotNull(MyTestAnnotation::value.getter.findAnnotation<PropertyMarker>())
    }

    @Test
    fun testRegularClass() {
        Assertions.assertNotNull(MyTestClass::value.getter.findAnnotation<PropertyMarker>())
    }
}


@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.PROPERTY_GETTER)
annotation class PropertyMarker

annotation class MyTestAnnotation(
        @get:PropertyMarker val value: String
)

class MyTestClass(
        @get:PropertyMarker val value: String
)

Upvotes: 4

Related Questions