上篇文章:juejin.im/post/5d9096…java
抽象語法樹由JCTree的內部類(如JCCompilationUnit,JCClassDecl,JCMethodDecl等)做爲語法節點構成。咱們能夠經過調用JCTree的accept()方法來訪問抽象語法樹的全部語法節點。數組
public abstract void accept(JCTree.Visitor var1); 複製代碼
accept()方法接收一個JCTree.Visitor的參數,經過執行這個方法,咱們能夠在Visitor類中獲取到抽象語法樹全部語法節點的數據。oop
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都是聲明語句,子類有: JCBlock、JCReturn、JCClassDecl、JCVariableDecl、JCTry、JCThrow等;post
表達式語句,繼承JCExpression都是表達式語句,子類有: JCAssign,JCBinary,JCBreak,JCFieldAccess,JCIdent,JCLiteral等;this
類定義spa
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;//包名+類名
}
複製代碼
方法定義rest
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)
}
複製代碼
變量定義code
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));
複製代碼
訪問修飾符orm
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);
複製代碼
代碼塊對象
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);//構建代碼塊
複製代碼
標識符表達式,能夠表示類、變量引用或者方法。
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"))))
複製代碼
其餘類的變量、方法的訪問表達式
public static class JCFieldAccess extends JCTree.JCExpression implements MemberSelectTree {
public JCTree.JCExpression selected;//類訪問表達式
public Name name;//變量名或方法名
public Symbol sym;
}
複製代碼
字面量表達式
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("}")
複製代碼
二元操做符
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));
複製代碼
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")));
複製代碼
賦值語句
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))
複製代碼
賦值語句
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))
複製代碼
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的操做語句
}
複製代碼
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;
}
複製代碼
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;//
}
public static class JCCatch extends JCTree implements CatchTree {
public JCTree.JCVariableDecl param;//catch的異常類型
public JCTree.JCBlock body;//catch代碼塊
}
複製代碼
方法調用表達式
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
}
複製代碼
doWhile循環 ; do(body)while(cond)
public static class JCDoWhileLoop extends JCTree.JCStatement implements DoWhileLoopTree {
public JCTree.JCStatement body;//do代碼塊
public JCTree.JCExpression cond;//條件語句
}
複製代碼
加強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;//代碼塊
}
複製代碼
異常拋出
public static class JCThrow extends JCTree.JCStatement implements ThrowTree {
public JCTree.JCExpression expr;//異常表達式
}
-->例子:throw Exception
treeMaker.Throw(treeMaker.Ident(names.fromString("Exception")));
複製代碼
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;//代碼執行語句
}
複製代碼
三目運算表達式,cond ? truepart : falsepart
public static class JCConditional extends JCTree.JCPolyExpression implements ConditionalExpressionTree {
public JCTree.JCExpression cond;//判斷條件
public JCTree.JCExpression truepart;//判斷爲真時執行的表達式
public JCTree.JCExpression falsepart;//判斷爲假時執行的表達式
}
複製代碼
空操做,即一個無效的分號 ";"
一元運算表達式
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")));
複製代碼
continue,跳過本次循環, continue label
public static class JCContinue extends JCTree.JCStatement implements ContinueTree {
public Name label;//label標籤
public JCTree target;//null
}
複製代碼
break,跳出循環, break label
public static class JCBreak extends JCTree.JCStatement implements BreakTree {
public Name label;//label標籤
public JCTree target;//null
}
複製代碼