当前位置:网站首页>[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.groovyThe 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
边栏推荐
- LeetCode 1189. Maximum number of "balloons"
- Go learning - dependency injection
- JS can really prohibit constant modification this time!
- Spark DF增加一列
- [designmode] adapter pattern
- Gavin teacher's perception of transformer live class - rasa project actual combat e-commerce retail customer service intelligent business dialogue robot system behavior analysis and project summary (4
- Uniapp development, packaged as H5 and deployed to the server
- LeetCode 6004. Get operands of 0
- 小程序容器可以发挥的价值
- Atcoder beginer contest 258 [competition record]
猜你喜欢

Spark SQL空值Null,NaN判断和处理

Extension and application of timestamp

Problems and solutions of converting date into specified string in date class

数据分析思维分析方法和业务知识——分析方法(二)

2022-02-13 work record -- PHP parsing rich text

How to use the flutter framework to develop and run small programs

Gavin teacher's perception of transformer live class - rasa project actual combat e-commerce retail customer service intelligent business dialogue robot system behavior analysis and project summary (4

Knowledge about the memory size occupied by the structure

如何制作自己的機器人

剖面测量之提取剖面数据
随机推荐
OpenCV经典100题
【文件IO的简单实现】
Spark DF adds a column
notepad++正则表达式替换字符串
Gavin teacher's perception of transformer live class - rasa project actual combat e-commerce retail customer service intelligent business dialogue robot system behavior analysis and project summary (4
Key structure of ffmpeg -- AVCodecContext
Search (DFS and BFS)
Meta AI西雅图研究负责人Luke Zettlemoyer | 万亿参数后,大模型会持续增长吗?
Spark DF增加一列
Global and Chinese markets of POM plastic gears 2022-2028: Research Report on technology, participants, trends, market size and share
[designmode] adapter pattern
notepad++正則錶達式替換字符串
PHP determines whether an array contains the value of another array
Opencv classic 100 questions
如何利用Flutter框架开发运行小程序
AtCoder Beginner Contest 258【比赛记录】
FFT learning notes (I think it is detailed)
Global and Chinese market of digital serial inverter 2022-2028: Research Report on technology, participants, trends, market size and share
Hudi of data Lake (1): introduction to Hudi
[simple implementation of file IO]