Как добавить фрагмент кода в тело метода с помощью 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
}
Другие вопросы по тегам