Search code examples
androidkotlinkotlinpoet

Is roundEnv.getElementsAnnotatedWith(AnnotationName::class.java) reflection broken when used with a @Repeatable @Retention(AnnotationRetention.Source)


When building a AbstractProcessor in Android studio using kapt/kotlinpoet. When I try to use the repeatable annotation tag it stop getting data back from roundEnv.getElementsAnnotatedWith(AnnotationName::class.java), I am able get the annotated classes info back if the repeatable tag is removed from the annotation

going to try to use other means of reflection

@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.SOURCE)
@Repeatable // <-- issue 
annotation class ConfigurableGroup(
    val key: String,
    val text: String
)
// the processor abbreviated

@AutoService(Processor::class)
@SupportedSourceVersion(SourceVersion.RELEASE_8)
@SupportedOptions(AnnotationProcessorNew.
KAPT_KOTLIN_GENERATED_OPTION_NAME)
class AnnotationProcessorNew : AbstractProcessor(){

override fun process(annotations: MutableSet<out TypeElement>, roundEnv: 
RoundEnvironment): Boolean {
    return generateConfigurables(roundEnv)
}

override fun getSupportedAnnotationTypes(): MutableSet<String> {
    return mutableSetOf(
ConfigurableGroup::class.java.name
}

roundEnv.getElementsAnnotatedWith(ConfigurableGroup::class.java)
       .filter { it.kind == ElementKind.CLASS }
       .forEach { classElement ->

          val classPackageName = 
processingEnv.elementUtils.getPackageOf(classElement).toString()
               val classSimpleName = classElement.simpleName.toString()

I would expect to get data from reflection both times when the annotation has a @repeatable tag or not.


Solution

  • It seems that Kotlin's @Repeatable annotation is purely a hint for tooling and does not match up with Java's @Repeatable contract.

    It seems that the java contract requires a container annotation to be defined so that the repeated annotations can be packaged as a single annotation for retrieval by the annotation processor.

    You either need to explicitly add @java.lang.annotation.Repeatable(ConfigurableGroups::class) for a container annotation and accept the warning it generates or define the annotations in Java instead of Kotlin.