在上一篇文章java自定义编译时注解器中讲述到了有关自定义注解器的使用,接来在这里将会讲述的是如何通过语法树表示所想要的代码结构,并通过编译处理器生成相应的字节码。
Java 编译处理流程
- 源文件在指定的命令行下被读取,解析为语法树。对应外部可见的定义会被记录到编译器的符号表中(符合表如:LineNumberTable 记录行号、LocalVariableTable 记录变量定义、Exception table 记录异常定义 、StackMapTable )
- 注解处理器编译处理注解。
- 语法分析器根据已解析创建的语法树分析并生成字节码,在语法树分析期间,当前所引用到的其他类也将会的的解析。
一、抽象语法树(Abstract Syntax Tree)
在计算机科学中,抽象语法树(Abstract Syntax Tree,AST),或简称语法树(Syntax tree),是源代码语法结构的一种抽象表示。它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。
抽象语法树由JCTree 内部类(如:JCCompilationUnit、JCImport、JCClassDecl、JCMethodDecl、JCVariableDecl 等等)作为语法节点构成。语法树的节点可以是 包名、修饰符、类、接口、异常、方法、变量、返回值等。
例如:
1 | package com.test; |
对应的语法树如下图:
JCTree 类中提供了 accept()
方法来范围语法树中的所有语法节点。
1 | public abstract void accept(JCTree.Visitor var1); |
accept
方法接收一个JCTree的内部类 Visitor
作为参数,Visitor 提供了一系列访问语法树各个语法节点的方法。在获取到响应的语法节点后,我们可以对语法节点进行增删改操作。
Visitor
的子类有 TreeScanner(可以扫描语法树的所有节点) 和 TreeTranslator(扫描语法树所有节点并且可以将节点进行转换)
JCCompilationUnit
Everything in one source file is kept in a TopLevel structure. 在语法树中作为每一个原文件的顶级结构,包含有 JCPackageDecl、JCImport、JCClassDecl 等信息。
JCClassDecl 类定义
1 | public static class JCClassDecl extends JCTree.JCStatement implements ClassTree { |
JCMethodDecl 方法定义
1 | public static class JCMethodDecl extends JCTree implements MethodTree { |
JCModifiers 访问修饰定义
1 | public static class JCModifiers extends JCTree implements ModifiersTree { |
JCVariableDecl 变量的定义
1 | public static class JCVariableDecl extends JCTree.JCStatement implements VariableTree { |
JCIdent 标识符表达式,可以表示类、变量引用或者方法。
1 | public static class JCIdent extends JCTree.JCExpression implements IdentifierTree { |
JCIf if语句定义
1 | public static class JCIf extends JCTree.JCStatement implements IfTree { |
JCAssign 赋值语句
1 | public static class JCAssign extends JCTree.JCExpression implements AssignmentTree { |
JCAssignOp
1 | public static class JCAssignOp extends JCTree.JCExpression implements CompoundAssignmentTree { |
JCBinary 二元操作符
1 | public static class JCBinary extends JCTree.JCExpression implements BinaryTree { |
JCReturn 返回语句
1 | public static class JCReturn extends JCTree.JCStatement implements ReturnTree { |
JCLiteral 字面量表达式
1 | public static class JCLiteral extends JCTree.JCExpression implements LiteralTree { |
JCFieldAccess 其他类的变量、方法的访问表达式
1 | public static class JCFieldAccess extends JCTree.JCExpression implements MemberSelectTree { |
JCMethodInvocation 方法调用表达式
1 | public static class JCMethodInvocation extends JCTree.JCPolyExpression implements MethodInvocationTree { |
JCSkip
空操作,即一个无效的分号 “;”
JCUnary 一元运算表达式
1 | public static class JCUnary extends JCTree.JCExpression implements UnaryTree { |
JCBlock 代码块 定义
1 | public static class JCBlock extends JCTree.JCStatement implements BlockTree { |
JCForLoop for 循环代码块定义
1 | public static class JCForLoop extends JCTree.JCStatement implements ForLoopTree { |
JCDoWhileLoop do…while 循环代码块定义
1 | public static class JCDoWhileLoop extends JCTree.JCStatement implements DoWhileLoopTree { |
JCWhileLoop while 循环代码块定义
1 | public static class JCWhileLoop extends JCTree.JCStatement implements WhileLoopTree { |
JCEnhancedForLoop 增强for 循环定义
1 | public static class JCWhileLoop extends JCTree.JCStatement implements WhileLoopTree { |
JCSynchronized 同步锁定义
1 | public static class JCSynchronized extends JCTree.JCStatement implements SynchronizedTree { |
样例
1 | // 构建同步代码块 |
参考资料:
http://openjdk.java.net/groups/compiler/doc/compilation-overview/index.html
https://www.cnblogs.com/wade-luffy/p/6050331.html