a Java annotation processor中,我使用DocTrees#getDocCommentTree(Element)获得DocCommentTree,我和访问者一起走过go .为找到的{@link个令牌调用Visitor's visitLink(LinkTree,C) method.对于{@link Foo},LinkTree#getReference().getSignature()返回Foo,尽管它不会给出完全限定的类名.就是,是java.lang.Foo吗?Foo是同一包的吗?是不是有Foo级的进口货?如何在解析Javadoc中的链接时获得引用的完全限定名称?

推荐答案

在注释处理器中解析Javadoc时,我们可以首先创建一个ImportTree,并使用它来确定由LinkTree#getReference()返回的ReferenceTree的FQCN,即{@link signature label}中的FQCN.我已经在10万分之一的情况下实现了这一点.伪码如下:

public class ExampleProcessor extends AbstractProcessor {

    private DocTrees docTrees;

    private Trees trees;

    @Override
    public synchronized void init(final ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
        docTrees = DocTrees.instance(processingEnv);
        trees = Trees.instance(processingEnv);
    }

    private void scanDocTree(Element element) {
        Map<String, String> imports = collectElementImports(element);
        ExampleContext context = new ExampleContext(imports);
        DocCommentTree tree = docTrees.getDocCommentTree(element);
        ExampleDocTreeVisitor visitor = new ExampleDocTreeVisitor();
        tree.accept(visitor, context);
    }

    private static final class ExampleDocTreeVisitor<Void, ExampleContext>
            extends SimpleDocTreeVisitor<Void, ExampleContext> {

        @Override
        public Void visitLink(LinkTree linkTree, final ExampleContext context) {
            String signature = linkTree.getReference().getSignature();
            String fqcn = context.imports.get(signature);
            // ...
            return super.visitLink(node, data);
        }

    }

    private Map<String, String> collectElementImports(Element element) {
        ImportCollectingTreeScanner scanner = new ImportCollectingTreeScanner();
        TreePath treePath = trees.getPath(element);
        scanner.scan(treePath.getCompilationUnit(), null);
        return scanner.imports;
    }

    private static final class ImportCollectingScanner
            extends TreeScanner<Object, Trees> {

        private final Map<String, String> imports = new HashMap<>();

        @Override
        public Object visitImport(ImportTree importTree, Trees trees) {
            Tree qualifiedIdentifier = importTree.getQualifiedIdentifier();
            String qualifiedClassName = qualifiedIdentifier.toString();
            String simpleClassName = qualifiedClassName.substring(qualifiedClassName.lastIndexOf('.') + 1);
            imports.put(simpleClassName, qualifiedClassName);
            return super.visitImport(importTree, trees);
        }

    }

}

学分

  • @piotr-p-karwaz为ImportTree个提示
  • Andi's blog关于如何在批注处理器中提取ImportTree

Java相关问答推荐

Java Streams在矩阵遍历中的性能影响

即使我正在使用并发方法,使用Javascript的应用程序也会继续冻结'

将不受支持的时区UT重写为UTC是否节省?

如何创建一个2d自上而下的移动系统,其中移动,同时持有两个关键是可能的处理?

使用Spring Boot3.2和虚拟线程的并行服务调用

Spring @Value default无法计算表达式

把一条整型短裤和两条短裤装成一条长的

通过Spring Security公开Spring Boot执行器端点

如何对多个字段进行分组和排序?

使用PDFBox从PDF中删除图像

如何从日志(log)行中删除包名称?

在Java中将int[]矩阵添加到ArrayList中,但出现错误

Spring Boot&;Docker:无法执行目标org.springframework.boot:spring-boot-maven-plugin:3.2.0:build-image

无法播放音频:从资源加载库GStreamer-Lite失败

Java组件项目中的JavaFX对话框国际化

项目react 堆中doOnComplete()和Subscribe()的第三个参数之间的差异

Java集合:NPE,即使没有添加空值

本机方法(JNI)总是编译的吗?

如何制作回文程序?

如何设置默认序列生成器分配大小