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