Редактирование / изменение файла .java программно? (не файл .class) - PullRequest
12 голосов
/ 25 февраля 2010

Итак, вот фрагмент кода, использующий 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 / создавал его измененную копию. Есть ли способ сделать это?

Ответы [ 4 ]

11 голосов
/ 19 января 2013

Я знаю, что прошло много времени с момента публикации, но одна из наиболее доступных библиотек преобразования Java выглядит как Ложка .

С домашней страницы Spoon :

Ложка позволяет вам преобразовывать (см. Ниже) и анализировать (см. Пример) исходный код. Spoon предоставляет полную и детальную метамодель Java где любой элемент программы (классы, методы, поля, операторы, выражения ...) могут быть доступны как для чтения и модификации. Spoon принимает в качестве входного исходного кода и производит преобразованный исходный код готов к компиляции.

Обновление: Square также создала библиотеку генерации исходного кода JavaPoet , свободный API выглядит достаточно просто для понимания.

2 голосов
/ 15 марта 2017

... Я бы хотел, чтобы 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 - Из javadoc JavaParser, «Этот класс представляет всю единицу компиляции. Каждый файл Java обозначает единицу компиляции.»

ПРИМЕЧАНИЕ. В своем коде вы захотите заменить вызовы Option.get () соответствующей необязательной обработкой.

2 голосов
/ 25 февраля 2010

Вам действительно потребуется полный анализ кода, который вы хотите изменить, чтобы убедиться, что вы вставили код в правильное место. Я бы подумал, что вам лучше всего использовать существующий инструмент синтаксического анализа, который позволяет переписать код, а не пытаться что-то делать вручную.

Eclipse IDE делает что-то подобное для поддержки рефакторинга кода. Эта статья может быть полезна.

0 голосов
/ 26 февраля 2010

То, что вы хотите - это система программной трансформации . Это инструмент, который анализирует ваш исходный файл и может применить преобразования, чтобы изменить его, регенерирует исходный код с изменениями.

Система преобразования источника в источник принимает правила в виде:

lhs -> rhs  if cond

, где lhs и rhs являются шаблонами для допустимых фрагментов языка, а cond проверяет, что правило безопасно применять. (Рассмотрим «? X /? X -> 1, если? X ~ = 0»; вам нужно условие, чтобы убедиться, что деление действительно).

Одним из таких инструментов является наш DMS Software Reengineering Toolkit . DMS имеет полноценные синтаксические анализаторы C, C ++, C #, Java, COBOL, Python, PHP и ECMAScript (как и многие менее известные языки) и может напрямую применять такие правила. DMS также обеспечивает построение таблицы символов, управление и анализ потока данных, поскольку они часто полезны при определении cond для сложных правил. При желании вы также можете прибегнуть к «стандартному» процедурному интерфейсу для посещения узлов дерева и изменения AST.

...