文章目录

  • 一、ASTTransformation#visit 方法中访问 Groovy 类、方法、字段、属性
  • 二、完整代码示例及进行编译时处理的编译过程
    • 1、Groovy 脚本 Groovy.groovy
    • 2、ASTTransformation 接口实现 MyASTTransformation.groovy
    • 3、配置 ASTTransformation
    • 3、使用命令行进行编译时处理

一、ASTTransformation#visit 方法中访问 Groovy 类、方法、字段、属性


在 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 源单元 , 可以通过该对象拿到源文件*/@Overridevoid visit(ASTNode[] nodes, SourceUnit source) {println nodesprintln sourceprintln source.ASTprintln source.source.reader.text// 获取 Groovy.groovy 脚本中的类集合 , 并进行遍历// 在 ModuleNode 中的类节点封装在了如下成员中// List<ClassNode> classes = new LinkedList<ClassNode>();source.AST.classes.each {it.visitContents(new GroovyClassVisitor() {@Overridevoid visitClass(ClassNode node) {// 分析类的方法println "visitClass ${node.name}"}@Overridevoid visitConstructor(ConstructorNode node) {// 分析类构造方法println "visitConstructor ${node.name}"}@Overridevoid visitMethod(MethodNode node) {// 分析普通方法println "visitMethod ${node.name}"}@Overridevoid visitField(FieldNode node) {// 分析字段println "visitField ${node.name}"}@Overridevoid 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 namedef hello(){println "hello"}
}def student = new Student()

2、ASTTransformation 接口实现 MyASTTransformation.groovy

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 源单元 , 可以通过该对象拿到源文件*/@Overridevoid visit(ASTNode[] nodes, SourceUnit source) {println nodesprintln sourceprintln source.ASTprintln source.source.reader.text// 获取 Groovy.groovy 脚本中的类集合 , 并进行遍历// 在 ModuleNode 中的类节点封装在了如下成员中// List<ClassNode> classes = new LinkedList<ClassNode>();source.AST.classes.each {it.visitContents(new GroovyClassVisitor() {@Overridevoid visitClass(ClassNode node) {// 分析类的方法println "visitClass ${node.name}"}@Overridevoid visitConstructor(ConstructorNode node) {// 分析类构造方法println "visitConstructor ${node.name}"}@Overridevoid visitMethod(MethodNode node) {// 分析普通方法println "visitMethod ${node.name}"}@Overridevoid visitField(FieldNode node) {// 分析字段println "visitField ${node.name}"}@Overridevoid visitProperty(PropertyNode node) {// 分析属性println "visitProperty ${node.name}"}})}}
}

3、配置 ASTTransformation

创建 Y:\002_WorkSpace\003_IDEA\Groovy_Demo2\src\main\groovy\resources\META-INF\services\org.codehaus.groovy.transform.ASTTransformation 目录层级及文件 , 在文件中配置 ASTTransformation 实现类的全类名 :

MyASTTransformation

3、使用命令行进行编译时处理

首先 , 进入 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 namedef hello(){println "hello"}
}def student = new Student()
visitConstructor <init>
visitConstructor <init>
visitMethod main
visitMethod run
visitProperty name
visitField name
visitMethod hello

【Groovy】编译时元编程 ( ASTTransformation#visit 方法中访问 Groovy 类、方法、字段、属性 | 完整代码示例及进行编译时处理的编译过程 )相关推荐

  1. 【Groovy】编译时元编程 ( ASTTransformation#visit 方法简介 | org.codehaus.groovy.ast.ModuleNode 脚本节点 )

    文章目录 一.ASTTransformation#visit 方法简介 二.org.codehaus.groovy.ast.ModuleNode 脚本节点 一.ASTTransformation#vi ...

  2. 【Groovy】编译时元编程 ( ASTTransformation#visit 方法获取 Groovy 源文件 )

    文章目录 一.ASTTransformation#visit 方法获取 Groovy 源文件 二.完整代码示例 1.Groovy 脚本 Groovy.groovy 2.ASTTransformatio ...

  3. 【Groovy】编译时元编程 ( AST 语法树分析 | ClassNode 根节点 | 方法 Methods 节点 | 字段 Fields 节点 | 属性 Properties 节点 )

    文章目录 一.AST 语法树分析 一.AST 语法树分析 在上一篇博客 [Groovy]编译时元编程 ( 编译时元编程引入 | 声明需要编译时处理的类 | 分析 Groovy 类的 AST 语法树 ) ...

  4. 【Groovy】编译时元编程 ( 编译时元编程引入 | 声明需要编译时处理的类 | 分析 Groovy 类的 AST 语法树 )

    文章目录 一.编译时元编程引入 二.声明需要编译时处理的类 三.分析 Groovy 类的 AST 语法树 一.编译时元编程引入 在之前的 " [Groovy]MOP 元对象协议与元编程 &q ...

  5. 【Groovy】编译时元编程 ( 编译时方法拦截 | 在 MyASTTransformation#visit 方法中进行方法拦截 )

    文章目录 一.在 MyASTTransformation#visit 方法中进行方法拦截 二.完整代码示例及进行编译时处理的编译过程 1.Groovy 脚本 Groovy.groovy 2.ASTTr ...

  6. 【Groovy】编译时元编程 ( 编译时方法注入 | 使用 buildFromSpec、buildFromString、buildFromCode 进行方法注入 )

    文章目录 一.在 MyASTTransformation#visit 方法中进行方法注入 1.使用 new AstBuilder().buildFromSpec 进行方法注入 2.使用 new Ast ...

  7. 【Groovy】编译时元编程 ( 方法拦截时用到的 AST 语法树节点 MethodNode 节点 | MethodNode 节点分析 | MethodNode 节点中的BlockStatement)

    文章目录 一.方法拦截时用到的 AST 语法树节点 MethodNode 节点 二.MethodNode 节点分析 三.MethodNode 节点中的 BlockStatement 集合 一.方法拦截 ...

  8. 【Groovy】Groovy 语言特点简介 ( 支持 Java 语法 | 支持 Java 虚拟机 | Groovy 语言是动态语言 | Groovy 扩展 JDK | 编译时元编程 )

    文章目录 一.Groovy 支持 Java 语法 二.Groovy 支持 Java 虚拟机 三.Groovy 语言是 动态语言 四.Groovy 扩展 JDK 五.Groovy 编译时元编程 一.Gr ...

  9. 【Groovy】自定义 Xml 生成器 BuilderSupport ( 继承 BuilderSupport 抽象类 | 在 createNode 方法中获取节点名称、节点属性、节点值信息 )

    文章目录 一.继承 BuilderSupport 抽象类 二.在 createNode 方法中获取节点名称.节点属性.节点值信息 三.完整代码示例 1.MyBuilderSupport 生成器代码 2 ...

最新文章

  1. 通过分析exevc系统调用处理过程来理解Linux内核如何装载和启动一个可执行程序...
  2. Kettle使用_7 数据校验组件应用
  3. 【数据结构基础笔记】【顺序表】
  4. [react] 请描述你对纯函数的理解?
  5. PID控制器开发笔记之三:抗积分饱和PID控制器的实现
  6. Net学习日记_ADO.Net_2_练习(treeView)
  7. 朝九晚五的工作值得留恋吗?
  8. OpenCV-Python实战(21)——OpenCV人脸检测项目在Web端的部署
  9. 一个HTML 导航栏下划线跟随效果
  10. 2010十一月份日用百货热销品货源推荐
  11. 云计算平台能够提供计算服务器,云计算平台提供了什么服务器
  12. 类似吾爱破解论坛的网站有哪些?破解软件网站合集推荐
  13. 浙江省高校教师职称计算机考试成绩查询系统,浙江省高校招生考试信息管理系统...
  14. 万字总结:金融市场基础知识
  15. linux用for循环写九九乘法表,写一个方法,用一个for循环打印九九乘法表
  16. c语言中lu是什么数据类型,C语言编程入门之--第四章C语言基本数据类型
  17. FlinkX数据同步
  18. 数据库资源博客---小麦苗BEST
  19. 努比亚 Z5 mini刷机包 omni4.4.2改动V4.0 自用版 精简 MIUI特效
  20. TPshop项目-功能测试(1)

热门文章

  1. vs2015上使用github进行版本控制
  2. 阿里云RDS的mysql数据库占用空间超过90%的处理
  3. 将用户输入内容中的尖括号、引号等进行转义
  4. Python学习入门基础教程(learning Python)--3.3.3 Python逻辑关系表达式
  5. 布局技巧:使用ViewStub
  6. shareSDK 微信分享的时候只能分享jpg格式的图片大于32k时为什么分享不出去?
  7. Azure Bill
  8. 01 Python基础学习
  9. post传参部分数据丢失
  10. IdentityServer4 配置负载均衡