JCTree类(com.sun.tools.javac.tree.JCTree)的简要分析
上一篇文章讲解了抽象语法树的来源和获取时机,接下来要分析一下抽象语法树的内部结构。
抽象语法树由JCTree的内部类(如JCCompilationUnit,JCClassDecl,JCMethodDecl等)作为语法节点构成。我们可以通过调用JCTree的accept()方法来访问抽象语法树的所有语法节点。
public abstract void accept(JCTree.Visitor var1);
accept()方法接收一个JCTree.Visitor的参数,通过执行这个方法,我们可以在Visitor类中获取到抽象语法树所有语法节点的数据。
Visitor
- 抽象内部类,内部定义了访问各种语法节点的方法,获取到对应的语法节点后我们可以对语法节点增加删除或者修改语句;
- Visitor派生子类有TreeScanner(扫描所有的语法节点)和TreeTranslator(扫描节点且可以把语法节点转换成另一种语法节点);
public abstract static class Visitor {
//访问类节点
public void visitClassDef(JCTree.JCClassDecl var1) {
this.visitTree(var1);
}
//访问方法节点
public void visitMethodDef(JCTree.JCMethodDecl var1) {
this.visitTree(var1);
}
//访问变量节点
public void visitVarDef(JCTree.JCVariableDecl var1) {
this.visitTree(var1);
}
//访问skip节点
public void visitSkip(JCTree.JCSkip var1) {
this.visitTree(var1);
}
//访问代码块节点
public void visitBlock(JCTree.JCBlock var1) {
this.visitTree(var1);
}
//访问doWhild循环
public void visitDoLoop(JCTree.JCDoWhileLoop var1) {
this.visitTree(var1);
}
//访问whild循环
public void visitWhileLoop(JCTree.JCWhileLoop var1) {
this.visitTree(var1);
}
//访问for循环
public void visitForLoop(JCTree.JCForLoop var1) {
this.visitTree(var1);
}
//访问forEach循环
public void visitForeachLoop(JCTree.JCEnhancedForLoop var1) {
this.visitTree(var1);
}
//访问switch
public void visitSwitch(JCTree.JCSwitch var1) {
this.visitTree(var1);
}
//访问case
public void visitCase(JCTree.JCCase var1) {
this.visitTree(var1);
}
//访问同步关键字
public void visitSynchronized(JCTree.JCSynchronized var1) {
this.visitTree(var1);
}
//访问try
public void visitTry(JCTree.JCTry var1) {
this.visitTree(var1);
}
//访问catch
public void visitCatch(JCTree.JCCatch var1) {
this.visitTree(var1);
}
//访问三目运算符表达式
public void visitConditional(JCTree.JCConditional var1) {
this.visitTree(var1);
}
//访问if语句
public void visitIf(JCTree.JCIf var1) {
this.visitTree(var1);
}
//访问break语句
public void visitBreak(JCTree.JCBreak var1) {
this.visitTree(var1);
}
//访问continue语句
public void visitContinue(JCTree.JCContinue var1) {
this.visitTree(var1);
}
//访问return语句
public void visitReturn(JCTree.JCReturn var1) {
this.visitTree(var1);
}
//访问异常抛出表达式节点
public void visitThrow(JCTree.JCThrow var1) {
this.visitTree(var1);
}
//访问方法调用节点
public void visitApply(JCTree.JCMethodInvocation var1) {
this.visitTree(var1);
}
//访问new对象语句节点
public void visitNewClass(JCTree.JCNewClass var1) {
this.visitTree(var1);
}
//访问new数组语句节点
public void visitNewArray(JCTree.JCNewArray var1) {
this.visitTree(var1);
}
//访问赋值语句节点
public void visitAssign(JCTree.JCAssign var1) {
this.visitTree(var1);
}
//访问赋值操作语句节点
public void visitAssignop(JCTree.JCAssignOp var1) {
this.visitTree(var1);
}
//访问赋值操作语句节点
public void visitUnary(JCTree.JCUnary var1) {
this.visitTree(var1);
}
//访问一元运算节点
public void visitBinary(JCTree.JCBinary var1) {
this.visitTree(var1);
}
//访问对其他类的方法调用或者变量调用节点
public void visitSelect(JCTree.JCFieldAccess var1) {
this.visitTree(var1);
}
//访问标识符
public void visitIdent(JCTree.JCIdent var1) {
this.visitTree(var1);
}
//访问字面量,可以是数字1,字符串"x"
public void visitLiteral(JCTree.JCLiteral var1) {
this.visitTree(var1);
}
//获取访问修饰符
public void visitModifiers(JCTree.JCModifiers var1) {
this.visitTree(var1);
}
}
JCStatement
声明语句,继承JCStatement都是声明语句,子类有:
JCBlock、JCReturn、JCClassDecl、JCVariableDecl、JCTry、JCThrow等;
JCExpression
表达式语句,继承JCExpression都是表达式语句,子类有:
JCAssign,JCBinary,JCBreak,JCFieldAccess,JCIdent,JCLiteral等;
JCClassDecl
类定义
public static class JCClassDecl extends JCTree.JCStatement implements ClassTree {
public JCTree.JCModifiers mods;//访问修饰符 比如public, final
public Name name;//类名
public List<JCTree.JCTypeParameter> typarams;//泛型参数列表
public JCTree.JCExpression extending;//父类
public List<JCTree.JCExpression> implementing;//接口列表
public List<JCTree> defs;//变量,方法定义列表
public ClassSymbol sym;//包名+类名
}
JCMethodDecl
方法定义
public static class JCMethodDecl extends JCTree implements MethodTree {
public JCTree.JCModifiers mods;//访问修饰符 比如public, final,static
public Name name;//方法名
public JCTree.JCExpression restype;//返回类型
public List<JCTree.JCTypeParameter> typarams;//泛型参数列表
public JCTree.JCVariableDecl recvparam;//null
public List<JCTree.JCVariableDecl> params;//方法参数列表
public List<JCTree.JCExpression> thrown;//异常抛出列表
public JCTree.JCBlock body;//方法体
public JCTree.JCExpression defaultValue;//注解类的方法需要的defaultValue
public MethodSymbol sym;//方法名+ (参数类型),如:setName(java.lang.String)
}
JCVariableDecl
变量定义
public static class JCVariableDecl extends JCTree.JCStatement implements VariableTree {
public JCTree.JCModifiers mods;//访问修饰符 比如public, final,static
public Name name;//变量名
public JCTree.JCExpression nameexpr;//null
public JCTree.JCExpression vartype;//变量的类型
public JCTree.JCExpression init;//初始化值
public VarSymbol sym;//变量名
}
-->创建变量: private x = 1;
treeMaker.VarDef(treeMaker.Modifiers(Flags.PRIVATE), names.fromString"x", treeMaker.TypeIdent(TypeTag.INT), treeMaker.Literal(1));
JCModifiers
访问修饰符
public static class JCModifiers extends JCTree implements ModifiersTree {
public long flags;//访问标志,例如:public,private,static
public List<JCTree.JCAnnotation> annotations;//注解列表
}
-->flag通常用Flags(com.sun.tools.javac.code.Flags)类的常量来表示
public class Flags {
public static final int PUBLIC = 1;
public static final int PRIVATE = 2;
public static final int PROTECTED = 4;
public static final int STATIC = 8;
public static final int FINAL = 16;
public static final int SYNCHRONIZED = 32;
public static final int VOLATILE = 64;
public static final int TRANSIENT = 128;
public static final int NATIVE = 256;
...
}
-->创建例子:public
treeMaker.Modifiers(Flags.PUBLIC);
JCBlock
代码块
public static class JCBlock extends JCTree.JCStatement implements BlockTree {
public long flags;//访问修复符
public List<JCTree.JCStatement> stats;//多行代码列表
}
-->使用例子:
List<JCTree.JCStatement> jcStatementList = List.nil();
treeMaker.Block(0, jcStatementList);//构建代码块
JCIdent
标识符表达式,可以表示类、变量引用或者方法。
public static class JCIdent extends JCTree.JCExpression implements IdentifierTree {
public Name name;//标识符的名字
public Symbol sym;//代表类时为包名+类名,代表其他类型数据时为null
protected JCIdent(Name var1, Symbol var2) {
this.name = var1;
this.sym = var2;
}
}
-->创建实例: 获取变量textView的引用
treeMaker.Ident(names.fromString("textView"))))
JCFieldAccess
其他类的变量、方法的访问表达式
public static class JCFieldAccess extends JCTree.JCExpression implements MemberSelectTree {
public JCTree.JCExpression selected;//类访问表达式
public Name name;//变量名或方法名
public Symbol sym;
}
JCLiteral
字面量表达式
public static class JCLiteral extends JCTree.JCExpression implements LiteralTree {
public TypeTag typetag;//常量的类型
public Object value;//常量的值
}
-->
字面量类型的枚举类
public enum TypeTag {
BYTE(1, 125, true),
CHAR(2, 122, true),
SHORT(4, 124, true),
LONG(16, 112, true),
FLOAT(32, 96, true),
INT(8, 120, true),
DOUBLE(64, 64, true),
BOOLEAN(0, 0, true),
CLASS,
...
}
-->使用例子:闭括号字符串"}"
treeMaker.Literal("}")
JCBinary
二元操作符
public static class JCBinary extends JCTree.JCExpression implements BinaryTree {
private JCTree.Tag opcode;//操作符
public JCTree.JCExpression lhs;//操作符左边
public JCTree.JCExpression rhs;//操作符右边
public Symbol operator;//null
}
-->二元运算符opcode可取值
public static enum Tag {
OR, // ||
AND, // &&
BITOR, // |
BITXOR, // ^
BITAND, // &
EQ, // ==
NE, // !=
LT, // <
GT, // >
LE, // <=
GE, // >=
SL, // <<
SR, // >>
USR, // >>>
PLUS, // +
MINUS, // -
MUL, // *
DIV, // /
MOD, // %
}
-->创建例子 : 1 + 1
treeMaker.Binary(JCTree.Tag.PLUS, treeMaker.Literal(1), treeMaker.Literal(1));
JCReturn
return语句
public static class JCReturn extends JCTree.JCStatement implements ReturnTree {
public JCTree.JCExpression expr;//返回语句的结果字段
}
-->例子:retrun this.xxx
treeMaker.Return(treeMaker.Select(treeMaker.Ident(names.fromString("this")),names.fromString("xxx")));
JCAssign
赋值语句
public static class JCAssign extends JCTree.JCExpression implements AssignmentTree {
public JCTree.JCExpression lhs;//赋值语句左边表达式
public JCTree.JCExpression rhs;//赋值语句右边表达式
}
-->例子:x = 1
treeMaker.Assign(treeMaker.Ident(names.fromString("x")))), treeMaker.Literal(1))
JCAssignOp
赋值语句
public static class JCAssignOp extends JCTree.JCExpression implements CompoundAssignmentTree {
private JCTree.Tag opcode;
public JCTree.JCExpression lhs;
public JCTree.JCExpression rhs;
public Symbol operator;
}
-->opcode可取值
public static enum Tag {
BITOR_ASG(BITOR), // |=
BITXOR_ASG(BITXOR), // ^=
BITAND_ASG(BITAND), // &=
SL_ASG(SL), // <<=
SR_ASG(SR), // >>=
USR_ASG(USR), // >>>=
PLUS_ASG(PLUS), // +=
MINUS_ASG(MINUS), // -=
MUL_ASG(MUL), // *=
DIV_ASG(DIV), // /=
MOD_ASG(MOD), // %=
}
-->例子:x += 1
treeMaker.AssignOp(JCTree.Tag.PLUS_ASG, treeMaker.Ident(names.fromString("x")))), treeMaker.Literal(1))
JCIf
if代码块; if(condition) {thenpart} else {elsepart}
public static class JCIf extends JCTree.JCStatement implements IfTree {
public JCTree.JCExpression cond;//条件语句
public JCTree.JCStatement thenpart;//if的操作语句
public JCTree.JCStatement elsepart;//else的操作语句
}
JCForLoop
for循环代码块;for (init; cond; step) {body}
public static class JCForLoop extends JCTree.JCStatement implements ForLoopTree {
public List<JCTree.JCStatement> init;
public JCTree.JCExpression cond;
public List<JCTree.JCExpressionStatement> step;
public JCTree.JCStatement body;
}
JCTry、JCCatch
try、catch和finally代码块;
public static class JCTry extends JCTree.JCStatement implements TryTree {
public JCTree.JCBlock body;//try代码块
public List<JCTree.JCCatch> catchers;//JCCatch
public JCTree.JCBlock finalizer;//final代码块
public List<JCTree> resources;//List.nil(),用不上的字段
public boolean finallyCanCompleteNormally;//
}
-->JCCatch
public static class JCCatch extends JCTree implements CatchTree {
public JCTree.JCVariableDecl param;//catch的异常类型
public JCTree.JCBlock body;//catch代码块
}
JCMethodInvocation
方法调用表达式
public static class JCMethodInvocation extends JCTree.JCPolyExpression implements MethodInvocationTree {
public List<JCTree.JCExpression> typeargs;//参数类型列表
public JCTree.JCExpression meth;//方法的调用语句,比如Log.i,setContentView
public List<JCTree.JCExpression> args;//参数列表
public Type varargsElement;//null
}
JCDoWhileLoop
doWhile循环 ; do(body)while(cond)
public static class JCDoWhileLoop extends JCTree.JCStatement implements DoWhileLoopTree {
public JCTree.JCStatement body;//do代码块
public JCTree.JCExpression cond;//条件语句
}
JCEnhancedForLoop
增强for循环 ; for(var : expr){body}
public static class JCEnhancedForLoop extends JCTree.JCStatement implements EnhancedForLoopTree {
public JCTree.JCVariableDecl var;
public JCTree.JCExpression expr;
public JCTree.JCStatement body;//代码块
}
JCThrow
异常抛出
public static class JCThrow extends JCTree.JCStatement implements ThrowTree {
public JCTree.JCExpression expr;//异常表达式
}
-->例子:throw Exception
treeMaker.Throw(treeMaker.Ident(names.fromString("Exception")));
JCSwitch,JCCase
switch代码块;switch(selector) {case pat : stats}
public static class JCSwitch extends JCTree.JCStatement implements SwitchTree {
public JCTree.JCExpression selector;//判断条件
public List<JCTree.JCCase> cases;//多个case
}
public static class JCCase extends JCTree.JCStatement implements CaseTree {
public JCTree.JCExpression pat;//case逻辑表达式
public List<JCTree.JCStatement> stats;//代码执行语句
}
JCConditional
三目运算表达式,cond ? truepart : falsepart
public static class JCConditional extends JCTree.JCPolyExpression implements ConditionalExpressionTree {
public JCTree.JCExpression cond;//判断条件
public JCTree.JCExpression truepart;//判断为真时执行的表达式
public JCTree.JCExpression falsepart;//判断为假时执行的表达式
}
JCSkip
空操作,即一个无效的分号 ";"
JCUnary
一元运算表达式,
public static class JCUnary extends JCTree.JCExpression implements UnaryTree {
private JCTree.Tag opcode;//操作运算符
public JCTree.JCExpression arg;//
}
public static enum Tag {
POS, // +
NEG, // -
NOT, // !
COMPL, // ~
PREINC, // ++ _;例子:++i
PREDEC, // -- _; 例子:--i
POSTINC, // _ ++; 例子:i++
POSTDEC, // _ --; 例子:i--
}
-->例子:i++;
treeMaker.Unary(JCTree.Tag.POSTINC, treeMaker.Ident(names.fromString("i")));
JCContinue
continue,跳过本次循环, continue label
public static class JCContinue extends JCTree.JCStatement implements ContinueTree {
public Name label;//label标签
public JCTree target;//null
}
JCBreak
break,跳出循环, break label
public static class JCBreak extends JCTree.JCStatement implements BreakTree {
public Name label;//label标签
public JCTree target;//null
}
作者:zl_adams
链接:https://www.jianshu.com/p/4bd5dc13f35a