Lets say my annotation processor's process function looks like below
override fun process(
annotations: MutableSet<out TypeElement>,
roundEnv: RoundEnvironment
): Boolean {
try {
roundEnv.getElementsAnnotatedWith(CustomAnnotation::class.java)
.mapNotNull {
if (it.kind != ElementKind.INTERFACE) {
printError(
"Only interfaces can be annotated with " +
MapperConfig::class.java.simpleName
)
null
} else {
it as TypeElement
}
}.forEach {
processMapperConfigInterface(it, roundEnv)
}
} catch (ex: Exception) {
messager.printError(ex.message!!)
}
return true
}
roundEnv.getElementsAnnotatedWith
returns me tthe java Elements without any kotlin type information, how do I use annotation processing to get proper kotlin type information instead?
I had the same problem and the only solution I could come up with, is to parse the element's metadata using the kotlinpoet-metadata API.
IMPORTANT NOTE: kotlinpoet-metadata
is still early in production and is itself based on the experimental kotlinx-metadata
library, so things might break in the future. However, it is currently used in the stable version of the Moshi Kotlin code generator.
First, make sure that you've added the following to your dependencies in your build.gradle:
dependencies {
implementation 'com.squareup:kotlinpoet:1.7.1'
implementation 'com.squareup:kotlinpoet-metadata:1.7.1'`
}
1.7.1 is the latest KotlinPoet version as of today.
You can get the Kotlin type information via a KmClass
, constructed from your element's metadata. Here's an example on using KmClass and here's what you would need to change in your code:
override fun process(
annotations: MutableSet<out TypeElement>,
roundEnv: RoundEnvironment
): Boolean {
try {
roundEnv.getElementsAnnotatedWith(CustomAnnotation::class.java)
.mapNotNull {
if (it.kind != ElementKind.INTERFACE) {
printError(
"Only interfaces can be annotated with " +
MapperConfig::class.java.simpleName
)
null
} else {
it as TypeElement
}
}.forEach {
val typeMetadata = it.getAnnotation(Metadata::class.java) ?: return@forEach
var kmClass = typeMetadata.toImmutableKmClass()
// HERE: kmClass should contain all the Kotlin type information.
}
} catch (ex: Exception) {
messager.printError(ex.message!!)
}
return true
}