如何使用 KotlinPoet 获取 PropertySpec 的正确 TypeName

8
使用KotlinPoet,为了生成用于向类和构造函数添加属性的PropertySpec,您需要一个TypeName对象。
TypeMirror.asTypeName() KotlinPoet函数已弃用,因为它对于Kotlin类型不总是正确的。
但我找不到任何一个示例,说明如何使用kotlinpoet-metadata API获取Kotlin类(例如kotlin.String)的正确TypeName,就像弃用消息所说的那样。
kotlinpoet-metadata API的文档似乎也完全损坏了(转到https://square.github.io/kotlinpoet/interop-kotlinx-metadata/#interop-with-kotlinx-metadata并单击API部分下的任何内容)
是否有人有一个示例,说明如何使用一些kotlinpoet-metadata代码替换TypeMirror.asTypeName()以获取TypeName,以便我可以创建PropertySpec?

1
你是否事先知道你所引用的类,还是该类由你的注解处理器确定,并且仅作为TypeMirror可用? - Louis Wasserman
1
该类在处理器中作为一个注释元素提供,因此我只有一个类型镜像。我知道在这种情况下当前的故障是由于字符串引起的。asTypeName总是生成java.lang.String,但我需要kotlin.String。 - M Dapp
1
还有一个在概述部分缺失的链接:KotlinPoet-metadata-specs - Михаил Нафталь
当类由您的注释处理器确定并且仅作为TypeMirror可用时,是否有任何可用的示例?链接似乎404。谢谢! - AllDayAmazing
2个回答

3

我不确定这是否符合废弃消息的意图,但这是我让它工作的方法。

首先,我必须添加kotlinpoet-metadata-specs。

implementation("com.squareup:kotlinpoet:1.7.1")
implementation("com.squareup:kotlinpoet-metadata:1.7.1")
implementation("com.squareup:kotlinpoet-metadata-specs:1.7.1")

然后使用com.squareup.kotlinpoet.metadata.specs.internal.ClassInspectorUtil中的一个工具方法来创建className。

val packageName = getPackage(element).qualifiedName.toString()
val typeMetadata = element.getAnnotation(Metadata::class.java)
val kmClass = typeMetadata.toImmutableKmClass()
val className = ClassInspectorUtil.createClassName(kmClass.name)

然后使用

val funSpec = FunSpec.builder("allNullableSet")
                     .receiver(className)
                     .returns(Boolean::class.java)
                     .addStatement(statement)
                     .build()

3
谢谢,这很有用。但是在KotlinPoet中,ClassInspectorUtil被标记为internal。我想知道是否有一种使用公共API从ImmutableKmClass获取TypeName的方法? - David Rawson
这对于属性也不起作用,因为只有类才能获得元数据注释。在这种情况下,对于构造函数参数,我可以使用:annotatedElement.enclosingElement.getAnnotation(Metadata::class.java).toImmutableKmClass().constructors[0].parameters来获取构造函数参数,但它们是 ImmutableKmValueParameter 而不是类。有没有办法为 ImmutableKmValueParameter 获取 TypeName?我可以为这种情况提出一个新问题... - M Dapp

0

我已经找到了一种方法,在我的AbstractProcessor中通过访问processingEnv来获取TypeElementTypeName,非常感谢。

val kmClass = (typeElement.kotlinClassMetadata() as KotlinClassMetadata.Class).toKmClass()
val elementName: TypeName = ClassName(processingEnv.elementUtils.getPackageOf(typeElement).toString(), kmClass.name.substringAfterLast("/"))

通过手动拆分kmClass.name,也可以在没有processingEnv的情况下完成。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接