如何使用JDT/AST将代码片段添加到方法体中

17

我正在尝试使用JDT/AST生成Java源代码。现在我有一个MethodDeclaration,想要将另一个源中的代码片段添加到该方法体中。该代码片段可以包含任何Java代码,即使是语法无效的代码。我只是找不到如何做到这一点。

使用JCodeModel,你可以使用JBlock#directStatement(String s)方法

在JDT/AST中是否有实现此功能的方法?


2
AST 操作通常需要你拥有语法上有效的树。如果你对该方法使用无效代码,一般来说,你就没有一个有效的树可以插入,要么你将无法完成操作,要么你将能够完成操作,但只会得到一个荒谬的树作为结果。 - Ira Baxter
好的,JST/AST 似乎不是合适的工具... - Morrandir
为什么需要插入无效代码? - Ira Baxter
我正在实现教育软件,其中UML活动图(由学生创建)应该被翻译成Java源代码。在图表编辑器中,可以定义带有任意Java代码的操作节点,这些代码需要按原样出现在生成的代码中。 - Morrandir
然后您可以解析代码,如果它没有错误,就可以使用它,并将其作为注释插入,如果有错误。 - Ira Baxter
显示剩余3条评论
3个回答

9
由于您已经为应用程序的其余部分拥有一个格式良好的树形结构,并且您想要在特定位置插入非格式良好的文本,因此您几乎无法使用标准树节点插入机制来完成此操作。
重要的是,您要生成包含插入片段的有效程序文本的文本。其中必须有一段逻辑来将AST打印为文本。您需要做的是要求将AST打印为文本,并在必要的精确点捕获它,以插入任意文本。
我们的DMS软件再造工具包在其漂亮的打印机中具有进入/退出打印节点钩子,以允许发生这种事情。
如果JDT / AST中不存在这样的东西,则可以尝试修改其漂亮的打印机以提供该钩子。或者,您可以考虑通过添加另一个不属于标准集的树节点类型来修改JDT / AST,该节点类型仅包含任意文本但像方法节点一样运行。假定每个节点都控制打印内容;然后,您可以定义该树节点的漂亮打印,以使其输出其文本。
最后一个真正的hacky解决方案:在将插入任意文本的地方插入一个完全有效的AST,其中包含某个具有唯一名称的虚假标识符,例如ZZZ。然后,将AST打印到字符串中,并对该字符串进行后处理,以替换包含唯一名称的虚假树的树,以包含实际用户文本。

3

我之前查看了API参考文档,但是没有找到添加任意代码片段的方法。请注意,代码片段可能包含语法无效的代码。(我刚刚将这句话添加到原始问题中...) - Morrandir
您可以解析任意代码片段,然后将生成的AST节点插入到方法体的AST节点中。Eclipse解析器在一定程度上容忍语法错误。 - reprogrammer
“在某种程度上”不够,很遗憾。:( - Morrandir
我添加了我的答案,包括获取编译问题指针的方法。 - reprogrammer
这不是关于检索编译问题的。提问者想要将包含编译错误的代码添加到AST中。我认为使用任何标准的JDT操作技术都不可能实现这一点。 - Unni Kris

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
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接