轉載:抽象語法樹AST的全面解析(二)

上篇文章:juejin.im/post/5d9096…java

類JCTree(com.sun.tools.javac.tree.JCTree)簡要分析

抽象語法樹由JCTree的內部類(如JCCompilationUnit,JCClassDecl,JCMethodDecl等)做爲語法節點構成。咱們能夠經過調用JCTree的accept()方法來訪問抽象語法樹的全部語法節點。數組

public abstract void accept(JCTree.Visitor var1)複製代碼

accept()方法接收一個JCTree.Visitor的參數,經過執行這個方法,咱們能夠在Visitor類中獲取到抽象語法樹全部語法節點的數據。oop

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等;post

JCExpression

表達式語句,繼承JCExpression都是表達式語句,子類有: JCAssign,JCBinary,JCBreak,JCFieldAccess,JCIdent,JCLiteral等;this

JCClassDecl

類定義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;//包名+類名
}
複製代碼

JCMethodDecl

方法定義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)
}
複製代碼

JCVariableDecl

變量定義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));
複製代碼

JCModifiers

訪問修飾符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);
複製代碼

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;//
}

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
}
複製代碼

原文地址:www.jianshu.com/p/4bd5dc13f…

相關文章
相關標籤/搜索