一、ASTTransformation#visit 方法中访问 Groovy 类、方法、字段、属性
在 ASTTransformation#visit 方法中 , 使用 source.AST 可以获取 Groovy 脚本的 AST 语法树节点 , 该节点是 ModuleNode 类型的 , 在一个 Groovy 脚本中可以定义多个 Class 类 , 其对应的 Class 语法树节点封装在了 ModuleNode 类的 List classes = new LinkedList(); 成员中 ;
因此 , 在 ASTTransformation#visit 方法中 , 可以使用
source.AST.classes
获取 Groovy 脚本中定义的所有 Groovy 类 ;
使用 each 方法遍历上述 Class 类节点集合 List classes , 在闭包中 , 使用 it 获取正在遍历的 ClassNode 类型的集合元素 ;
source.AST.classes.each { it }
遍历时 , 执行 ClassNode 对象的 visitContents 方法 , 传入 GroovyClassVisitor 对象 , 用于访问 Groovy 的每个类 ;
GroovyClassVisitor 对象中 , 提供了访问 类 、成员字段 、成员方法 、属性 、 构造函数的回调方法 ;
代码示例 :
import org.codehaus.groovy.ast.ASTNode import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.ConstructorNode import org.codehaus.groovy.ast.FieldNode import org.codehaus.groovy.ast.GroovyClassVisitor import org.codehaus.groovy.ast.MethodNode import org.codehaus.groovy.ast.PropertyNode import org.codehaus.groovy.control.SourceUnit import org.codehaus.groovy.transform.ASTTransformation import org.codehaus.groovy.transform.GroovyASTTransformation @GroovyASTTransformation class MyASTTransformation implements ASTTransformation { /** * 编译时处理方法 * @param nodes AST 抽象语法树节点 , 是 ASTNode 数组类型 * @param source 源单元 , 可以通过该对象拿到源文件 */ @Override void visit(ASTNode[] nodes, SourceUnit source) { println nodes println source println source.AST println source.source.reader.text // 获取 Groovy.groovy 脚本中的类集合 , 并进行遍历 // 在 ModuleNode 中的类节点封装在了如下成员中 // List<ClassNode> classes = new LinkedList<ClassNode>(); source.AST.classes.each { it.visitContents(new GroovyClassVisitor() { @Override void visitClass(ClassNode node) { // 分析类的方法 println "visitClass ${node.name}" } @Override void visitConstructor(ConstructorNode node) { // 分析类构造方法 println "visitConstructor ${node.name}" } @Override void visitMethod(MethodNode node) { // 分析普通方法 println "visitMethod ${node.name}" } @Override void visitField(FieldNode node) { // 分析字段 println "visitField ${node.name}" } @Override void visitProperty(PropertyNode node) { // 分析属性 println "visitProperty ${node.name}" } }) } } }
编译时输出结果 :
visitConstructor <init> visitConstructor <init> visitMethod main visitMethod run visitProperty name visitField name visitMethod hello
二、完整代码示例及进行编译时处理的编译过程
1、Groovy 脚本 Groovy.groovy
class Student{ def name def hello(){ println "hello" } } def student = new Student()