知识点汇总:如何修改Java的抽象语法树?

在网上关于如何修改Java的抽象语法树的相关API文档并不多,于是本篇记录一下相关的知识点,以便随后查阅。

JCTree的介绍

JCTree是语法树元素的基类,包含一个重要的字段pos,该字段用于指明当前语法树节点(JCTree)在语法树中的位置,因此我们不能直接用new关键字来创建语法树节点,即使创建了也没有意义。

此外,结合访问者模式,将数据结构与数据的处理进行解耦,部分源码如下:

public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
     public int pos = -1;
     ...
     public abstract void accept(JCTree.Visitor visitor);
     ...
}

我们可以看到JCTree是一个抽象类,这里重点介绍几个JCTree的子类

1、JCStatement:声明语法树节点,常见的子类如下:

JCBlock:语句块语法树节点

JCReturn:return语句语法树节点

JCClassDecl:类定义语法树节点

JCVariableDecl:字段/变量定义语法树节点

2、JCMethodDecl:方法定义语法树节点

3、JCModifiers:访问标志语法树节点

4、JCExpression:表达式语法树节点,常见的子类如下

JCAssign:赋值语句语法树节点

JCIdent:标识符语法树节点,可以是变量,类型,关键字等等

TreeMaker介绍

TreeMaker用于创建一系列的语法树节点,我们上面说了创建JCTree不能直接使用new关键字来创建,所以Java为我们提供了一个工具,就是TreeMaker,它会在创建时为我们创建的JCTree对象设置pos字段,所以必须使用上下文相关的TreeMaker对象来创建语法树节点。

接下来着重介绍一下常用的几个方法。

TreeMaker.Modifiers

TreeMaker.Modifiers方法用于创建访问标志语法树节点(JCModifiers),源码如下

public JCModifiers Modifiers(long flags) {
    return Modifiers(flags, List.< JCAnnotation >nil());
 }

 public JCModifiers Modifiers(long flags,
     List<JCAnnotation> annotations) {
         JCModifiers tree = new JCModifiers(flags, annotations);
         boolean noFlags = (flags & (Flags.ModifierFlags | Flags.ANNOTATION)) == 0;
         tree.pos = (noFlags && annotations.isEmpty()) ? Position.NOPOS : pos;
        return tree;
}

flags:访问标志

annotations:注解列表

其中flags可以使用枚举类com.sun.tools.javac.code.Flags来表示,例如我们可以这样用,就生成了下面的访问标志了。

treeMaker.Modifiers(Flags.PUBLIC + Flags.STATIC + Flags.FINAL);
​
public static final
TreeMaker.ClassDef

TreeMaker.ClassDef用于创建类定义语法树节点(JCClassDecl),源码如下:

public JCClassDecl ClassDef(JCModifiers mods,
    Name name,
    List<JCTypeParameter> typarams,
    JCExpression extending,
    List<JCExpression> implementing,
    List<JCTree> defs) {
        JCClassDecl tree = new JCClassDecl(mods,
                                     name,
                                     typarams,
                                     extending,
                                     implementing,
                                     defs,
                                     null);
        tree.pos = pos;
        return tree;
}

mods:访问标志,可以通过TreeMaker.Modifiers来创建

name:类名

typarams:泛型参数列表

extending:父类

implementing:实现的接口

defs:类定义的详细语句,包括字段、方法的定义等等

TreeMaker.MethodDef

TreeMaker.MethodDef用于创建方法定义语法树节点(JCMethodDecl),源码如下

public JCMethodDecl MethodDef(JCModifiers mods,
    Name name,
    JCExpression restype,
    List<JCTypeParameter> typarams,
    List<JCVariableDecl> params,
    List<JCExpression> thrown,
    JCBlock body,
    JCExpression defaultValue) {
        JCMethodDecl tree = new JCMethodDecl(mods,
                                       name,
                                       restype,
                                       typarams,
                                       params,
                                       thrown,
                                       body,
                                       defaultValue,
                                       null);
       tree.pos = pos;
       return tree;
}
​
public JCMethodDecl MethodDef(MethodSymbol m,
    Type mtype,
    JCBlock body) {
        return (JCMethodDecl)
            new JCMethodDecl(
                Modifiers(m.flags(), Annotations(m.getAnnotationMirrors())),
                m.nam
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值