Как добавить фрагмент кода в тело метода с помощью JDT/AST
Я пытаюсь сгенерировать исходный код Java с помощью JDT/AST. Теперь у меня есть MethodDeclaration и я хочу добавить фрагмент кода (из другого источника) в тело метода. Фрагмент кода может содержать любой код Java, даже синтаксически неверный код. Я просто не могу найти способ сделать это.
С JCodeModel вы бы использовали метод JBlock#directStatement(String s).
Есть ли способ сделать это с JDT/AST?
2 ответа
Поскольку у вас есть правильно сформированное дерево для остальной части приложения, и вы хотите вставить некорректно сформированный текст в определенном месте, вы почти не сможете сделать это с помощью стандартных механизмов вставки узлов дерева.
Важно то, что вы создаете текст для действительного текста программы с фрагментом, вставленным в нужном месте. Где-то там должна быть часть логики, которая печатает AST как текст. Что вам нужно сделать, это попросить, чтобы AST был напечатан в виде текста, и перехватить его в середине этого процесса, в точную необходимую точку, чтобы вставить произвольный текст.
Наш инструментарий реинжиниринга программного обеспечения DMS имеет в своем симпатичном принтере хуки входа / выхода из узла печати, позволяющие этому происходить.
Если таких вещей нет в JDT/AST, вы можете попытаться изменить его prettyprinter, чтобы получить этот хук. В качестве альтернативы вы можете рассмотреть возможность изменения JDT / AST путем добавления другого типа узла дерева, который не является частью стандартного набора, который просто содержит произвольный текст, но действует как узел метода. Предположительно, каждый узел контролирует то, что печатается; тогда вы можете определить красивую печать для этого узла дерева, чтобы заставить его выводить свой текст.
Последнее действительно хакерское решение: вставьте совершенно правильный AST, куда пойдет произвольный текст, содержащий где-то фиктивный идентификатор с уникальным именем, например, ZZZ. Затем напечатайте AST в строку и постобработайте строку, чтобы заменить поддельные деревья, содержащие уникальное имя, фактическим текстом пользователя.
Сначала вам нужно разобрать фрагмент кода в AST. Вы можете использовать ASTParser
API для этого.
Можно получить проблемы компиляции модуля компиляции (см. CompilationUnit.getProblems()
).
Есть несколько способов изменить код Java с помощью JDT. Я бы посоветовал вам рассмотреть ASTRewrite
API для модификации тела метода.
Вы можете управлять AST с помощью ASTParser API - и вывод даже не нужно компилировать.
Вот пример для вашего случая:
String textToInsert = "Some text";
StringLiteral stringLiteral = methodDeclaration.getAST().newStringLiteral();
rewriter.set(stringLiteral, StringLiteral.ESCAPED_VALUE_PROPERTY, textToInsert, null);
ListRewrite methodStatements = rewriter.getListRewrite(methodDeclaration.getBody(), Block.STATEMENTS_PROPERTY);
methodStatements.insertFirst(stringLiteral, null);
Результат:
public void myMethod() {
Some text
}