Java – nullable types in the kotlin annotation processor

I'm developing an annotation processor for kotlin. Because the processed elements are written in Java, I didn't receive nullables? On the contrary, using @ nullable annotation is good, but I have encountered the problem of receiving null parameters in types and higher-order functions, for ordinary parameters

var someNullField: String? = ""

I will receive Java. Net in the process Lang. string, whose comment contains @ org. String jetbrains. annotations. Nullable.

But list < string? > For example, Java util. List< java. Lang. string > no comment, not in the main element, not in the type parameter, resulting in an unknown nullability state

翻译错误 TIMEOUT

Some of the codes I use now:

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()}")
            }
}

All help will be greatly appreciated

Solution

Some necessary history: starting with Java 6 (when the mirroring API is exposed), Java annotations cannot be used for anything, but top-level elements of the same type that can be accessed through reflection You can annotate classes, methods, and fields, but you cannot annotate type parameters (list < string >) or local variables (string value =...) Sun / Oracle engineers have acknowledged this limitation and the so-called "type annotation" has appeared in Java 8

Type annotations can locate any type: the type of a local variable, the type of an array component, the type of a type variable, or even the return type (the latter annotations are placed similarly, but different from the old-fashioned annotations on methods!) The type annotation is created with a new @ target value: elementtype#type_ USE.

When the kotlin wrote it

List<String?>

That really means

List<@Nullable String>

It can be read as: "list of nullable string elements"

Since the type itself is the target, you need to get comments by checking its original typemirror (do not disturb deleted or captured typemirrors, which do not have enough connection with the source code to retain comments) Coincidentally, the mirror API was refactored to produce a new interface annotatedconstruct, and easily make typemirror its descendant

Now the bad news: by the time Java 8 was released, support for checking type annotations was obviously not production ready, so it was slaughtered JSR has been rewritten to imply that "typemirror #getannotationmirrors" should not return anything

Support bits removed from the public API are still available through Oracle's vendor specific tree API (supported only in javac) The typemirror returned by the tree #gettypemirror may contain comments that you expect But because it's wrong, you can only get comments through a series of hackers, and in the end, it won't work all the time (for example, in the case of nested type parameters) For some research in this direction, see this question

The fix incorporates this confusion in Java 9 I haven't tested it yet, but it looks like typemirror #getannotation mirrors may eventually work There are no plans to reverse migrate the fix to the old java version

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>