编译期修改 AST,实现对类的增强

JCTree

抽象语法树(Abstract Syntax Tree)语法分析分析出来的树结构是由 JCTree 来表示的,语法树的每一个节点都代表着程序代码中的一个语法结构,例如包、类型、修饰符、运算符、接口、返回值、代码注释等都是一个语法结构。

JCTree 子类

JCAnnotatedType

被注解的泛型:(注解的 Target 为ElementType.TYPE_USE时可注解泛型)

public static class A <T extends @Reality String> {
}
protected JCAnnotatedType(List<JCAnnotation> annotations, JCExpression underlyingType) {
    Assert.check(annotations != null && annotations.nonEmpty());
    this.annotations = annotations;
    this.underlyingType = underlyingType;
}

JCAnnotation

注解:@annotationType(args)

@Reality(callSuper = false)
protected JCAnnotation(Tag tag, JCTree annotationType, List<JCExpression> args) {
    this.tag = tag;
    this.annotationType = annotationType;
    this.args = args;
}

JCArrayAccess

数组访问:a[0]

protected JCArrayAccess(JCExpression indexed, JCExpression index) {
    this.indexed = indexed;
    this.index = index;
}

JCArrayTypeTree

数组类型

String[]
protected JCArrayTypeTree(JCExpression elemtype) {
    this.elemtype = elemtype;
}

JCAssert

assert 断言

protected JCAssert(JCExpression cond, JCExpression detail) {
    this.cond = cond;
    this.detail = detail;
}

JCAssign

赋值:lhs = rhs 例如 i = 1

protected JCAssign(JCExpression lhs, JCExpression rhs) {
    this.lhs = lhs;
    this.rhs = rhs;
}

JCAssignOp

赋值:lhs 操作= rhs 例如 i += 1

protected JCAssignOp(Tag opcode, JCTree lhs, JCTree rhs, Symbol operator) {
    this.opcode = opcode;
    this.lhs = (JCExpression)lhs;
    this.rhs = (JCExpression)rhs;
    this.operator = operator;
}

操作符可选值:

 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),                    // %=

JCBinary

二叉结构的语句

protected JCBinary(Tag opcode, JCExpression lhs, JCExpression rhs, Symbol operator) {
    this.opcode = opcode;
    this.lhs = lhs;
    this.rhs = rhs;
    this.operator = operator;
}
double i = d + i * f

第一个 JCBinary 为:

opcode = PLUS, lhs = d, rhs = i * f, operator = null

第二个 JCBinary 为:

opcode = MUL, lhs = i, rhs = f, operator = null

操作符可选值:

OR,                              // ||
AND,                             // &&
BITOR,                           // |
BITXOR,                          // ^
BITAND,                          // &
EQ,                              // ==
NE,                              // !=
LT,                              // <
GT,                              // >
LE,                              // <=
GE,                              // >=
SL,                              // <<
SR,                              // >>
USR,                             // >>>
PLUS,                            // +
MINUS,                           // -
MUL,                             // *
DIV,                             // /
MOD,                             // %s

JCBlock

语句块

{
    ...
}
//或
static {
    ...
}
protected JCBlock(long flags, List<JCStatement> stats) {
    this.stats = stats;
    this.flags = flags;
}

JCCase

case语句:case pat : stats

protected JCCase(JCExpression pat, List<JCStatement> stats) {
    this.pat = pat;
    this.stats = stats;
}

JCCatch

catch捕捉异常:catch(param) bodys

protected JCCatch(JCVariableDecl param, JCBlock body) {
    this.param = param;
    this.body = body;
}

JCClassDecl

类的定义

@Reality
public class MainActivity extends AppCompatActivity {

    private static int kk = 1;

    static {
        kk = 2;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}
protected JCClassDecl(JCModifiers mods,
                   Name name,
                   List<JCTypeParameter> typarams,
                   JCExpression extending,
                   List<JCExpression> implementing,
                   List<JCTree> defs,
                   ClassSymbol sym)
{
    this.mods = mods;
    this.name = name;
    this.typarams = typarams;
    this.extending = extending;
    this.implementing = implementing;
    this.defs = defs;
    this.sym = sym;
}

JCCompilationUnit

protected JCCompilationUnit(List<JCAnnotation> packageAnnotations,
                JCExpression pid,
                List<JCTree> defs,
                JavaFileObject sourcefile,
                PackageSymbol packge,
                ImportScope namedImportScope,
                StarImportScope starImportScope) {
    this.packageAnnotations = packageAnnotations;
    this.pid = pid;
    this.defs = defs;
    this.sourcefile = sourcefile;
    this.packge = packge;
    this.namedImportScope = namedImportScope;
    this.starImportScope = starImportScope;
}

JCConditional

三目运算符:cond ? truepart : falsepart 例如 a ? 1 : 3

 protected JCConditional(JCExpression cond, JCExpression truepart, JCExpression falsepart)
 {
     this.cond = cond;
     this.truepart = truepart;
     this.falsepart = falsepart;
 }

JCContinue

continue跳过一次循环,continue label

protected JCContinue(Name label, JCTree target) {
    this.label = label;
    this.target = target;
}

JCDoWhileLoop

do-while循环

do {
    body
} while (cond)
protected JCDoWhileLoop(JCStatement body, JCExpression cond) {
    this.body = body;
    this.cond = cond;
}

JCEnhancedForLoop

增强循环

for (String s : list) {
    System.out.println(s);
}
protected JCEnhancedForLoop(JCVariableDecl var, JCExpression expr, JCStatement body) {
    this.var = var;
    this.expr = expr;
    this.body = body;
}

JCExpression

表达式,赋值、调用方法等都算一个表达式,凡是继承 JCExpression 都算一个表达式

JCExpressionStatement

内部封装了 JCExpression,实际上还是个表达式

JCFieldAccess

访问父类、其他类的变量时

this.age

JCForloop

for 循环

protected JCForLoop(List<JCStatement> init,
                  JCExpression cond,
                  List<JCExpressionStatement> update,
                  JCStatement body)
{
    this.init = init;
    this.cond = cond;
    this.step = update;
    this.body = body;
}

JCFunctionalExpression

函数式表达式:lambda(JCLambda) 和 method reference(JCMemberReference) 继承于JCFunctionalExpression

JCIdent

出现在表达式中的变量名、调用的方法名以及类名等

@Reality //JCIdent Reality ClassSymbol com.juno.annotations.Reality
//JCIdent AppCompatActivity ClassSymbol android.support.v7.app.AppCompatActivity
public class MainActivity extends AppCompatActivity  {

    //JCIdent String ClassSymbol java.lang.String
    private static final String TAG = "MainActivity";
    
    private int kk = 1;

    @Override //JCIdent Override ClassSymbol java.lang.Override
    //JCIdent Bundle ClassSymbol android.os.Bundle
    protected void onCreate(Bundle savedInstanceState) {
    
        //JCIdent super
        //JCIdent savedInstanceState
        super.onCreate(savedInstanceState);
        
        //JCIdent setContentView 
        //JCIdent R
        setContentView(R.layout.activity_main);
        
        TextView textView;
        //JCIdent textView
        //JCIdent findViewById
        //JCIdent R
        textView = findViewById(R.id.text);

        int i = 0;
        int j = 1;
        
        //JCIdent i
        //JCIdent j
        i = j * 3 + 2;
        
        //JCIdent this
        this.kk = 0;
    }
}

JCIf

if 判断语句:if(condition) {thenpart} else {elsepart}

protected JCIf(JCExpression cond, JCStatement thenpart, JCStatement elsepart)
{
    this.cond = cond;
    this.thenpart = thenpart;
    this.elsepart = elsepart;
}

JCImport

import 语句

protected JCImport(JCTree qualid, boolean importStatic) {
    this.qualid = qualid;
    this.staticImport = importStatic;
}

JCInstanceOf

instanceof语句:expr instanceof clazz

textView instanceof View
protected JCInstanceOf(JCExpression expr, JCTree clazz) {
    this.expr = expr;
    this.clazz = clazz;
}

JCLabeledStatement

带有标签的语句:label : body

protected JCLabeledStatement(Name label, JCStatement body) {
    this.label = label;
    this.body = body;
}

JCLambda

lambda 表达式:表达式主体只有一句表达式

v -> v.setVisibility(View.INVISIBLE)

当主体变为语句块时:

v -> { v.setVisibility(View.VISIBLE); }

当参数 v 指明类型为 View 时:

(View v) -> v.setVisibility(View.INVISIBLE)

JCLiteral

表示常量

int a = 1
protected JCLiteral(TypeTag typetag, Object value) {
    this.typetag = typetag;
    this.value = value;
}

Tag 可选值有

INT,                      //int
LONG,                     //long
FLOAT,                    //float
DOUBLE,                   //double
CHAR,                     //char
CLASS,                    //String
BOT,                      //null

JCMemberReference

lambda 表达式中的方法引用:expr::name

ObjectUtil::new
this::util
protected JCMemberReference(ReferenceMode mode, 
                            Name name, 
                            JCExpression expr, 
                            List<JCExpression> typeargs) {
    this.mode = mode;
    this.name = name;
    this.expr = expr;
    this.typeargs = typeargs;
}

JCMethodDecl

方法的定义

@Reality
private static <T extends String> int print(@NonNull final String s) throws RuntimeException {
    Log.e(TAG, s);
    return 1;
}
@Reality
@interface B {
    int value() default 1;
}
protected JCMethodDecl(JCModifiers mods,
                    Name name,
                    JCExpression restype,
                    List<JCTypeParameter> typarams,
                    JCVariableDecl recvparam,
                    List<JCVariableDecl> params,
                    List<JCExpression> thrown,
                    JCBlock body,
                    JCExpression defaultValue,
                    MethodSymbol sym)
{
    this.mods = mods;
    this.name = name;
    this.restype = restype;
    this.typarams = typarams;
    this.params = params;
    this.recvparam = recvparam;
    // TODO: do something special if the given type is null?
    // receiver != null ? receiver : List.<JCTypeAnnotation>nil());
    this.thrown = thrown;
    this.body = body;
    this.defaultValue = defaultValue;
    this.sym = sym;
}

JCMethodinvocation

方法执行语句

notNull(before)
proxy.invoke(target, method, args)
protected JCMethodInvocation(List<JCExpression> typeargs,
                JCExpression meth,
                List<JCExpression> args) {
    this.typeargs = (typeargs == null) ? List.<JCExpression>nil() : typeargs;
    this.meth = meth;
    this.args = args;
}

JCModifiers

类、变量、方法等的修饰符和注解

@Reality private static final String TAG = "MainActivity";
protected JCModifiers(long flags, List<JCAnnotation> annotations) {
    this.flags = flags;
    this.annotations = annotations;
}

flag 的可选值,位于 Flags 类中

int PUBLIC       = 1;
int PRIVATE      = 1<<1;
int PROTECTED    = 1<<2;
int STATIC       = 1<<3;
int FINAL        = 1<<4;
int SYNCHRONIZED = 1<<5;
int VOLATILE     = 1<<6;
int TRANSIENT    = 1<<7;
int NATIVE       = 1<<8;
int INTERFACE    = 1<<9;
int ABSTRACT     = 1<<10;
int STRICTFP     = 1<<11;

JCNewArray

new 数组

new String[]{"123","456"}
new B[3][4]
protected JCNewArray(JCExpression elemtype, List<JCExpression> dims, List<JCExpression> elems) {
    this.elemtype = elemtype;
    this.dims = dims;
    this.annotations = List.nil();
    this.dimAnnotations = List.nil();
    this.elems = elems;
}

JCNewClass

new 一个对象

new B<String>("123")
protected JCNewClass(JCExpression encl,
                   List<JCExpression> typeargs,
                   JCExpression clazz,
                   List<JCExpression> args,
                   JCClassDecl def) {
    this.encl = encl;
    this.typeargs = (typeargs == null) ? List.<JCExpression>nil() : typeargs;
    this.clazz = clazz;
    this.args = args;
    this.def = def;
}

JCParens

括号:(expr) 存在于if、计算式、synchronized中

protected JCParens(JCExpression expr) {
    this.expr = expr;
}

JCPrimitiveTypeTree

基本类型

TypeTag 可选值

INT,
LONG,
FLOAT,
DOUBLE,
DOOLEAN,
CHAR,
BYTE,
SHORT,
VOID,

JCReturn

return语句:return expr

protected JCReturn(JCExpression expr) {
    this.expr = expr;
}

JCSkip

空操作,即一个无效的分号 “;”

JCStatement

声明,凡是继承JCStatement都是一个声明,在JCBlock中拿到的都是JCStatement,想在JCBlock中拿到JCExpression就用JCExpressionStatement

JCSWitch

switch 语句:switch(selector) { cases }

protected JCSwitch(JCExpression selector, List<JCCase> cases) {
    this.selector = selector;
    this.cases = cases;
}

JCSynchronized

synchronized同步锁:synchronized( lock ) { block }

protected JCSynchronized(JCExpression lock, JCBlock body) {
    this.lock = lock;
    this.body = body;
}

JCThrow

抛出异常:throw expr

protected JCThrow(JCExpression expr) {
    this.expr = expr;
}

JCTry

try块:try body catchers finally finalizer

protected JCTry(List<JCTree> resources, JCBlock body, List<JCCatch> catchers, JCBlock finalizer) {
    this.body = body;
    this.catchers = catchers;
    this.finalizer = finalizer;
    this.resources = resources;
}

JCTypeApply

泛型参数

List<String> list = new ArrayList<>()

对于List<String> list

对于new ArrayList<>()

protected JCTypeApply(JCExpression clazz, List<JCExpression> arguments) {
    this.clazz = clazz;
    this.arguments = arguments;
}

JCTypeCast

类型转换:(clazz)expr

((TextView) findViewById(R.id.text))
(TextView) textView
protected JCTypeCast(JCTree clazz, JCExpression expr) {
    this.clazz = clazz;
    this.expr = expr;
}

JCTypeIntersection

泛型交叉

public static class A<T extends String & Runnable> {
}
protected JCTypeIntersection(List<JCExpression> bounds) {
    this.bounds = bounds;
}

JCTypeParameter

类的泛型定义:class

<T extends View>
protected JCTypeParameter(Name name, List<JCExpression> bounds, List<JCAnnotation> annotations) {
    this.name = name;
    this.bounds = bounds;
    this.annotations = annotations;
}

JCTypeUnion

catch 块中异常的或定义:T1 T2 … Tn
try {
    ...
} catch (ClassCastException | ArrayIndexOutOfBoundsException e) {
    ...
}
protected JCTypeUnion(List<JCExpression> components) {
    this.alternatives = components;
}

JCUnary

一元运算符,例如 i++

protected JCUnary(Tag opcode, JCExpression arg) {
    this.opcode = opcode;
    this.arg = arg;
}

Tag 的可选值

POS,                             // +
NEG,                             // -
NOT,                             // !
COMPL,                           // ~
PREINC,                          // ++ _
PREDEC,                          // -- _
POSTINC,                         // _ ++
POSTDEC,                         // _ --

JCVariableDecl

定义变量

final TextView textView = findViewById(R.id.text)
double i = 1 + 2 * 3
int i = cond ? 0 : 1
protected JCVariableDecl(JCModifiers mods,
                 Name name,
                 JCExpression vartype,
                 JCExpression init,
                 VarSymbol sym) {
    this.mods = mods;
    this.name = name;
    this.vartype = vartype;
    this.init = init;
    this.sym = sym;
}

JCWhileLoop

while循环:while(cond){body}

protected JCWhileLoop(JCExpression cond, JCStatement body) {
    this.cond = cond;
    this.body = body;
}

JCWildcard

泛型中的”?”通配符:? super String

protected JCWildcard(TypeBoundKind kind, JCTree inner) {
    kind.getClass(); // null-check
    this.kind = kind;
    this.inner = inner;
}

BoundKind 可选值

EXTENDS("? extends "),
SUPER("? super "),
UNBOUND("?");

原文

Java AST JCTree简要分析