在 ASTTransformation#visit 方法中 , 使用 source.AST
可以获取 Groovy 脚本的 AST 语法树节点 , 该节点是 ModuleNode 类型的 , 在一个 Groovy 脚本中可以定义多个 Class 类 , 其对应的 Class 语法树节点封装在了 ModuleNode
类的 List<ClassNode> classes = new LinkedList<ClassNode>();
成员中 ;
因此 , 在 ASTTransformation#visit 方法中 , 可以使用
source.AST.classes
获取 Groovy 脚本中定义的所有 Groovy 类 ;
使用 each 方法遍历上述 Class 类节点集合 List<ClassNode> 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
class Student{
def name
def hello(){
println "hello"
}
}
def student = new Student()
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}"
}
})
}
}
}
创建 Y:\002_WorkSpace\003_IDEA\Groovy_Demo2\src\main\groovy\resources\META-INF\services\org.codehaus.groovy.transform.ASTTransformation
目录层级及文件 , 在文件中配置 ASTTransformation
实现类的全类名 :
MyASTTransformation
首先 , 进入 Y:\002_WorkSpace\003_IDEA\Groovy_Demo2\src\main\groovy
目录 ,
cd Y:\002_WorkSpace\003_IDEA\Groovy_Demo2\src\main\groovy
然后 , 编译 编译时处理类 MyASTTransformation.groovy , 将编译后的字节码文件 MyASTTransformation.class
保存到 Y:\002_WorkSpace\003_IDEA\Groovy_Demo2\src\main\groovy\classes
目录下 ,
groovyc -d classes MyASTTransformation.groovy
再后 , 打包上述编译好的字节码文件 , 存放在 Y:\002_WorkSpace\003_IDEA\Groovy_Demo2\src\main\groovy\test.jar
路径 ;
jar -cf test.jar -C classes . -C resources .
最后 , 依赖 test.jar 执行 Groovy.groovy 脚本
groovy -classpath test.jar Groovy.groovy
执行结果为 :
[org.codehaus.groovy.ast.ModuleNode@2b175c00]
org.codehaus.groovy.control.SourceUnit@3eb81efb
org.codehaus.groovy.ast.ModuleNode@2b175c00
class Student{
def name
def hello(){
println "hello"
}
}
def student = new Student()
visitConstructor <init>
visitConstructor <init>
visitMethod main
visitMethod run
visitProperty name
visitField name
visitMethod hello