我正在创建一个 Kotlin 编译器插件,其中我需要检查数据类的属性是否有注释:
data class User(
@MyAnnotation
val name: String
)
我通过以下方式覆盖
DelegatingClassBuilder.newField
:
internal class MyClassBuilder(
delegateBuilder: ClassBuilder
) : DelegatingClassBuilder(delegateBuilder) {
override fun newField(
origin: JvmDeclarationOrigin,
access: Int,
name: String,
desc: String,
signature: String?,
value: Any?
): FieldVisitor {
val visitor = super.newField(origin, access, name, desc, signature, value)
val descriptor = origin.descriptor as? PropertyDescriptor ?: return visitor
if (descriptor.annotations.hasAnnotation(FqName("com.example.MyAnnotation"))) {
// I never get here
}
return visitor
}
}
问题:无论我的属性是否有注释,
descriptor.annotations
都不会包含我的注释。如果我将注释使用目标更改为其他任何内容,我仍然没有得到注释。
同时,如果我注释一个函数并覆盖
newMethod
,我可以使用非常相似的代码获得该函数的注释。
问题:如何获取数据类中属性的注释?
我想我的回答不会对你有帮助,但对任何有未来问题的人来说。 对于没有Target的字段注释,编译器将生成一个具有注释的函数。 所以,
data class User(@MyAnnotation val name: String)
将编译为以下函数:
getName
getName$annotations
顾名思义,注释
@MyAnnotation
位于getName$annotations
。
您可以通过指定目标来避免这种情况:
data class User(@field:MyAnnotation val name: String)
有了目标,就可以直接通过
newField
函数引用;否则,您必须通过 newMethod
函数访问它并提取该字段。如果您为最终用户开发插件,您可能应该实现这两种方法,因为最终用户可能(不)添加目标
试试这个:
myObject::class
.memberProperties
.forEach {
if (it.hasAnnotation<FooBar>()) {
val annotation = it.findAnnotation<FooBar>()
// doYourStuff()
}
在数据类中:
@property:FooBar
val myField: Any