【Groovy】编译时元编程 ( 编译时方法拦截 | 在 MyASTTransformation#visit 方法中找到要拦截的方法 )

简介: 【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 classes = new LinkedList(); 成员中 ;



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 集合中 , 名称为 “hello” 的节点 , 也就是查找 Student 类中的 hello 方法对应的 MethodNode 节点 ;


 

source.AST.classes.find {
            // 查找名称为 Student 的类
            // it 是 ClassNode 节点
            it.name == "Student"
        }?.methods?.find {
            // 查找 Student 类下名称为 hello 的方法
            // it 是 MethodNode 节点
            it.name == "hello"
        }
目录
相关文章
|
5月前
|
编译器 Java
Java编译器注解运行和自动生成代码问题之重写init方法的问题如何解决
Java编译器注解运行和自动生成代码问题之重写init方法的问题如何解决
|
6月前
|
Java API Android开发
ASM 框架:字节码操作的常见用法(生成类,修改类,方法插桩,方法注入)
ASM 框架:字节码操作的常见用法(生成类,修改类,方法插桩,方法注入)
112 0
【Groovy】MOP 元对象协议与元编程 ( 使用 Groovy 元编程进行函数拦截 | 动态拦截函数 | 动态获取 MetaClass 中的方法 | evaluate 方法执行Groovy脚本 )
【Groovy】MOP 元对象协议与元编程 ( 使用 Groovy 元编程进行函数拦截 | 动态拦截函数 | 动态获取 MetaClass 中的方法 | evaluate 方法执行Groovy脚本 )
201 0
【Groovy】MOP 元对象协议与元编程 ( 使用 Groovy 元编程进行函数拦截 | 动态拦截函数 | 动态获取 MetaClass 中的方法 | evaluate 方法执行Groovy脚本 )
【Groovy】编译时元编程 ( ASTTransformation#visit 方法中访问 Groovy 类、方法、字段、属性 | 完整代码示例及进行编译时处理的编译过程 )(二)
【Groovy】编译时元编程 ( ASTTransformation#visit 方法中访问 Groovy 类、方法、字段、属性 | 完整代码示例及进行编译时处理的编译过程 )(二)
181 0
【Groovy】编译时元编程 ( ASTTransformation#visit 方法中访问 Groovy 类、方法、字段、属性 | 完整代码示例及进行编译时处理的编译过程 )(二)
【Groovy】编译时元编程 ( ASTTransformation#visit 方法中访问 Groovy 类、方法、字段、属性 | 完整代码示例及进行编译时处理的编译过程 )(一)
【Groovy】编译时元编程 ( ASTTransformation#visit 方法中访问 Groovy 类、方法、字段、属性 | 完整代码示例及进行编译时处理的编译过程 )(一)
274 0
【Groovy】编译时元编程 ( ASTTransformation#visit 方法中访问 Groovy 类、方法、字段、属性 | 完整代码示例及进行编译时处理的编译过程 )(一)
【Groovy】MOP 元对象协议与元编程 ( 使用 Groovy 元编程进行函数拦截 | 使用 MetaClass 进行方法拦截 | 对象上拦截方法 | 类上拦截方法 )
【Groovy】MOP 元对象协议与元编程 ( 使用 Groovy 元编程进行函数拦截 | 使用 MetaClass 进行方法拦截 | 对象上拦截方法 | 类上拦截方法 )
189 0
【Groovy】MOP 元对象协议与元编程 ( 使用 Groovy 元编程进行函数拦截 | 使用 MetaClass 进行方法拦截 | 对象上拦截方法 | 类上拦截方法 )
【Groovy】MOP 元对象协议与元编程 ( 使用 Groovy 元编程进行函数拦截 | 重写 MetaClass#invokeMethod 方法实现函数拦截 | 实现函数调用转发 )
【Groovy】MOP 元对象协议与元编程 ( 使用 Groovy 元编程进行函数拦截 | 重写 MetaClass#invokeMethod 方法实现函数拦截 | 实现函数调用转发 )
156 0
【Groovy】MOP 元对象协议与元编程 ( 使用 Groovy 元编程进行函数拦截 | 重写 MetaClass#invokeMethod 方法实现函数拦截 | 实现函数调用转发 )
【错误记录】Groovy 扩展方法调用报错 ( 静态扩展方法 或 实例扩展方法 需要分别配置 | 没有配置调用会报错 groovy.lang.MissingMethodException )
【错误记录】Groovy 扩展方法调用报错 ( 静态扩展方法 或 实例扩展方法 需要分别配置 | 没有配置调用会报错 groovy.lang.MissingMethodException )
596 0
【错误记录】Groovy 扩展方法调用报错 ( 静态扩展方法 或 实例扩展方法 需要分别配置 | 没有配置调用会报错 groovy.lang.MissingMethodException )
【Groovy】MOP 元对象协议与元编程 ( 使用 Groovy 元编程进行函数拦截 | 实现 GroovyInterceptable 接口 | 重写 invokeMethod 方法 )
【Groovy】MOP 元对象协议与元编程 ( 使用 Groovy 元编程进行函数拦截 | 实现 GroovyInterceptable 接口 | 重写 invokeMethod 方法 )
176 0
【Groovy】MOP 元对象协议与元编程 ( 使用 Groovy 元编程进行函数拦截 | 实现 GroovyInterceptable 接口 | 重写 invokeMethod 方法 )
【Groovy】MOP 元对象协议与元编程 ( 使用 Groovy 元编程进行函数拦截 | 属性缺失 propertyMissing 函数回调 | 方法缺失 methodMissing 函数回调 )
【Groovy】MOP 元对象协议与元编程 ( 使用 Groovy 元编程进行函数拦截 | 属性缺失 propertyMissing 函数回调 | 方法缺失 methodMissing 函数回调 )
158 0
【Groovy】MOP 元对象协议与元编程 ( 使用 Groovy 元编程进行函数拦截 | 属性缺失 propertyMissing 函数回调 | 方法缺失 methodMissing 函数回调 )

热门文章

最新文章