关于ast抽象语法树JcImport和JCCompilationUnit的用法

最近在做抽象语法树的功能,一开始很懵逼,非常感谢大佬提供的类属性解释文章,这才开始明白如何去写。
博客地址:https://www.jianshu.com/p/68027eaf45ad

关于如何创建注解处理器我这儿就不说了,网上有很多方式,如下:
https://blog.csdn.net/a1527238987/article/details/80379834

废话不多说,现在有一些需求,需要在编译期间动态添加某个导包怎么办,经过上面的博客我查到JcImport是表示导包的类,但是要如何使用呢,一开始我用的是
在这里插入图片描述
defs这个属性,试图通过添加一个JcImport进去,然后运行各种报错,经过调试发现,他只表示某些方法,错误写法:

java.util.List defs = new ArrayList();
JCTree.JCIdent ident = _maker.Ident(_names.fromString(TRACKER_PACKAGE));
JCTree.JCImport jcImport = _maker.Import(_maker.Select(ident, _names.fromString(TRACKER_CLASS)), false);
defs.add(jcImport);
jcClassDecl.defs = List.from(defs);

后来经过查资料,我发现了一个类JCCompilationUnit,发现它里面包含很多信息
在这里插入图片描述
它里面包含很多信息,这里面的defs正是包含import导包和定义的class信息,如图:
在这里插入图片描述
这个时候我就想要怎么拿到这个信息,于是google搜索资料,发现根本没啥资料
然后看到一个网址有一些code example,如下网址:
https://www.programcreek.com/java-api-examples/?class=com.sun.tools.javac.tree.JCTree&method=JCCompilationUnit

在Example 10中我发现JCCompilationUnit是TreePath中获取的,于是我知道TreePath又是由element获取来的

_trees = Trees.instance(processingEnv);
TreePath treePath = _trees.getPath(element)

最终代码:

    private void addImportInfo(Element element) {
        TreePath treePath = _trees.getPath(element);
        Tree leaf = treePath.getLeaf();
        if (treePath.getCompilationUnit() instanceof JCTree.JCCompilationUnit && leaf instanceof JCTree) {
            JCTree.JCCompilationUnit jccu = (JCTree.JCCompilationUnit) treePath.getCompilationUnit();

            for (JCTree jcTree : jccu.getImports()) {
                if (jcTree != null && jcTree instanceof JCTree.JCImport) {
                    JCTree.JCImport jcImport = (JCTree.JCImport) jcTree;
                    if (jcImport.qualid != null && jcImport.qualid instanceof JCTree.JCFieldAccess) {
                        JCTree.JCFieldAccess jcFieldAccess = (JCTree.JCFieldAccess) jcImport.qualid;
                        try {
                            if (TRACKER_PACKAGE.equals(jcFieldAccess.selected.toString()) && TRACKER_CLASS.equals(jcFieldAccess.name.toString())) {
                                return;
                            }
                        } catch (NullPointerException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            java.util.List<JCTree> trees = new ArrayList<>();
            trees.addAll(jccu.defs);
            JCTree.JCIdent ident = _maker.Ident(_names.fromString(TRACKER_PACKAGE));
            JCTree.JCImport jcImport = _maker.Import(_maker.Select(
                    ident, _names.fromString(TRACKER_CLASS)), false);
            if (!trees.contains(jcImport)) {
                trees.add(0, jcImport);
            }
            jccu.defs = List.from(trees);
        }
    }

这里的Element.getKind == ElementKind.CLASS

这样就可以看到你对应的import代码加进去了,这是我的分析过程可能有点啰嗦,将就着看吧。

项目地址github地址

评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值