kotlin注释处理器中的可空类型

Gil*_*eig 8 java annotations annotation-processing kotlin kapt

我正在为Kotlin开发注释处理器,因为处理过的元素是用Java编写的,我没有收到?带有@Nullable注释的nullables ,这很好,但是我遇到了在类型和高阶函数中接收空参数的问题,对于正常参数.

var someNullField: String? = "" 
Run Code Online (Sandbox Code Playgroud)

我将在其注释java.lang.String过程@org.jetbrains.annotations.Nullable中收到.

但是List<String?>例如将返回我java.util.List<java.lang.String>没有任何注释不在主元素中而不在类型参数中导致未知的可空性状态

我尝试使用javax.lang.model.util.Types找到某种结果,但没有.

我现在使用的一些代码:

val utils = processingEnvironment.typeUtils
val type = fieldElement.asType()
if (type is DeclaredType) {
    val typeElement = utils.asElement(type)
    type.typeArguments
            .forEach {
                //Trying different ways and just printing for possible results
                val capture = utils.capture(it)
                val erasure = utils.erasure(it)
                val element = utils.asElement(it)
                printMessage("element: $element isNullable: ${element.isNullable()} isNotNull: ${element.isNotNull()}\ncapture: $capture isNullable: ${capture.isNullable()} isNotNull: ${capture.isNotNull()}\nerasure: $erasure isNullable: ${erasure.isNullable()} isNotNull: ${erasure.isNotNull()}")
            }
}
Run Code Online (Sandbox Code Playgroud)

所有帮助将不胜感激.

use*_*723 5

一些必要的历史:从 Java 6(当 Mirror API 公开时)开始,Java 注释不能用于任何东西,但可以通过反射访问相同类型的顶级元素。您可以注释类、方法和字段,但不能注释类型参数 ( List<String>) 或局部变量 ( String value = ...)。Sun/Oracle 工程师已经承认了这个限制,并且在 Java 8 中诞生了所谓的“类型注释”。

类型注释可以针对类型什么的:类型局部变量的阵列组件类型,类型变量类型,甚至返回类型(!后来注释也同样放置,但是从方法的老派注解不同)。类型注释是通过新@Target值创建的:ElementType#TYPE_USE

当 Kotlin 人写

List<String?>
Run Code Online (Sandbox Code Playgroud)

这真的意味着

List<@Nullable String>
Run Code Online (Sandbox Code Playgroud)

可以读作:“可为空的字符串元素列表”。

由于类型本身是目标类型,因此您应该通过检查它的原始类型来获取注释TypeMirror(不要理会擦除或捕获的 TypeMirror,它们与源代码的连接不足以保留注释)。巧合的是,镜像 API 被重构,产生了新的接口AnnotatedConstruct,并方便地使 TypeMirror 成为它的后代。


现在坏消息是:到 Java 8 发布时,对检查类型注释的支持显然还没有做好生产准备,所以它被扼杀了。JSR 已被重写以暗示“TypeMirror#getAnnotationMirrors”应该不返回任何内容。

从公共 API 中删除的部分支持仍可通过 Oracle 的供应商特定的Tree API 获得(仅在 javac 中受支持)。由 Tree#getTypeMirror 返回的 TypeMirror可能包含您期望的注释。但是由于它有问题,您将只能通过一系列 hack 获得注释,最终,这不会一直有效(例如在嵌套类型参数的情况下)。有关方向的一些研究,请参阅此问题

Java 9 中已合并了该混乱的修复程序。我尚未对其进行测试,但看起来 TypeMirror#getAnnotationMirrors 最终可能会起作用。没有计划将修复程序向后移植到较旧的 Java 版本。