java - 如何使用 Java Compiler Tree API (com.sun.source.util) 重构源代码

标签 java abstract-syntax-tree javaparser

我目前正在分析Java源代码。我通过使用 Compiler Tree API 来解析源代码来完成 AST 分析。但是我在向编译单元添加新的 AST 节点(例如插入表达式或语句)时遇到问题,该编译单元稍后可以由 Java 编译器编译。我没有找到任何方法或类可以做到这一点。

最佳答案

我不认为 Java 编译器的设计目的是让您从 AST 重新生成源代码。毕竟,它没有这个必要。

如果你想修改程序,你可以考虑使用源到源 program transformation system (PTS) 。这些是解析源代码(构建 AST)的工具,允许您使用以解析源代码的语法编写的源到源转换规则,对 AST 进行更改,并且可以重新生成来自 AST 的源文本。

PTS 规则本质上是说,“如果您看到这个,请将其替换为那个”。我们的 PTS(DMS 软件重组工具包)的示例:

rule convert_square_to_multiply:(b: primitive_expression):product -> product
  =  "  \b ** 2 "  ->   " \b * \b " 
  if no_side_effects(b);

此规则查找一个表达式,求 2 次方,并应用经典的编译器“强度缩减”以使其计算成本更低。注意 b 上额外的语义检查约束;您的 PTS 必须能够帮助您实现此类“分析”。

该规则的工作原理是:

  • 将已解析源程序的 AST 与规则左侧模式隐含的 AST 进行匹配(“如果您看到这个...”)
  • 匹配时,模式变量(“b”)绑定(bind)到相应的子树
  • 检查“if”条件以验证其是否正确,
  • 如果是这样,则匹配的子树将被删除并替换为形状由规则右侧暗示的树(“用此替换它”)

所有这一切的美妙之处在于对 AST 的操作,无需编写繁琐的程序代码来在树上爬上爬下、检查节点类型、拼接节点进出等。源到源的重写更容易编写、检查并维护。

如果您无法使用 PTS,您可以考虑构建自己的 pretty-print ; see my SO answer on how to do that 。我怀疑 Java 编译器是否捕获了足够的信息来重新生成“漂亮”的源代码;它可能足以重新生成可编译的源代码。举个例子,我很确定 Java 编译器 AST 不会保留注释;因此,它们将很难再生。标准 PTS 捕获并再现所有这些内容。

关于java - 如何使用 Java Compiler Tree API (com.sun.source.util) 重构源代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29572742/

相关文章:

java - 在 JavaParser 中获取继承类的名称

java - 使用 Javaparser 访问 Javadoc 返回 null

java - 帮助在多个线程上运行 Java runtime.exec()

java - 按下 JButton 时尝试更改图像

Python ast 包 : traversing object hierarchies

java - 将 ANTLR 解析规则映射到用于代码生成的自定义 Java AST 类

java - 如何使用 Javaparser 解析 for 循环?

java - 为什么字段似乎在构造函数之前被初始化?

java - 如何在 JavaFX 中设置 tableView 的行前景色?

c++ - 如何从 clang AST 节点打印源位置