I want to get the annotation for overloaded function as below:
class A{
@debug
fun functionA(){
}
@debug
fun functionA(a:Int){
}
}
But kotlinx-metadata-jvm
doesn’t seem to provide any utility function to do this. It only provides Flag.HAS_ANNOTATIONS
flags which is commented:
/**
* Signifies that the corresponding declaration has at least one annotation.
*
* This flag is useful for reading Kotlin metadata on JVM efficiently. On JVM, most of the annotations are written not to the Kotlin
* metadata, but directly on the corresponding declarations in the class file. This flag can be used as an optimization to avoid
* reading annotations from the class file (which can be slow) in case when a declaration has no annotations.
*/
@JvmField
val HAS_ANNOTATIONS = Flag(F.HAS_ANNOTATIONS)
For non-overloaded functions, I can get annotations from ExecutableElement
as below:
val functionAnnotations=mutableMapOf<String,Annotation>()
ElementFilter.methodsIn(typeElement.enclosedElements).forEach{
functionAnnotations[it.simpleName.toString()]= it.getAnnotation(debug::class.java)
}
val header = typeElement.getAnnotation(Metadata::class.java).run {
KotlinClassHeader(kind, metadataVersion, bytecodeVersion, data1, data2, extraString, packageName, extraInt)
}
val metadata = KotlinClassMetadata.read(header) as KotlinClassMetadata.Class
metadata.accept(object: KmClassVisitor() {
override fun visitFunction(flags: Flags, name: String): KmFunctionVisitor? {
val annotation=functionAnnotations[name] // retrieve by name
}
}
For overloaded functions, you can’t just map them using their names, their types should also be included which are only visited by kotlinx-metadata.
One possible way to do this maybe through JvmFunctionExtensionVisitor
which has fun visit(signature: JvmMethodSignature?)
that provides JvmMethodSignature
. But JvmMethodSignature is merely name:String+desc:String
. Then this JvmMethodSignature
should be same
as ExecutableElement
. But this way is too verbose and fragile.