2015-11-10 59 views
1

我寫了AST變換創建一個JPA映射屬性的設置(這兩種設置本地現場和關係的另一端調用setOwner):爲什麼我的Groovy AST在我的方法轉換的末尾插入空?

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生成的方法?

回答

3

我沒有看過JD-GUI,所以我不能說這個工具在理解字節碼方面的能力有多強,它不是來自Java。但總的來說反彙編只能稍微展示一下在這種情況下,Java代碼可能看起來像,絕不意味着它應該從非Java語言顯示正確的代碼。因此,如果您反彙編Groovy,那麼最好不要指望正確的Java代碼。

在這種情況下,我懷疑JD-GUI在我們還沒有擺脫的解決方法上絆倒了。在幾種情況下,我們在方法末尾添加了死代碼,const_null,你已經注意到了。如果一個字節碼標籤在方法結束時使用,我們這樣做是因爲與驗證問題。而且由於死代碼不會影響正確性,所以我們正在使用此解決方案。

+0

我注意到,自動添加的無聊setter是簡單的'this.x = param'形式,沒有別的。爲什麼該代碼避免冗餘? – chrylis

+0

因爲我們設法避免了某些情況下的死代碼部分。要清楚:這個死代碼是不是真的需要。正是在那裏,以滿足主要驗證和不能夠做的字節碼地址的重排,以避免這種情況的需要字節碼後端的內部結構的結果。所以在某些情況下,代碼是寫入的,而在其他情況下則不是。 – blackdrag

相關問題