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

时间:2017-08-19 20:02:45

标签: java annotations kotlin annotation-processing kapt

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

var someNullField: String? = "" 

我会在注释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()}")
            }
}

所有帮助将不胜感激。

1 个答案:

答案 0 :(得分:3)

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

类型注释可以定位任何内容的类型类型的局部变量,数组组件类型,类型变量类型甚至返回类型(以后的注释类似地放置,但不同于方法上的老派注释!)。类型注释是通过新的@Target值创建的:ElementType#TYPE_USE

Kotlin人写的时候

List<String?>

这真的意味着

List<@Nullable String>

可以读作:&#34;可以为空的String元素列表&#34;。

由于类型本身是目标,因此您需要通过检查其原始TypeMirror来获取注释(不要为删除或捕获的TypeMirrors而烦恼,他们没有足够的源代码连接来保留注释。巧合的是,Mirror API被重构,产生了新的接口AnnotatedConstruct,并且方便地使TypeMirror成为它的后代。

现在是坏消息:到Java 8发布时,检查类型注释的支持显然还没有生产就绪,所以它被屠杀了。 JSR已被重写为暗示,&#34; TypeMirror#getAnnotationMirrors&#34;应该什么也不返回。

从公共API中删除的支持位仍可通过Oracle特定于供应商的Tree API获得(仅在javac中受支持)。 Tree#getTypeMirror 返回的TypeMirror可能按照您期望的方式包含注释。但由于它是错误的,你只能通过一系列黑客获得注释,并且最终,它不会一直工作(例如在嵌套类型参数的情况下)。有关该方向的一些研究,请参阅this question

The fix这个混乱是在Java 9中合并的。我还没有对它进行测试,但看起来TypeMirror#getAnnotationMirrors可能最终有效。没有计划将修复程序反向移植到旧的Java版本。