0

我有这个类实现 ASTTransformation 并为每个标有特定注释的字段创建一个 getter 和 setter 方法:

@GroovyASTTransformation(phase=CompilePhase.SEMANTIC_ANALYSIS)
public class Rewriter implements ASTTransformation {
public void visit(ASTNode[] nodes, SourceUnit source) {
    List fields = nodes.findAll { it instanceof FieldNode }
    fields.each {
        MethodNode get = createGetter(it)
        MethodNode set = createSetter(it)
        source.getAST().addMethod(get)
        source.getAST().addMethod(set)
    }
}

private MethodNode createGetter(FieldNode f) {
    Parameter[] parameters = []
    ClassNode[] exceptions = []
    Statement state = new AstBuilder().buildFromString("return ${f.name}").get(0)
    return new MethodNode("get" + f.name.capitalize(), Opcodes.ACC_PUBLIC, ClassHelper.make(f.getType().name), parameters, exceptions, state)
}

private MethodNode createSetter(FieldNode f) {
    Parameter[] parameters = [
        new Parameter(ClassHelper.make(f.getType().name), f.name)
    ]
    ClassNode[] exceptions = []
    Statement state = new AstBuilder().buildFromString("this.${f.name} = ${f.name}").get(0)
    return new MethodNode("set" + f.name.capitalize(), Opcodes.ACC_PUBLIC, ClassHelper.VOID_TYPE, parameters, exceptions, state)
    }
}

运行以下测试类

class Main {
    @Accessors
    int counter = 5

    public static void main(String[] args) {
            println getCounter()
    }
}

产生以下错误:

org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
User\groovy\meta\src\Main.groovy: -1: Invalid duplicate class definition of class Main : The source User\groovy\meta\src\Main.groovy contains at least two definitions of the class Main.
One of the classes is an explicit generated class using the class statement, the other is a class generated from the script body based on the file name. Solutions are to change the file name or to change the class name.
@ line -1, column -1.
1 error

这是什么原因造成的?它似乎创建了方法并将它们添加到源的 AST 中。我正在使用 Groovy-Eclipse 4.3

4

1 回答 1

1

您非常接近进行有效的 AST 转换。以下是我查看和测试您的代码的一些观察结果。

  • 在该visit方法中,

    source.getAST().addMethod(...)
    

    似乎是MultipleCompilationErrorsException你所看到的来源。将其替换为

    it.declaringClass.addMethod(...)
    
  • 此外,在Main类中,您将需要在static main方法中创建一个实例:println new Main().getCounter()should to the trick。

  • 您的 get 和 set 方法与 groovy 提供的默认 get 和 set 方法相同。即使你以后想改变它,现在也很难测试,因为没有办法知道正在使用的是你的 AST 转换还是 groovy 提供的方法。因此,您至少应该暂时将行为更改为“非标准”(或更改方法名称)。我通过在 getter 的返回值中插入“+1”来测试代码。

  • 最后一点,这可能是一个品味问题:我认为如果注释和 AST 转换具有“匹配”的名称会更清楚。即我将重命名RewriterAccessorsASTTransformation.

于 2013-11-04T17:09:52.780 回答