Grails with ATS Transformation tutorial with a demo example

I wanted to play with Groovy’s AST Transformation in Grails. I thought naively that it would be enough to put the AST Transformation code into the source folder, like in a pure groovy project. I run the grails-app and it didn’t worked. So I searched for help in the world-wide-web. Some guys said that the AST code need to be precompiled and there is no way to do it with one compile run. Sadly I couldn’t find an example or a tutorial how to do the precompiling. After some frustrating hours of searching and trying I got a working solution. Now I am going to share my knowledge and hope that I can help you with this post.

At first I give you an explanation what an AST Transformation is.
When the Groovy compiler compiles Groovy scripts and classes, at some point in the process, the source code will end up being represented in memory in the form of a Concrete Syntax Tree, then transformed into an Abstract Syntax Tree. The purpose of AST Transformations is to let developers hook into the compilation process to be able to modify the AST before it is turned into bytecode that will be run by the JVM.
In simple words it means that you can modify programmable your code at compile time.Groovy’s documentation provides a simple example what you can do with AST. In this example a new Annotation @WithLogging is created. If you add this Annotation to a method then the AST Transformation adds at the beginning and at the end of the method a print line statement with “Starting” and “Ending” and the method name. Now I will show you how to get this example running in grails.

The first thing i had done was creating a new source-folder (src/ast) and put all files in it which needs to be precompiled => all AST related files. In this case WithLogging.groovy and WithLoggingASTTransformation.groovy

WithLogging.groovy
1: @Retention(RetentionPolicy.SOURCE)
2: @Target([ElementType.METHOD])
3: @GroovyASTTransformationClass(“astexample.WithLoggingASTTransformation”)
4: public @interface WithLogging {
5: }
Here we define the Annotation and bind it to the WithLoggingASTTransformation class. It’s important to use the full path to the class.

WithLoggingASTTransformation.groovy
1: @GroovyASTTransformation(phase = CompilePhase.CANONICALIZATION)
2: class WithLoggingASTTransformation implements ASTTransformation {
3: private static HashSet set = new HashSet()
4: public void visit(ASTNode[] nodes, SourceUnit sourceUnit) {
5: sourceUnit.getAST()?.getClasses().each { ClassNode classNode ->
6: classNode.getAllDeclaredMethods().findAll { MethodNode method ->
7: method.getAnnotations(new ClassNode(WithLogging))
8: }.each { MethodNode method ->
9: if(!set.contains(method)) {
10: Statement startMessage = createPrintlnAst(“Starting method.name)11:StatementendMessage=createPrintlnAst(Endingmethod.name”)
12: List existingStatements = method.getCode().getStatements()
13: existingStatements.add(0, startMessage)
14: existingStatements.add(endMessage)
15: set.add(method)
16: }
17: }
18: }
19: }
20: private Statement createPrintlnAst(String message) {
21: return new ExpressionStatement(
22: new MethodCallExpression(
23: new VariableExpression(“this”),
24: new ConstantExpression(“println”),
25: new ArgumentListExpression(
26: new ConstantExpression(message)
27: )
28: )
29: )
30: }
31: }
This class preforms the AST Transformation. The compiler automatically calls the visit-method. This method iterates over all methods of all classes and check if the method has the @WithLogging Annotation. If the method has this Annotation then it adds the println-statements to the method.

The next step is to tell the grails app that it needs to precompile those files. To do that you have to create a new file in /scripts called “_Events.groovy”. This file is a grant script and with it you can hook into the grails events. We need now a hook into the compiling of the app and it’s done like this.
1: eventCompileStart = {target ->
2: compileAST(basedir, classesDirPath)
3: }
4: def compileAST(def srcBaseDir, def destDir) {
5: ant.sequential {
6: echo “Precompiling AST Transformations …”
7: echo “src srcBaseDir{destDir}”
8: path id: “grails.compile.classpath”, compileClasspath
9: def classpathId = “grails.compile.classpath”
10: mkdir dir: destDir
11: groovyc(destdir: destDir,
12: srcDir: “$srcBaseDir/src/ast”,
13: classpathref: classpathId,
14: verbose: grailsSettings.verboseCompile,
15: stacktrace: “yes”,
16: encoding: “UTF-8”)
17: echo “done precompiling AST Transformations”
18: }
19: }

At last we create a simple grails-controller to test the AST Transformation.
1: class AstController {
2: def index = {
3: loggedMethod()
4: render ‘i am just a dummy method to call the method..’
5: }
6: @WithLogging
7: def loggedMethod() {
8: println “i am doing some important stuff!”
9: }
10: }
When you run the app and call the index-handler than you will get this output:
1: Starting loggedMethod
2: i am doing some important stuff!
3: Ending loggedMethod

That’s it. The most important thing for the AST transformation in Grails is the /scripts/_Events.groovy file. The rest is just normal AST transformation code or Grail’s code.

You can download the whole tutorial code as a STS project with includes a running AST Grails app here.

I hope you enjoyed the tutorial and you are welcome to leave some feedback.

课件内容覆盖了从ROS基础知识到进阶应用的完整学习路径,具体如下: 第1章 ROS概述与环境搭建:介绍ROS相关概念、安装步骤、程序编写编译运行流程,以及集成开发环境的搭建。 第2章 ROS通信机制:系统讲解ROS核心的话题通信、服务通信和参数服务器三大通信机制。 第3章 ROS通信机制进阶:侧重通信机制编程语法的深入介绍,包括相关API、头文件与源文件的使用、Python模块导入等。 第4章 ROS运行管理:介绍元功能包、launch文件、工作空间覆盖、节点重名、分布式通信等运行管理策略。 第5章 ROS常用组件:讲解TF坐标变换、rosbag数据录制回放、rqt工具箱等实用工具的使用。 第6章 机器人系统仿真:介绍如何将URDF与RViz结合实现机器人建模与可视化,以及使用Gazebo搭建仿真环境。 第7章 机器人导航(仿真) :系统性介绍导航模块(地图、定位、感知、路径规划、运动控制),并通过完整案例展现仿真环境下的导航功能实现。 第8章 机器人平台设计:讲解从0到1搭建实体机器人的全过程,包括底盘设计、控制系统安装、分布式环境搭建及传感器集成。 第9章 机器人导航(实体) :介绍如何将仿真环境下开发的导航功能迁移部署到实体机器人上。 第10章 ROS进阶:深入介绍action通信、动态配置参数、pluginlib和nodelet等进阶通信策略与工具。 本套课件内容系统、由浅入深,既覆盖了ROS机器人操作系统的基础理论与通信机制,也包含了机器人系统仿真、实体平台设计与导航等实践环节。读者学习后能够掌握机器人的相关理论知识,构建属于自己的机器人平台并实现自主导航功能。课件适用于各类学校的ROS机器人操作系统课程教学,同时也适合机器人技术初学者自学参考。
代码转载自:https://pan.quark.cn/s/a5441b581188 在本文中,我们将详细研究在Delphi编程环境内如何运用SQLite3数据库系统,尤其是关于本地数据库与内存数据库的应用。SQLite3是一种轻量级、自包含的数据库引擎,它无需独立的服务器进程,因此使得在Delphi应用程序中的集成变得十分便捷。本文将主要聚焦以下几个领域: 1. **SQLite3概述** SQLite3是一种开源的SQL数据库,它被广泛用于移动应用、嵌入式设备以及桌面软件中。它的长处在于运行速度快、资源消耗低,并且支持标准的SQL语法。 2. **在Delphi中整合SQLite3** Delphi程序员可以通过第三方组件或API直接与SQLite3进行通信。一种普遍的方法是采用SQLite3的Delphi封装类,这允许开发者以面向对象的方法来管理数据库。这些封装类通常包括创建、打开、关闭数据库,执行SQL指令,以及管理结果集等功能。 3. **本地数据库导入到内存** 当需要提升数据处理速度或减少磁盘I/O操作时,可以将本地的SQLite3数据库导入到内存中。这通常通过建立一个内存数据库连接来实现,使用SQL指令`ATTACH DATABASE memory: AS mem_db`来完成。这样,所有的数据库操作都将执行在内存中,直到手动终止连接。 4. **内存数据库复制到本地** 内存数据库虽然便于使用,但并不持久。如果需要保存内存中的数据,可以将其复制到本地文件。这通常通过创建一个新的SQLite3文件,然后使用`INSERT INTO`或`ATTACH DATABASE`指令将内存数据库的信息转移到这个新文件。 5. **运用SQLite3 Sim...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值