Groovy编译时元编程 ( 编译时方法拦截 | 在 MyASTTransformation#visit 方法中找到要拦截的方法 )
Posted 韩曙亮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Groovy编译时元编程 ( 编译时方法拦截 | 在 MyASTTransformation#visit 方法中找到要拦截的方法 )相关的知识,希望对你有一定的参考价值。
文章目录
一、在 MyASTTransformation#visit 方法中找到要拦截的方法
在 ASTTransformation 接口实现类的
void visit(ASTNode[] nodes, SourceUnit source)
方法中 , 其中 ASTNode[] nodes
参数是 AST 语法树根节点数组 , 每个数组元素都是一个 ModuleNode 对应一个 Groovy 脚本 ;
SourceUnit source
是源单元 , 可以通过该对象拿到源文件 ;
source.AST
是单个 ModuleNode 对象 , 对应一个 Groovy 脚本 ;
1、获取 ClassNode 节点集合
source.AST.classes
就是一个 Groovy 脚本中定义的类节点数组 ; 这是在 ModuleNode 中的 ClassNode 类节点封装在了 List<ClassNode> classes = new LinkedList<ClassNode>();
成员中 ;
2、查找指定的 ClassNode 节点
使用
source.AST.classes.find
// 查找名称为 Student 的类
// it 是 ClassNode 节点
it.name == "Student"
代码 , 可以查找到名称为 “Student” 的 ClassNode 节点 , 也就是 Student 类对应的节点 ;
集合的 find 方法原型如下 , 得到的是一个集合元素对象 ; 该方法返回的是集合中第一个与闭包条件匹配的集合元素 ;
/**
* 查找与闭包条件匹配的第一个值。例子:
* <pre class="groovyTestCase">def list = [1,2,3]
* assert 2 == list.find it @code > 1
* </pre>
*
* @param self a Collection
* @param closure a closure condition
* @return the first Object found, in the order of the collections iterator, or null if no element matches
* @since 1.0
*/
public static <T> T find(Collection<T> self, @ClosureParams(FirstParam.FirstGenericType.class) Closure closure)
BooleanClosureWrapper bcw = new BooleanClosureWrapper(closure);
for (T value : self)
if (bcw.call(value))
return value;
return null;
3、获取指定 ClassNode 节点下的 MethodNode 节点集合
再进一步 , 如果获取的 ClassNode 节点不为空 , 则获取该节点下的 MethodNode 节点集合 , 使用 ?.methods
代码获取 ,
source.AST.classes.find
// 查找名称为 Student 的类
// it 是 ClassNode 节点
it.name == "Student"
?.methods
ClassNode 的 getMethods 方法原型如下 :
public class ClassNode extends AnnotatedNode implements Opcodes
/**
* @return 与此相关的方法 @code ClassNode
*/
public List<MethodNode> getMethods()
if (redirect != null)
return redirect.getMethods();
lazyClassInit();
return methodsList;
4、查找指定的 MethodNode 节点
查找 List<MethodNode>
集合中 , 名称为 “hello” 的节点 , 也就是查找 Student 类中的 hello 方法对应的 MethodNode 节点 ;
source.AST.classes.find
// 查找名称为 Student 的类
// it 是 ClassNode 节点
it.name == "Student"
?.methods?.find
// 查找 Student 类下名称为 hello 的方法
// it 是 MethodNode 节点
it.name == "hello"
以上是关于Groovy编译时元编程 ( 编译时方法拦截 | 在 MyASTTransformation#visit 方法中找到要拦截的方法 )的主要内容,如果未能解决你的问题,请参考以下文章
Groovy编译时元编程 ( 方法拦截时用到的 AST 语法树节点 MethodNode 节点 | MethodNode 节点分析 | MethodNode 节点中的BlockStatement)
Groovy编译时元编程 ( 编译时元编程引入 | 声明需要编译时处理的类 | 分析 Groovy 类的 AST 语法树 )
Groovy编译时元编程 ( ASTTransformation#visit 方法简介 | org.codehaus.groovy.ast.ModuleNode 脚本节点 )
Groovy编译时元编程 ( 编译时方法注入 | 使用 buildFromSpecbuildFromStringbuildFromCode 进行方法注入 )