一、AST

AST  abstract syntax tree (抽象语法结构树),是对java语言的一种抽象,每个节点都能对应到一种java语法,最终一个java文件就是由棵节点树构成

二、Tree

Tree是一个接口,是AST节点的抽象,内部有一个最重要的枚举Kind,定义了java中的每条语句的格式,也是对应着AST的一个节点

以下均为子接口,每个结构都定义了语法节点类型

Tree

  • WildcardTree
  • TypeParameterType
  • StatementTree      (一个完整的语句,比如简单的"int a = 1;",注意最后的“;”)
  • ThrowTree
  • ReturnTree
  • TryTree
  • ContinueTree
  • BreakTree
  • BlockTree
  • DoWhileLoopTree
  • ClassTree
  • VariableTree
  • WhileLoopTree
  • ForLoopTree
  • SwitchTree
  • SynchronizedTree
  • EnhancedForLoopTree
  • LabeedStatementTree
  • AssertTree
  • EmptyStatementTree
  • IfTree
  • ExpressionStatementTree
  • CatchTree
  • MethodTree
  • ArrayTypeTree
  • UnionTypeTree
  • ModifiersTree
  • ParameterizedTypeTree
  • CaseTree
  • ExpressionTree       (一个非完整的语句,比如简单的"a = 1",注意最后没有“;”)
  • MemberReferenceTree
  • LambdaExpressionTree
  • UnaryTree
  • MethodInvocationTree
  • AnnotatedTypeTree
  • CompoundAssignmentTree
  • BinaryTree
  • ErroneousTree
  • MemberSelectTree
  • ArrayAccessTree
  • TypeCastTree
  • NewClassTree
  • ConditionalExpressionTree
  • ParenthesizedTree
  • AnnotationTree
  • NewArrayType
  • InstanceOfTree
  • IdentifierTree
  • AssignmentTree
  • LiteralTree
  • CompilationUnitTree
  • IntersectionTypeTree
  • PrimitiveTypeTree
  • Import

三、Kind

AST 节点类型,对应着java的语法

枚举类型

Tree节点(就是上面列出的接口)

定义

示例

ANNOTATED_TYPE

AnnotatedTypeTree

注解类型,可以用在任何类型上

注解的Target为:TYPE_PARAMETER

TYPE_USE

@NotNull String

ANNOTATION

AnnotationTree

普通的注解

@Data

@JsonProperties(value="sdf")

TYPE_ANNOTATION

AnnotationTree

跟ANNOTATION,待验证有什么区别

ARRAY_ACCESS

ArrayAccessTree

数组访问

array[3]

ARRAY_TYPE

ArrayTypeTree

数组类型

int[]

ASSIGNMENT

AssignmentTree

赋值

a = 1

BLOCK

BlockTree

语句块

{}

{ statements }

static { statements }

BREAK

BreakTree

break

break;

break label;

CASE

CaseTree

case 语句

case expression:statements

default: statements

CATCH

CatchTree

catch 语句

catch(parameter)  block

注:这些语句会有嵌套问题

CLASS

INTERFACE

ENUM

ANNOTATION_TYPE

ClassTree

class 定义

modifiers class simpleName typeParameters

       extends extendsClause

       implements implementsClause

{

   <em>members</em>

}

COMPILATION_UNIT

CompilationUnitTree

一个编译单元

包括源文件和package-info.java

CONDITIONAL_EXPRESSION

ConditionalExpressionTree

三元运算符

a == 1 ? 1 : 0

CONTINUE

ContinueTree

continue 语句

continue;

continue label;

DO_WHILE_LOOP

DoWhileLoopTree

do...while

ENHANCED_FOR_LOOP

EnhancedForLoopTree

增强for

for(int i: intlist) { statement }

EXPRESSION_STATEMENT

ExpressionStatementTree

语句

MEMBER_SELECT

MemberSelectTree

对象.操作

aClass.aparams

MEMBER_REFERENCE

MemberReferenceTree

成员引用表达式

FOR_LOOP

ForLoopTree

for循环

IDENTIFIER

IdentifierTree

识别符,与literal区分开

a = 1

a 就是一个identifier

IF

IfTree

IMPORT

ImportTree

INSTANCE_OF

InstanceOfTree

instanceof 表达式

LABELED_STATEMENT

LabeledStatementTree

label语法

label : statement

METHOD

MethodTree

方法定义

方法

modifiers typeParameters type name (parameters )

   body

 

注解

modifiers type name () default defaultValue

METHOD_INVOCATION

MethodInvocationTree

method invoke语法

MODIFIERS

ModifiersTree

修饰符(Modifier)

包括注解

NEW_ARRAY

NewArrayTree

NEW_CLASS

NewClassTree

LAMBDA_EXPRESSION

LambdaExpressionTree

lambda表达式

PRIMITIVE_TYPE

PrimitiveTypeTree

基础类型

RETURN

ReturnTree

return

EMPTY_STATEMENT

EmptyStatementTree

空的";"

SWITCH

SwitchTree

SYNCHRONIZED

SynchronizedTree

THROW

ThrowTree

TRY

TryTree

PARAMETERIZED_TYPE

ParameterizedTypeTree

泛型

List<Integer>

UNION_TYPE

UnionTypeTree

多变量声明

try {

}catch(Exception e1 | Exception e2){

}

INTERSECTION_TYPE

IntersectionTypeTree

T extends MyA & MyB

TYPE_CAST

TypeCastTree

强转语句

(int)a

TYPE_PARAMETER

TypeParameterTree

VARIABLE

VariableTree

变量

modifiers type name initializer ;

modifiers type qualified-name.this

WHILE_LOOP

WhileLoopTree

POSTFIX_INCREMENT

POSTFIX_DECREMENT

PREFIX_INCREMENT

PREFIX_DECREMENT

UNARY_PLUS

UNARY_MINUS

BITWISE_COMPLEMENT

LOGICAL_COMPLEMENT

UnaryTree

运算符

++、--、+、-、~、!、*、/、%


MULTIPLY

DIVIDE

REMAINDER

PLUS

MINUS

LEFT_SHIFT

RIGHT_SHIFT

UNSIGNED_RIGHT_SHIFT

LESS_THAN

GREATER_THAN

LESS_THAN_EQUAL

GREATER_THAN_EQUAL

EQUAL_TO

NOT_EQUAL_TO

AND

XOR

OR

CONDITIONAL_AND

CONDITIONAL_OR

BinaryTree

两元运算

MULTIPLY_ASSIGNMENT

DIVIDE_ASSIGNMENT

REMAINDER_ASSIGNMENT

PLUS_ASSIGNMENT

MINUS_ASSIGNMENT

LEFT_SHIFT_ASSIGNMENT

RIGHT_SHIFT_ASSIGNMENT

UNSIGNED_RIGHT_SHIFT_ASSIGNMENT

AND_ASSIGNMENT

XOR_ASSIGNMENT

OR_ASSIGNMENT

CompoundAssignmentTree

赋值运算符

+=、-=、*=

INT_LITERAL

LONG_LITERAL

FLOAT_LITERAL

DOUBLE_LITERAL

BOOLEAN_LITERAL

CHAR_LITERAL

STRING_LITERAL

NULL_LITERAL

LiteralTree

字面值

a =  1  (1就是)

OTHER

null

 四、JCTree

com.sun.tools.javac.tree.JCTree 是Tree的一个抽象实现类,有各种实现类,代表着一个个的AST节点

JC具体类

实现Tree

Tag

Kind

备注

LetExpr

LETEXPR

不支持

JCErroneous

ErroneousTree

ERRONEOUS

ERRONEOUS

JCAnnotatedType

AnnotatedTypeTree

ANNOTATED_TYPE

ANNOTATED_TYPE

JCModifiers

ModifiersTree

MODIFIERS

MODIFIERS


JCAnnotation

AnnotationTree


JCTypeParameter

TypeParameterTree

TYPEPARAMETER

TYPE_PARAMETER

JCTypeIntersection

IntersectionTypeTree

TYPEINTERSECTION

INTERSECTION_TYPE

JCTypeUnion

UnionTypeTree

TYPEUNION

UNION_TYPE

JCTypeApply

ParameterizedTypeTree

TYPEAPPLY

PARAMETERIZED_TYPE

JCArrayTypeTree

ArrayTypeTree

TYPEARRAY

ARRAY_TYPE

JCPrimitiveTypeTree

PrimitiveTypeTree

TYPEIDENT

PRIMITIVE_TYPE


JCLiteral

LiteralTree

LITERAL

INT_LITERAL

LONG_LITERAL

... 以LITERAL结尾的


JCIdent

IdentifierTree

IDENT

IDENTIFIER


JCMemberReference

MemberReferenceTree

REFERENCE

MEMBER_REFERENCE

JCFieldAccess

MemberSelectTree

SELECT

MEMBER_SELECT


JCArrayAccess

ArrayAccessTree

INDEXED

ARRAY_ACCESS


JCInstanceOf

InstanceOfTree

TYPETEST

INSTANCE_OF

JCTypeCast

TypeCastTree

TYPE_CAST

TYPECAST

JCBinary

BinaryTree

根据操作符定

根据tag映射

JCAssignOp

CompoundAssignmentTree

赋值,根据操作符定

支持的是 “+=”这种

根据tag映射

JCAssign

AssignmentTree

ASSIGN

支持的是直接赋值

ASSIGNMENT


JCParens

ParenthesizedTree

PARENS

PARENTHESIZED

JCLambda

LambdaExpressionTree

LAMBDA

LAMBDA_EXPRESSION

JCNewArray

NewArrayTree

NEWARRAY

NEW_ARRAY

JCNewClass

NewClassTree

NEWCLASS

NEW_CLASS

JCMethodInvocation

MethodInvocationTree

APPLY

METHOD_INVOCATION

JCAssert

AssertTree

ASSERT

ASSERT

JCThrow

ThrowTree

THROW

THROW


JCReturn

ReturnTree

RETURN

RETURN


JCContinue

ContinueTree

CONTINUE

CONTINUE

JCBreak

BreakTree

BREAK

BREAK

JCExpressionStatement

ExpressionStatementTree

EXEC

EXPRESSION_STATEMENT

JCIf

IfTree

IF

IF

JCConditional

ConditionalExpressionTree

CONDEXPR

CONDITIONAL_EXPRESSION

JCCatch

CatchTree

CATCH

CATCH

JCTry

TryTree

TRY

TRY

JCSynchronized

SynchronizedTree

SYNCHRONIZED

SYNCHRONIZED

JCCase

CaseTree

CASE

CASE

JCSwitch

SwitchTree

SWITCH

SWITCH

JCLabeledStatement

LabeledStatementTree

LABELLED

LABELED_STATEMENT

JCEnhancedForLoop

EnhancedForLoopTree

FOREACHLOOP

ENHANCED_FOR_LOOP

JCForLoop

ForLoopTree

FORLOOP

FOR_LOOP

JCWhileLoop

WhileLoopTree

WHILELOOP

WHILE_LOOP

JCDoWhileLoop

DoWhileLoopTree

DOLOOP

DO_WHILE_LOOP

JCBlock

BlockTree

BLOCK

BLOCK

JCSkip

EmptyStatementTree

SKIP

EMPTY_STATEMENT

JCVariableDecl

VariableTree

VARDEF

VARIABLE


JCMethodDecl

MethodTree

METHODDEF

METHOD


JCClassDecl

ClassTree

CLASSDEF

ANNOTATION_TYPE

INTERFACE

ENUM

CLASS


JCImport

ImportTree

IMPORT

IMPORT


JCCompilationUnit

CompilationUnitTree

TOPLEVEL

COMPILATION_UNIT

五、JC类的Factory

细心阅读会发现,各种JC类的构造函数都是protected,也就是说,并不能直接进行初始化,所以现在要使用Factory,Factory是各种JC类的工厂定义

JAVACC语法分析器 java语法树分析_JAVACC语法分析器

六、TreeMaker

TreeMaker实现了Factory接口,所以我们它会是我们经常使用的一个类

还需要关注的一个Names,这个基本是创建一个节点的开始

Names: 用来存储和表示解析后的词法,每个字符集合都会是一个Name对象,所有的对象都存储在Name.Table内部类中。

在学习以下内容时,一定要熟练掌握JCIdent和Names。

Javac编译原理 - wade&luffy - 博客园

 

javac源码笔记与简单的编译原理 | Ren's Time Overflow Skyline ^_^

深入分析 Javac 编译原理 - 知乎

6.1、添加 import

// import com.leisure.lombok.thrift.AstTreeClass
// 获取标识符
JCTree.JCIdent jcIdent = treeMaker.Ident(names.fromString("com.leisure.lombok.thrift"));
// 获取标识符
Name className = names.fromString("AstTreeClass");
// 定义访问
JCTree.JCFieldAccess jcFieldAccess = treeMaker.Select(jcIdent, className);
// 添加import节点
JCTree.JCImport anImport = treeMaker.Import(jcFieldAccess, false);
// 加入AST树种
jcCompilationUnit.defs = jcCompilationUnit.defs.append(anImport);

6.2、定义属性

默认构造函数

//private AstTreeClass variable = new AstTreeClass()
        // new AstTreeClass()
        JCTree.JCNewClass newClass = treeMaker.NewClass(null, null, treeMaker.Ident(names.fromString("AstTreeClass")), List.nil(), null);

        // private AstTreeClass variable = ...
        JCTree.JCVariableDecl variableDecl = treeMaker.VarDef(treeMaker.Modifiers(Modifier.PRIVATE.ordinal()),
                names.fromString("variable"), treeMaker.Ident(names.fromString("AstTreeClass")), newClass);

带参数的构造函数

使用这个我们就可以实现@Slf4j了(当然了,还需要有插件,才能真正像@Slf4j一样使用)

//public static final AstTreeClass staticVariable = new AstTreeClass(1)
        JCTree.JCLiteral constantOne = treeMaker.Literal(1);
        JCTree.JCNewClass newClass1 = treeMaker.NewClass(null, null, treeMaker.Ident(names.fromString("AstTreeClass")), List.of(constantOne), null);

        JCTree.JCVariableDecl staticVariableDecl = treeMaker.VarDef(
                treeMaker.Modifiers(Flags.PUBLIC + Flags.STATIC + Flags.FINAL),
                names.fromString("staticVariable"),
                treeMaker.Ident(names.fromString("AstTreeClass")),
                newClass1
        );

6.4、添加方法

String name = variableDecl.name.toString();
            JCTree.JCExpression varType = variableDecl.vartype;
            // getter,假设name长度大于1
            String getterMethodName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1);
            // this.name
            JCTree.JCExpression thisName = treeMaker.Select(treeMaker.This(classDecl.sym.type), names.fromString(name));
            JCTree.JCReturn jcReturn = treeMaker.Return(thisName);
            // public type getName() {return this.name;}
            JCTree.JCMethodDecl getter = treeMaker.MethodDef(
                    treeMaker.Modifiers(Flags.PUBLIC), // 访问标识
                    names.fromString(getterMethodName), // 方法名字
                    varType,                            // 返回类型
                    List.nil(),                          // 泛型形参列表
                    List.nil(),                        // 参数列表
                    List.nil(),                        // 异常列表
                    treeMaker.Block(0, List.of(jcReturn)), // block
                    null                   // 默认方法
            );
// setter
            // public void setName(nameType name) {this.name = name;}
            String setterMethodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
            // 这里只是生成了this.name = name表达式
            JCTree.JCAssign assign = treeMaker.Assign(thisName, treeMaker.Ident(names.fromString(name)));
            // 生成一条语句 this.name = name;
            JCTree.JCExpressionStatement assignStat = treeMaker.Exec(assign);
            JCTree.JCMethodDecl setterMethodDecl = treeMaker.MethodDef(
                    treeMaker.Modifiers(Flags.PUBLIC),     // 访问标识
                    names.fromString(setterMethodName),    // 方法名
                    treeMaker.TypeIdent(TypeTag.VOID),                     // 返回类型
                    List.nil(),                    // 泛型形参列表
                    List.of(treeMaker.VarDef(
                            treeMaker.Modifiers(Flags.PARAMETER),   // 普通参数
                            variableDecl.name,
                            varType,
                            null   // 初始化为空,方法入参时为空即可
                            )
                    ), // 参数列表
                    List.nil(), // 异常列表
                    treeMaker.Block(0, List.of(assignStat)), // 方法体
                    null //默认方法
            );


TreeMaker  -> JCTree -> Tree ,接下来的一系列就是应用了