使用Eclipse JDT AST Rewrite以编程方式修改现有Java源代码作为独立应用程序

时间:2013-10-15 16:05:49

标签: java eclipse code-generation eclipse-jdt

我有一个现有的Java应用程序,其中包含我想以编程方式修改的源文件。我需要能够对源文件进行分析,并根据该分析执行源转换。我还需要能够理解不同源文件之间的关系。我还想将此过程创建为独立的Java应用程序。

做一点研究我发现了以下工具:代码模型& Eclipse JDT。我确定还有其他人。我已经排除了代码模型,因为它(据我所知)只允许生成新代码,不适用于现有代码。

Eclipse JDT库似乎符合我的所有需求。我能够轻松地解析源文件。我可以配置绑定,以便保留跨类型的信息。我现在遇到的问题是让ASTRewrite功能正常工作。看来(从我读过的例子和文档中)它只能在eclipse插件中运行。当我尝试使用重写器时,我收到以下错误:

java.lang.IllegalArgumentException: This API can only be used if the AST is created from a compilation unit or class file 

我可以在独立应用程序中使用ASTRewrite功能,还是需要开始查看其他工具?

2 个答案:

答案 0 :(得分:6)

由于您没有提供任何代码,我无法给您一个明确的答案,但ASTRewrite即使在 Eclipse “生态系统”之外使用也能正常工作。 您很可能使用错误的方法在AST上应用更改。 为了使其工作,请执行以下操作

将整个java文件读入字符串并从中创建org.eclipse.jface.text.Document

final String source = FileUtils.readFileToString(javaSRC);
org.eclipse.jface.text.Document document = new org.eclipse.jface.text.Document(source);

现在,您可以创建 ASTParser ASTRewriter 的实例,并将解析器的来源设置为您刚刚创建的文档。

ASTParser parser = ASTParser.newParser(AST.JLS4);
parser.setSource(document.get().toCharArray());
parser.setKind(ASTParser.K_COMPILATION_UNIT);

final CompilationUnit cu = (CompilationUnit) parser.createAST(null);
ASTRewrite rewriter = ASTRewrite.create(cu.getAST());   

cu.recordModifications();

完成所有修改后,请调用正确的重写方法,即:public TextEdit rewriteAST(IDocument document,Map options)

在此之后,您可以应用更改,并且(如果您愿意)也将更改写回文件。

TextEdit edits = rewriter.rewriteAST(document,null);
edits.apply(document);
FileUtils.write(javaSRC, document.get());

顺便说一句:我用以下的罐子测试了这段代码:

org.eclipse.osgi_3.8.2.v20130124-134944.jar

org.eclipse.jdt.core_3.8.3.v20130121-145325.jar

org.eclipse.equinox.preferences_3.5.1.v20121031-182809.jar

org.eclipse.equinox.common_3.6.100.v20120522-1841.jar

org.eclipse.core.runtime_3.8.0.v20120912-155025.jar

org.eclipse.core.resources_3.8.1.v20121114-124432.jar

org.eclipse.core.jobs_3.5.300.v20120912-155018.jar

org.eclipse.core.contenttype_3.4.200.v20120523-2004.jar

答案 1 :(得分:3)

我没有完成项目,但我整理了一个使用概念的概念验证工具:

  1. TattleTale用于类依赖。
  2. JavaParser用于分析代码。
  3. JavaParser给我留下了特别深刻的印象,TattleTale做了我需要做的事情。 JavaParser当然能够动态更改代码。

    显然,您需要罐子和来源,TattleTale适用于罐子,JavaParser适用于来源。