获取 javax.annotation.processing.Processor 中 VariableElement 的封闭 class 名称

Get enclosing class name of a VariableElement in javax.annotation.processing.Processor

我刚开始学习 Java 中的注释处理。我有 @MyAnnotation 目标 ElementType.FIELD,在我的 Processor 中,我将注释限制为仅允许非空唯一 value。哪个正常工作。

在记录错误以防某些重复 value 设置为 MyAnnotation.value 时,我想提供源代码中现有注释和新的重复注释的完整路径.

我的注释:

@Retention(RetentionPolicy.RUNTIME)
@Target(value = ElementType.FIELD)
public @interface   ProviderColumn {
    String content_id();
}

示例父 Class.

public class EnclosingParent {
    @ProviderColumn(content_id="Hello")
    private String value1;

    @ProviderColumn(content_id="Hello")
    private String value2;
}

我的 AnnotationProcessor

@Override
public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment)
{
    UniqueColumnNameChecker columnNameChecker = new UniqueColumnNameChecker();

    try {

        for (Element annotatedElement : roundEnvironment.getElementsAnnotatedWith(ProviderColumn.class)) {

            // We can cast it, because we know that it is of ElementType.FIELD
            VariableElement variableElement = (VariableElement) annotatedElement;

            try {
                ProviderColumnId providerColumnId =
                        new ProviderColumnId(variableElement);

                // How can I get the EnclosingParent.class or even just a complete canonical class name?

                // throws a DuplicateAnnotationIdException when it detects duplicate entries.
                columnNameChecker.addAnnotationColumnName(providerColumnId);
            }
            catch (IllegalArgumentException e) {
                error(variableElement, e.getMessage());
                return true;
            }
        }
    }
    catch (DuplicateAnnotationIdException ex) {
        error(ex.getMessage());
        return true;
    }

    return true;
}

但是我无法弄清楚如何从 VariableElement 中获取封闭的 class 信息。由于我才开始 AnnotationProcessing,我什至不确定这是否可行,而且我无法在 Whosebug 或其他任何地方找到与此问题相关的任何问题。

预期错误输出

Duplicate content_id()='Hello' detected, Found at 'com.example.EnclosingParent.value1' and 'com.example.EnclosingParent.value2'.

注意:我意识到如果我定义一个新的 ElementType.TYPE 注释并设置为封闭 class,我可以获得父信息,但我希望避免这种情况,因为它增加了额外的责任第三方开发者。

显然是个愚蠢的问题。我在所有错误的地方寻找封闭元素,发现这个优秀的 Annotation Processor Tutorial 其中指出:

Elements and TypeMirrors

...

You can think of it like a XML file you try to parse (or an abstract syntax tree in compiler construction)

我意识到 Element 本身可能包含我需要的所有信息。

只需要调用variableElement.getEnclosingElement()获取父Element

从那里开始就很容易了,您可以像这样附上 class 名称:

element.getEnclosingElement().asType().toString();

但这并不能保证封闭元素是 TypeElement。所以只需使用 instanceof 来确保它是。