当前位置:网站首页>[groovy] compile time metaprogramming (compile time method injection | method injection using buildfromspec, buildfromstring, buildfromcode)
[groovy] compile time metaprogramming (compile time method injection | method injection using buildfromspec, buildfromstring, buildfromcode)
2022-07-06 00:35:00 【Programmer community】
List of articles
- One 、 stay MyASTTransformation#visit Method injection
- 1、 Use new AstBuilder().buildFromSpec Conduct method injection
- 2、 Use new AstBuilder().buildFromString Conduct method injection
- 3、 Use new AstBuilder().buildFromCode Conduct method injection
- Two 、 Complete code examples and the compilation process of compile time processing
- 1、Groovy Script Groovy.groovy
- 2、ASTTransformation Interface implementation MyASTTransformation.groovy
- 3、 To configure ASTTransformation
- 3、 Use the command line for compile time processing
One 、 stay MyASTTransformation#visit Method injection
stay 【Groovy】 Compile time metaprogramming ( Compile time method interception | stay MyASTTransformation#visit Method interception in method ) Blog Method injection based on method interception ;
First of all, MethodNode To deal with
// eureka Student Under the hello Method // stay MethodNode Call under the node // it Namely MethodNode node BlockStatement blockStatement = code // Empty BlockStatement Medium List<Statement> statements member // Method intercepts emptying , No longer execute the original method // Method injection does not empty , Will execute the original method content blockStatement.statements.clear()
If you will blockStatement.statements
Cleaned up , No more execution Student#hello The original method content ;
Retain blockStatement.statements
The original set element , Continue adding other elements to it , Other contents can be executed on the basis of the original method ;
1、 Use new AstBuilder().buildFromSpec Conduct method injection
First create a method node ,
// Create a method node def methods = new AstBuilder().buildFromSpec {
expression {
methodCall {
variable('this') constant('println') argumentList {
constant('hello buildFromSpec') } } } }
Then the method node , Add to blockStatement.statements
Collection ;
// Add the method node to hello In the method blockStatement.statements.addAll(methods)
2、 Use new AstBuilder().buildFromString Conduct method injection
// Create a method node def methods2 = new AstBuilder().buildFromString('println "hello buildFromString"') // Add the method node to hello In the method blockStatement.statements.addAll(methods2)
3、 Use new AstBuilder().buildFromCode Conduct method injection
// Create a method node , Note that what you get here is def methods3 = new AstBuilder().buildFromCode {
println "hello buildFromCode" } // Add the method node to hello In the method blockStatement.statements.addAll(methods3[0].statements)
Two 、 Complete code examples and the compilation process of compile time processing
1、Groovy Script Groovy.groovy
class Student{
def name def hello(){
println "hello" }}def student = new Student()student.hello()
2、ASTTransformation Interface implementation MyASTTransformation.groovy
import org.codehaus.groovy.ast.ASTNodeimport org.codehaus.groovy.ast.builder.AstBuilderimport org.codehaus.groovy.ast.stmt.BlockStatementimport org.codehaus.groovy.control.SourceUnitimport org.codehaus.groovy.transform.ASTTransformationimport org.codehaus.groovy.transform.GroovyASTTransformation@GroovyASTTransformationclass MyASTTransformation implements ASTTransformation {
/** * Compile time processing * @param nodes AST Abstract syntax tree node , yes ASTNode An array type * @param source Source unit , You can get the source file through this object */ @Override void visit(ASTNode[] nodes, SourceUnit source) {
println nodes println source println source.AST println source.source.reader.text // obtain Groovy.groovy A collection of classes in a script , And traverse // stay ModuleNode The class nodes in are encapsulated in the following members // List<ClassNode> classes = new LinkedList<ClassNode>(); source.AST.classes.find {
// The search name is Student Class // it yes ClassNode node it.name == "Student" }?.methods?.find {
// lookup Student The name under the class is hello Methods // it yes MethodNode node it.name == "hello" }?.with {
// eureka Student Under the hello Method // stay MethodNode Call under the node // it Namely MethodNode node BlockStatement blockStatement = code // Empty BlockStatement Medium List<Statement> statements member // Method intercepts emptying , No longer execute the original method // Method injection does not empty , Will execute the original method content blockStatement.statements.clear() // Create a method node def methods = new AstBuilder().buildFromSpec {
expression {
methodCall {
variable('this') constant('println') argumentList {
constant('hello buildFromSpec') } } } } // Add the method node to hello In the method //blockStatement.statements.addAll(methods) // Create a method node def methods2 = new AstBuilder().buildFromString('println "hello buildFromString"') // Add the method node to hello In the method //blockStatement.statements.addAll(methods2) // Create a method node , Note that what you get here is def methods3 = new AstBuilder().buildFromCode {
println "hello buildFromCode" } // Add the method node to hello In the method blockStatement.statements.addAll(methods3[0].statements) } }}
3、 To configure ASTTransformation
establish D:\002_Project\012_Groovy\Groovy_Demo\src\main\groovy\resources\META-INF\servicesorg.codehaus.groovy.transform.ASTTransformation
Directory level and documents , Configure... In a file ASTTransformation
The full class name of the implementation class :
MyASTTransformation
3、 Use the command line for compile time processing
First , Get into D:\002_Project\012_Groovy\Groovy_Demo\src\main\groovy
Catalog ,
cd D:\002_Project\012_Groovy\Groovy_Demo\src\main\groovy
then , compile Compile time processing class MyASTTransformation.groovy , The compiled bytecode file MyASTTransformation.class
Save to D:\002_Project\012_Groovy\Groovy_Demo\src\main\groovy\classes
Under the table of contents ,
groovyc -d classes MyASTTransformation.groovy
And then , Package the above compiled bytecode file , Store in D:\002_Project\012_Groovy\Groovy_Demo\src\main\groovy\test.jar
route ;
jar -cf test.jar -C classes . -C resources .
Last , rely on test.jar perform Groovy.groovy Script
groovy -classpath test.jar Groovy.groovy
The execution result is :
[org.codehaus.groovy.ast.ModuleNode@7d7758be]org.codehaus.groovy.control.SourceUnit@2bdd8394org.codehaus.groovy.ast.ModuleNode@7d7758beclass Student{
def name def hello(){
println "hello" }}def student = new Student()student.hello()[org.codehaus.groovy.ast.ModuleNode@16ce702d]org.codehaus.groovy.control.SourceUnit@7b94089borg.codehaus.groovy.ast.ModuleNode@16ce702dprintln "hello buildFromString"[org.codehaus.groovy.ast.ModuleNode@72c28d64]org.codehaus.groovy.control.SourceUnit@6492fab5org.codehaus.groovy.ast.ModuleNode@72c28d64__synthesized__label__1644323893072__:{
println "hello buildFromCode" }hello buildFromCode
边栏推荐
- STM32 key chattering elimination - entry state machine thinking
- OS i/o devices and device controllers
- 【文件IO的简单实现】
- Power query data format conversion, Split Merge extraction, delete duplicates, delete errors, transpose and reverse, perspective and reverse perspective
- Global and Chinese markets for hinged watertight doors 2022-2028: Research Report on technology, participants, trends, market size and share
- Cloud guide DNS, knowledge popularization and classroom notes
- Natural language processing (NLP) - third party Library (Toolkit):allenlp [library for building various NLP models; based on pytorch]
- 数据分析思维分析方法和业务知识——分析方法(三)
- Anconda download + add Tsinghua +tensorflow installation +no module named 'tensorflow' +kernelrestart: restart failed, kernel restart failed
- 【DesignMode】组合模式(composite mode)
猜你喜欢
Spark AQE
The relationship between FPGA internal hardware structure and code
XML Configuration File
Notepad++ regular expression replacement string
Extracting profile data from profile measurement
KDD 2022 | 脑电AI助力癫痫疾病诊断
Search (DFS and BFS)
[designmode] composite mode
Calculate sha256 value of data or file based on crypto++
XML配置文件
随机推荐
Browser reflow and redraw
Search (DFS and BFS)
State mode design procedure: Heroes in the game can rest, defend, attack normally and attack skills according to different physical strength values.
Ffmpeg learning - core module
Spark DF增加一列
Model analysis of establishment time and holding time
Global and Chinese market of water heater expansion tank 2022-2028: Research Report on technology, participants, trends, market size and share
Spark-SQL UDF函数
小程序容器可以发挥的价值
MYSQL GROUP_ The concat function realizes the content merging of the same ID
Browser local storage
Leetcode:20220213 week race (less bugs, top 10% 555)
About the slmgr command
Knowledge about the memory size occupied by the structure
Spark SQL null value, Nan judgment and processing
《编程之美》读书笔记
Meta AI西雅图研究负责人Luke Zettlemoyer | 万亿参数后,大模型会持续增长吗?
notepad++正则表达式替换字符串
Leetcode 450 deleting nodes in a binary search tree
How to solve the problems caused by the import process of ecology9.0