17

我正在尝试使用 JDT/AST 生成 Java 源代码。我现在有MethodDeclaration并想将代码片段(来自另一个来源)添加到方法主体。代码片段可以包含任何 Java 代码,甚至是语法无效的代码。我只是找不到这样做的方法。

使用 JCodeModel 您将使用JBlock#directStatement(String s) 方法

有没有办法用 JDT/AST 做到这一点?

4

3 回答 3

9

由于您为应用程序的其余部分提供了格式良好的树,并且您想在特定位置插入格式不正确的文本,因此使用标准的树节点插入机制几乎无法做到这一点。

重要的是您为有效的程序文本生成文本,并在正确的位置插入片段。在某处必须有一段逻辑将 AST 打印为文本。您需要做的是要求将 AST 打印为文本,并在该过程的中间捕获它,在必要的精确点插入您的任意文本。

我们的 DMS Software Reengineering Toolkit 在其漂亮的打印机中具有进入/退出打印节点挂钩,以允许这种事情发生。

如果 JDT/AST 中不存在这样的东西,你可以尝试修改它的 prettyprinter 来给你那个钩子。或者,您可以考虑通过添加不属于标准集的另一种树节点类型来修改 JDT/AST,它只包含任意文本但行为类似于方法节点。大概每个节点都控制打印的内容;然后您可以为该树节点定义漂亮打印,以使其输出其文本。

最后一个非常老套的解决方案:在任意文本所在的位置插入一个完全有效的 AST,其中包含一个具有唯一名称的虚假标识符,例如 ZZZ。然后,将 AST 打印为字符串,并对字符串进行后处理,以将包含唯一名称的虚假树替换为实际的用户文本。

于 2012-12-16T06:46:33.730 回答
3

您首先需要将代码片段解析为 AST。您可以ASTParser为此目的使用 API。

可能会遇到编译单元的编译问题(请参阅 参考资料CompilationUnit.getProblems())。

有几种方法可以使用 JDT 修改 Java 代码。我建议您考虑使用ASTRewriteAPI 来修改方法的主体。

于 2012-12-12T19:19:10.983 回答
1

您可以使用 ASTParser API 操作 AST - 甚至不必编译输出。

这是您的案例的示例:

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
}
于 2020-04-11T13:04:06.220 回答