Редактирование/изменение файла .java программно? (не файл .class)
Итак, вот фрагмент кода, использующий CodeModel, который генерирует Java-код:
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/создавал измененную копию. Есть ли способ сделать это?
Ответы
Ответ 1
Я знаю, что прошло некоторое время с момента публикации, но одна из наиболее доступных для поиска библиотек преобразования Java выглядит Spoon.
Из Spoon Homepage:
Ложка позволяет вам трансформироваться (см. ниже) и анализировать (см. пример) исходный код. Spoon предоставляет полную и мелкозернистую метамодель Java где любой программный элемент (классы, методы, поля, выражения...) могут быть доступны как для чтения, так и для модификации. Ложка принимает в качестве исходного кода и производит преобразованный исходный код готовый к компиляции.
Обновление: Square также создала библиотеку генерации исходного кода JavaPoet, свободный API выглядит достаточно простым, чтобы понять.
Ответ 2
Вам действительно понадобится полный анализ кода, который вы хотите изменить, чтобы вы вставляли код в нужное место. Я бы подумал, что лучше всего использовать существующий инструмент синтаксического анализа, который позволяет переписывать код, а не пытаться делать что-то вручную.
Eclipse IDE делает что-то подобное для поддержки рефакторинга кода. Этот article может быть полезен.
Ответ 3
... Я бы хотел, чтобы API напрямую изменял файл java/создавал измененную копию. Есть ли способ сделать это?
JavaParser - это API, который позволяет вам читать файлы Java, изменять их и получать результаты в виде строки.
Более конкретно, JavaParser анализирует файл и создает AST (абстрактное синтаксическое дерево). Затем вы можете изменить JavaParser AST, представляющий ваш исходный код, используя API и получить строковое представление 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() правильной дополнительной обработкой.
Ответ 4
Что вам нужно, это система преобразования программ. Это инструмент, который анализирует ваш исходный файл и может
применять преобразования для его модификации, восстанавливает исходный код с изменениями.
Система преобразования источника в источник принимает правила вида:
lhs -> rhs if cond
где lhs и rhs являются шаблонами suce для действительных фрагментов языка, а cond проверяет правильность этого правила. (Рассмотрим "? X/? X → 1, если? X ~ = 0", вам нужно условие, чтобы убедиться, что деление действительно).
Одним из таких инструментов является наш DMS Software Reengineering Toolkit. У DMS есть полные парсеры C, С++, С#, Java, COBOL, Python, PHP и ECMAScript (как и многие менее известные языки) и могут применять такие правила напрямую.
DMS также обеспечивает сбор и контроль таблиц символов и анализ потока данных, поскольку они часто полезны при определении cond для сложных правил. Если вы хотите, вы также можете вернуться к "стандартным" процедурным интерфейсам, чтобы посещать узлы дерева и изменять АСТ.