为什么我的 Groovy AST 转换会在我的方法末尾插入 null?
Why does my Groovy AST transform insert null at the end of my method?
我编写了一个 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);
}
这行得通,但是生成的方法最后有一个奇怪的 null
语句,被 JD-GUI 反汇编(除了一个奇怪的局部变量):
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
?
我没有看过 JD-GUI,所以我不知道这个工具在理解字节码方面的能力如何,这不是来自 Java。但总的来说,反汇编程序只能在某种程度上显示 Java 代码在这种情况下的样子,绝不应该显示来自非 Java 语言的正确代码。所以如果你反汇编 Groovy.
最好不要指望正确的 Java 代码
在这种情况下,我怀疑 JD-GUI 遇到了我们尚未摆脱的解决方法。在某些情况下,我们会在方法结束处添加死代码 const_null,这就是您注意到的。我们这样做是因为如果在方法末尾使用字节码标签,验证器就会出现问题。由于死代码不会影响正确性,我们目前正在使用此解决方案。
我编写了一个 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);
}
这行得通,但是生成的方法最后有一个奇怪的 null
语句,被 JD-GUI 反汇编(除了一个奇怪的局部变量):
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
?
我没有看过 JD-GUI,所以我不知道这个工具在理解字节码方面的能力如何,这不是来自 Java。但总的来说,反汇编程序只能在某种程度上显示 Java 代码在这种情况下的样子,绝不应该显示来自非 Java 语言的正确代码。所以如果你反汇编 Groovy.
最好不要指望正确的 Java 代码在这种情况下,我怀疑 JD-GUI 遇到了我们尚未摆脱的解决方法。在某些情况下,我们会在方法结束处添加死代码 const_null,这就是您注意到的。我们这样做是因为如果在方法末尾使用字节码标签,验证器就会出现问题。由于死代码不会影响正确性,我们目前正在使用此解决方案。