2010-02-25 12 views
11

Więc tutaj jest kawałek kodu z wykorzystaniem CodeModel który generuje kod Java:Edytowanie/modyfikowanie pliku .java programowo? (Nie plik .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); 

Ten kod generuje plik .java:

package foo; 
public class Bar { 

     int foo() { 
     return 5; 
    } 
} 

Ja jednak DO NOT chcę, aby CodeModel utworzył dla mnie nowy plik java. Mam już plik .java i chciałbym dodać kilka linii kodu do metody w nim zawartej. Dlatego chciałbym, aby interfejs API bezpośrednio zmodyfikował plik java/utworzył zmodyfikowaną jego kopię. Czy jest jakiś sposób na zrobienie tego?

+0

Posiadanie klas częściowych [z C#] w Javie w pewnym stopniu pomoże ... – Fakrudeen

+0

@Frude Wypowiedz proszę. – Jay

+0

C# umożliwia definicje klas do rozpiętości wielu plików. Jeśli zmiany są tylko addytywne, możesz zdefiniować je [generuj] w innym pliku, zamiast modyfikować istniejący plik. Wszystko to jest dla ciebie dyskusyjne, ponieważ java nie ma klas częściowych. Dlatego dodałem go jako komentarz. – Fakrudeen

Odpowiedz

10

Wiem, że minęło trochę czasu od pierwotnego wpisu, ale jedną z bardziej dostępnych bibliotek transformacji Java wydaje się być Spoon.

Z Spoon Homepage:

Łyżka pozwala na przekształcenie (patrz niżej) i analizy (patrz przykład) kodu źródłowego. Łyżka zapewnia kompletny i dokładny metamodel Java , w którym każdy element programu (klasy, metody, pola, instrukcje, wyrażenia ) może być dostępny zarówno do odczytu, jak i modyfikacji. Łyżka przyjmuje kod źródłowy i generuje przetworzony kod źródłowy gotowy do kompilacji.

Aktualizacja: Plac również stworzył bibliotekę generacji JavaPoet kodu źródłowego, płynna API wygląda dość proste do zrozumienia.

+1

nawet nie pamiętam, dlaczego zadałem to pytanie :) .. dzięki za odpowiedź - i tak nagradzam twoją odpowiedź! – Jay

+1

Czy JavaPoet może odczytać istniejący kod źródłowy? Nie mogę znaleźć żadnej wzmianki o tym w przeglądaniu JavaPoet README.md. – JohnC

+1

@JohnC, przepraszam, nie użyłem JavaPoet w gniewie, ale z tego, co mogę zebrać, Łyżka wydaje się lepiej pasować do twoich wymagań. Nie ma powodu, aby nie łączyć dwóch bibliotek w celu modyfikacji i czystej generacji (tj. Odpowiedniego narzędzia do właściwej pracy). –

2

Naprawdę będziesz potrzebować pełnej analizy kodu, który chcesz zmodyfikować, aby zapewnić wstawienie kodu do właściwej lokalizacji. Pomyślałem, że najlepiej będzie użyć istniejącego narzędzia do analizy, które pozwoli przepisać kod, zamiast próbować zrobić coś ręcznie.

Eclipse IDE robi coś takiego w celu obsługi refaktoryzacji kodu. Ta article może być pomocna.

-1

Co chcesz to program transformation system. To jest narzędzie, które analizuje plik źródłowy i może zastosować transformacje, aby je zmodyfikować, a następnie zregeneruje kod źródłowy z modyfikacjami.

System transformacja źródła do źródła akceptuje zasady formie:

lhs -> rhs if cond 

gdzie LHS i RHS są sosie wzorce dla ważnych fragmentów języka i cond kontroli że zasada jest bezpieczna. (Rozważ "? X /? X -> 1 if? X ~ = 0"; potrzebujesz warunku, aby sprawdzić, czy podział jest ważny).

Jednym z takich narzędzi jest nasz DMS Software Reengineering Toolkit. DMS posiada pełne parserów C, C++, C#, Java, COBOL, Python, PHP i ECMAScript (podobnie jak wiele mniej znanych języków) i może bezpośrednio stosować takie reguły. DMS zapewnia również konstrukcję tablic symboli i kontrolę oraz analizę przepływu danych, ponieważ są one często przydatne przy definiowaniu cond dla złożonych reguł. Jeśli chcesz, możesz również wrócić do "standardowego" interfejsu proceduralnego, aby odwiedzić węzły drzewa i zmodyfikować AST.

+0

@Ira thanks. Patrzę jednak na wykorzystanie rzeczy otwartych, a nie komercyjnych. – Jay

+0

Cóż, możesz wypróbować TXL http://www.txl.ca lub Stratego http://www.strategoxt.org, które są również systemami transformacji programów, które mają reguły przepisywania źródła na źródło. To, czego nie mają, to, co uważam za niezbędne, jest transformacja proceduralnych języków, to tablica symboli i narzędzia analizy przepływu. Stwierdziliśmy, że są one niezbędne do przeprowadzenia rzetelnej transformacji programowej na dużą skalę. Możesz spróbować je wdrożyć samodzielnie w narzędziach OSS, ale wymaga to dużo pracy. YMMV. –

+0

Wow. 7-letnia odpowiedź, która odnosi się bezpośrednio do pytania OP-u, w tym do zapewnienia alternatyw dla open source, gdy OP jasno to wyraził w swoim komentarzu ... i * teraz * powoduje obniżenie wartości? Nie sądzę, by spadkowcy byli gotowi wyjaśnić, dlaczego go zarzucili. –

2

... Chciałbym, aby interfejs API bezpośrednio zmodyfikował plik Java/utworzył zmodyfikowaną kopię tego pliku. Czy jest jakiś sposób na zrobienie tego?

JavaParser to API, które pozwala na czytanie w plikach Java, modyfikowanie ich i uzyskiwanie wyników w postaci ciągu.

Dokładniej, JavaParser analizuje plik i buduje AST (abstrakcyjne drzewo składniowe). Następnie możesz zmodyfikować AST JavaParser reprezentujący twój kod źródłowy za pomocą API i pobrać reprezentację String AST.

Mam już plik .java i chcę dodać kilka linii kodu do metody w nim zawartej.

Oto przykład użycia JavaParser aby dodać linię na końcu ciała metody i wydrukować wynik:

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 - Z javadoc JavaParser za „Klasa ta reprezentuje całą kompilację Jednostka Każdy plik java oznacza jednostkę kompilacji. "

UWAGA: W kodzie należy zamienić wywołania Option.get() z odpowiednią opcjonalną obsługą.

+1

Twoja odpowiedź nie wyjaśniła mi, czy wygenerowany kod źródłowy będzie oryginalny, ale z lokalnymi modyfikacjami. Pytanie wymaga minimalnych modyfikacji, prawdopodobnie w celu zapobieżenia wielu konfliktom kontroli wersji. – neves

Powiązane problemy