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
}
關于如何操作AST請看抽象語法樹AST的全面分析(三)