2010-02-25 133 views
11

所以,在這裏是一塊使用CodeModel代碼生成Java代碼:以編程方式編輯/修改.java文件? (未.class文件)

JCodeModel cm = new JCodeModel(); 
    JDefinedClass dc = cm._class("foo.Bar"); 
    JMethod m = dc.method(0, int.class, "foo"); 
    m.body()._return(JExpr.lit(5)); 
    File f = new File("C:/target/classes"); 
    f.mkdirs(); 
    cm.build(f); 

此代碼生成一個.java文件:

package foo; 
public class Bar { 

     int foo() { 
     return 5; 
    } 
} 

然而,我不要希望CodeModel爲我創建一個新的Java文件。我已經有一個.java文件,並且希望在其中添加幾行代碼。所以,我希望API直接修改java文件/創建它的修改副本。有沒有辦法做到這一點?

+0

在java中部分類[C#]會在一定程度上有所幫助... – Fakrudeen 2010-02-25 17:23:02

+0

@Fakrudeen請詳細說明。 – Jay 2010-02-26 14:19:24

+0

C#允許類定義跨越多個文件。如果更改只是附加的,您可以在不同的文件中定義[生成]它們,而不是修改現有的文件。所有這些都對你沒有意義,因爲java沒有部分類。這就是爲什麼我添加它作爲評論。 – Fakrudeen 2010-02-26 16:05:42

回答

10

我知道這已經有一段時間了,但最容易看的Java轉換庫之一看起來是Spoon

Spoon Homepage

勺使您能夠變換(見下文)和分析(見實施例) 源代碼。 Spoon提供了一個完整的細粒度Java元模型,其中任何程序元素(類,方法,字段,語句,...)都可以被訪問以供讀取和修改。 勺子作爲輸入源代碼併產生準備編譯的轉換後的源代碼 。

更新:方也創造了JavaPoet源代碼生成庫,流暢的API看起來很簡單的把握。

+1

甚至不記得爲什麼我問這個問題:) ..謝謝你回答 - 無論如何我會獎勵你的答案! – Jay 2013-01-19 17:05:38

+1

JavaPoet可以讀取現有的源代碼嗎?在撇取JavaPoet README.md時,我找不到任何提及。 – JohnC 2016-03-11 21:54:54

+1

@JohnC,對不起,我沒有在憤怒中使用過JavaPoet,但從我能收集的信息來看,Spoon似乎更適合您的需求。沒有理由不把2個庫合併爲修改和純代(即適合正確工作的正確工具)。 – 2016-03-18 12:42:05

2

您確實需要對您要修改的代碼進行完整分析,以確保您將代碼插入到正確的位置。我認爲你最好的選擇是利用現有的解析工具,它允許代碼被重寫,而不是嘗試手工做某件事。

Eclipse IDE執行類似的操作來支持代碼重構。這article可能會有所幫助。

-1

你想要的是一個program transformation system。這是一個解析你的源文件的工具,並且 可以應用轉換來修改它,並通過修改重新生成源代碼。

甲源到源變換系統接受的形式的規則:

lhs -> rhs if cond 

其中LHSRHS是用於該語言的有效片段和COND檢查烴源模式該規則可以安全地應用。 (如果?x〜= 0,則考慮「?x /?x - > 1;您需要條件來驗證除法是否有效)。我們的DMS Software Reengineering Toolkit。 DMS具有完整的C,C++,C#,Java,COBOL,Python,PHP和ECMAScript前端解析器(可以使用許多較少的已知語言),並且可以直接應用這些規則。 DMS還提供了符號表結構和控制以及數據流分析,因爲這些常常用於爲複雜規則定義一個條款。如果你願意,你也可以回到一個「標準」程序界面來訪問樹節點並修改AST。

+0

@Ira謝謝。然而,我正在使用開源的東西,而不是商業的東西。 – Jay 2010-02-26 14:18:17

+0

那麼,你可以試試TXL http://www.txl.ca或Stratego http://www.strategoxt.org,它們也是程序轉換系統,它們有源碼到源碼的重寫規則。他們沒有的東西,我相信是程序語言轉換的基本必要條件,是符號表和流程分析工具。我們發現這些對於進行可靠的大規模程序轉換是不可或缺的。你可以嘗試在OSS工具中自己實現這些,但是它需要很多工作。因人而異。 – 2010-02-26 14:28:34

+0

哇。 7年的答案,這直接解決了OP的問題,包括當OP在他的評論中明確提供開源替代品時......並且*現在*它繪製了低價提議?我不認爲downvoters願意解釋他們爲什麼downvoted。 – 2016-12-31 17:31:36

2

...我想API直接修改java文件/創建它的修改副本。有沒有辦法做到這一點?

JavaParser是一個API,允許您讀取Java文件,修改它們,並以String形式獲取結果。

更具體地說,JavaParser解析文件並構建AST(抽象語法樹)。然後,您可以使用API​​修改表示源代碼的JavaParser AST並檢索AST的字符串表示形式。

我確實已經有一個.java文件,並且希望向其中的一個方法添加幾行代碼。

下面是使用JavaParser類添加一行到方法本體的端部和打印結果的示例:

class MyClass { 
    public static void someMethod() { 
     /* ... */ 
     // Lines will be added here: 
    } 

    public static void main(String[] args) { 
     String newStatement = "System.out.println(\"Hello world!\");" 
     File myClassSourceFile = new File("MyClass.java"); 
     CompilationUnit cu = JavaParser.parse(myClassSourceFile); 
     ClassOrInterfaceDeclaration classDeclaration = cu.getClassByName("MyClass").get(); 
     MethodDeclaration method = classDeclaration.getMethodsByName().get(0); 
     method.getBody().get().addStatement(newStatement); 

     // Print out the resulting Java source code. 
     System.out.println(cu.toString()); 
    } 
} 

CompilationUnit - 從JavaParser類的Javadoc,「此類表示整個編譯單位。每個java文件表示一個編譯單元。「

注意:在您的代碼中,您需要用適當的可選處理來替換Option.get()調用。

+1

如果生成的源代碼是原始代碼,但通過本地化修改,您的回答並未向我明確表示。該問題要求進行最小限度的修改,可能會阻止很多版本控制衝突。 – neves 2018-03-03 21:28:41