为什么我的Groovy AST转换在我的方法结束时插入null?

时间:2015-11-10 09:37:16

标签: groovy metaprogramming abstract-syntax-tree

我编写了一个AST转换,为JPA映射属性创建了一个setter(它设置了本地字段并在关系的另一端调用setOwner):

private static void createSetter(FieldNode field) {
    Parameter parameter = GeneralUtils.param(field.getType(), field.getName());

    BlockStatement body = new BlockStatement();
    body.addStatement(assignS(fieldX(field), varX(parameter)));

    MethodCallExpression setterCall = callX(varX(parameter), "setOwner", varX("this", field.getDeclaringClass()));
    setterCall.setType(ClassHelper.VOID_TYPE);
    body.addStatement(stmt(setterCall));

    MethodNode method = new MethodNode(setterName(field.getName()), ACC_PUBLIC, ClassHelper.VOID_TYPE, new Parameter[] {parameter}, ClassNode.EMPTY_ARRAY, body);
    field.getDeclaringClass().addMethod(method);
}

这样可行,但生成的方法最后在JD-GUI反汇编时有一个奇怪的null语句(除了一个奇怪的局部变量):

public void setMore(Simple_MoreStuff more) {
    Simple_MoreStuff localSimple_MoreStuff = more;
    this.more = localSimple_MoreStuff;
    more.setOwner(this);
    null;
}

它似乎不会影响实际的正确性,但它很奇怪,而且它似乎是一个错误。在MethodCallExpression中,我发现了这条评论但不知道它是否相关,因为我的方法实际上是无效的(我明确地将其设置在上面,并没有区别):

//TODO: set correct type here
// if setting type and a methodcall is the last expression in a method,
// then the method will return null if the method itself is not void too!
// (in bytecode after call: aconst_null, areturn)

有没有办法让生成的方法不会出现虚假的null

1 个答案:

答案 0 :(得分:3)

我没有看过JD-GUI,所以我不知道这个工具在理解字节码方面有多么强大,而不是来自Java。但是一般来说,反汇编程序只能在某种程度上显示出这种情况下的Java代码,但绝不应该从非Java语言中显示正确的代码。因此,如果您反汇编Groovy,最好不要指望正确的Java代码。

在这种情况下,我怀疑JD-GUI无法解决我们还没有摆脱的变通方法。在几种情况下,我们在方法结束时添加了死代码,const_null,你注意到了。我们这样做是因为如果在方法结束时使用字节码标签时验证程序出现问题。由于死代码不影响正确性,我们目前正在使用此解决方案。