kotlinannotationsannotation-processor

Get value of static field from annotation


I would like to get value from static field from the declared annotation. Example:

@TestAnnotation
const val MY_CUSTOM_FIELD = "test123"

and I would like to get "test123" as value.

So far I can get the name and kind from Element like this:

for (element: Element in environment?.getElementsAnnotatedWith(TestAnnotation::class.java)!!) {
   if (element.kind != ElementKind.FIELD) {
      messager?.error("@TestAnnotation must be applied to field")
      return true
   }
   val typeMirror = element.asType()
   messager?.error(elements?.getName(element.simpleName).toString()) // this prints MY_CUSTOM_FIELD
   messager?.error(typeMirror.toString()) // this prints java.lang.String
}

is it possible somehow to get "test123"?


Solution

  • You can use VariableElement#getConstantValue():

    Returns the value of this variable if this is a final field initialized to a compile-time constant. Returns null otherwise. The value will be of a primitive type or a String. If the value is of a primitive type, it is wrapped in the appropriate wrapper class (such as Integer).

    Note that not all final fields will have constant values. In particular, enum constants are not considered to be compile-time constants. To have a constant value, a field's type must be either a primitive type or String.

    Returns:
    the value of this variable if this is a final field initialized to a compile-time constant, or null otherwise

    See Java Language Specification:
    15.28 Constant Expression
    4.12.4 final Variables

    You'll have to cast the Element to a VariableElement. For example:

    for (element: Element in environment?.getElementsAnnotatedWith(TestAnnotation::class.java)!!) {
       if (element.kind != ElementKind.FIELD) {
          messager?.error("@TestAnnotation must be applied to field")
          return true
       }
       val constant = (element as VariableElement).constantValue;
    }
    

    Note that since element.kind == ElementKind.FIELD the cast to VariableElement will work.