当前位置: 首页 > 知识库问答 >
问题:

时髦的 AST 转换 - 如何使用 Gradle 和 Intellij IDEA 编译 Java 注释类

东方森
2023-03-14

我想开发一个Groovy AST转换,在某些类上添加一些方法。所以我写了一个注释类和相应的转换类。然后,我用我的Groovy AST注释来注释一个java类。

当我使用嵌入式时髦编译器编译 java 注释类时(例如,通过以下代码段:类增强类 = 新 GroovyClassLoader().parseClass(新文件(“...”));),执行转换并将方法添加到代码段中称为增强类的已编译类中。

但我无法用Gradle groovy插件和Intellij IDEA正确编译java类。

问题:每个人都可以帮助我在Gradle和Intellij IDEA中使用Groovy AST转换吗?

注1:我用的是Intellij IDEA 14旗舰版。

注2:我的Groovy AST类、java注释类和我的“build.gradle”文件如下:

注释类:

@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
@GroovyASTTransformationClass(classes = {MyASTTransformation.class})
public @interface MyAST {
}

和转换类:

@CompileStatic
@GroovyASTTransformation(phase = CompilePhase.SEMANTIC_ANALYSIS)
public class MyASTTransformation implements ASTTransformation {
   @Override
   public void visit(ASTNode[] nodes, SourceUnit sourceUnit) {
      ...
   }
}

java注释类:

@MyAST
public class A {
   ...
}

"build.gradle"文件:

apply plugin: 'groovy'
sourceSets {
    main {
       groovy {
          srcDirs = ['src/main/groovy', 'src/main/java']
       }
        java {
          srcDirs = []
      }
   }
}

dependencies {
    compile 'org.codehaus.groovy:groovy-all:2.4.4'
}

共有1个答案

仲孙善
2023-03-14

我创建了我的第一个自定义AST转换,我也遇到了类似的问题,因此分享了我有限的经验。我正在使用Groovy 2.4.7和IntelliJ IDEA 2016.3.2。我只能在以下情况下使用自定义转换注释:

  1. 它是作为一个单独的工件(项目)创建的,另一个使用注释的项目引用了它
  2. 在与使用自定义注释的Groovy代码运行GroovyShell的自定义AST转换代码相同的项目中运行Groov测试脚本

我第一次尝试在同一项目中这样做,但这不起作用。我相信这是因为AST转换发生在编译时。这是我的例子:

AST改造项目

注释

@Retention (RetentionPolicy.SOURCE)
@Target ([ElementType.TYPE, ElementType.METHOD])
@GroovyASTTransformationClass (classes = [SqlAssistTransform])
@interface SqlAssist {
}

转型

@GroovyASTTransformation(phase=CompilePhase.SEMANTIC_ANALYSIS)
class SqlAssistTransform extends AbstractASTTransformation {
...
}

settings.gradle

rootProject.name = 'groovy-sql-transform'

build.gradle

...
group = 'com.company.groovy.transform'
version = '1.0-groovy-2.4'
description = 'Groovy AST transformation for SQL syntax'
...

使用 AST 注释的项目

带注释的类

@SqlAssist
class Something {
...
}

依赖关系示例#1-依赖于存储库中的AST工件

build.gradle

...
dependencies {
     ...
    // As long as your local repository (or remote repository) has the AST transformation project installed. i.e. Run '.\gradlew install' in AST project to install to local repository
    compile group:'com.company.groovy.transform', name:'groovy-sql-transform', version: '1.0.0-groovy-2-4'
    ...
}
...

依赖关系示例#2-依赖于AST项目

build.gradle

...
dependencies {
    ...
    compile project(':groovy-sql-transform')
    ...
}
...

settings.gradle

rootProject.name = 'project-name'

// Assumption that AST project lives at the same level as this project
include "groovy-sql-transform"
project(":groovy-sql-transform").projectDir = new File("../groovy-sql-transform")

测试

我没有创建适当的单元测试,但我确实使用了以下内容在IntelliJ中进行测试和调试,这样我就可以在AST转换代码的不同位置查看AST。AST转换项目中的示例测试Groovy脚本:

new GroovyShell(getClass().classLoader).evaluate '''

import com.company.groovy.transform.SqlAssist

@SqlAssist
class Testing {
...
}

'''
 类似资料:
  • 我目前正在尝试实现一些Groovy编译时AST转换,但遇到了麻烦: 如何为字段的赋值语句指定AST转换?i、 e.AST转换应转换以下代码: 变成类似的东西 我用这个AST构建器调用进行了尝试: 但在声明类的“init”方法中插入结果语句后,它反而插入了一个变量赋值,如 我浏览了Ast Builder TestCase中包含的示例,但它们只涵盖了类主体中的字段声明,而不是字段分配。我自己使用的尝试

  • 我正在尝试使用AST转换替换类的方法。 我首先检查该方法是否存在,然后将其删除(基于此)。 我看到集合上的大小发生了变化,但该方法仍然可以在类节点上访问。 删除该方法后,我想添加一个同名的新方法: 但是,这会导致以下错误: 正确的方法是什么? 更新:由于我打算做的就是替换该方法的现有功能,因此我创建了一个新的块语句,并使用 在现有方法上设置了它。

  • 问题内容: 我已经使用了Java编译器树api来为Java源文件生成ast。但是,我无法访问源文件中的注释。 到目前为止,我一直找不到从源文件中提取注释的方法..是否有使用编译器API或其他工具的方法? 问题答案: 通过使用getsourceposition()和一些字符串操作来解决问题(不需要正则表达式)

  • 我想在将源代码传递给编译器之前,在编译时转换java源代码。换句话说,我想创建一个能够转换的预处理器 转换为任何其他代码,如: null 我很乐意为这两种方法找到一个java代码预处理的简单示例。 有没有人认为有什么聪明的方法来进行代码转换,而不是用多个ivy模块完全改变现有的大型代码库?注释似乎是最好的方法,但我不明白该怎么做。

  • null 代码(步骤1和2): 实际上,第一个任务执行良好,并为注释处理器实现编译.class文件。它在第二个任务停止。 Ant说: Java 1.6 Ant 1.8.2

  • 我写了我自己的AST转换,它应该生成getter和setter方法(在这里创建getter方法)。但是他们不工作,不能理解原因。 使用属性创建注释 我的AST转换代码应该为注释字段创建getter方法 注释检查 在哪个地方我犯了错误? 运行结果: 线程“main”groovy中出现异常。lang.MissingMethodException:没有方法ua的签名。家插科打诨。用法实例getMyCou