如何使用Java Compiler Tree API (com.sun.source.util)重构源码
How do I use Java Compiler Tree API (com.sun.source.util) to reconstruct source code
我目前正在分析 Java 源代码。我通过使用编译器树 API 来解析源代码来完成 AST 分析。但是我在将新的 AST 节点(例如插入表达式或语句)添加到编译单元时遇到问题,稍后可以由 Java 编译器编译。我没有找到任何方法或 class 可以做到这一点。
我不认为 Java 编译器旨在让您从 AST 重新生成源代码。毕竟,它不需要那个。
如果要修改程序,可以考虑使用源到源program transformation system (PTS)。这些是解析源代码(构建 AST)的工具,允许您使用以已解析源代码的语法编写的源到源转换规则,对 AST 进行更改,并且 can 从 AST 重新生成源文本。
PTS 规则本质上说,"if you see this, replace it by that"。我们的 PTS(DMS 软件再造工具包)示例:
rule convert_square_to_multiply:(b: primitive_expression):product -> product
= " \b ** 2 " -> " \b * \b "
if no_side_effects(b);
此规则找到一个表达式,提高到 2 次方,并应用经典编译器 "strength reduction" 以降低计算成本。注意 b 上的额外语义检查约束;你的 PTS 必须能够帮助你实现这样的 "analyses"。
该规则适用于:
- 将已解析源程序的 AST 与规则左侧的模式隐含的 AST 相匹配 ("if you see this...")
- 匹配时,模式变量("b")绑定到相应的子树
- 正在检查 "if" 条件以验证其是否为真,
- 如果是,匹配的子树将被删除并替换为一棵树,其形状由规则右侧暗示 ("replace it by this")
所有这一切的美妙之处在于无需编写繁琐的程序代码即可在树上爬上爬下、检查节点类型、将节点拼接进出等操作 AST。源代码到源代码的重写更容易编写, 检查和维护。
如果你不会使用 PTS,你可以考虑构建你自己的 prettyprinter; see my SO answer on how to do that。我怀疑 Java 编译器捕获了足够的信息来重新生成 "pretty" 源代码;它可能足以重新生成可编译的源代码。例如,我很确定 Java 编译器 AST 不会保留注释;因此,它们将很难再生。一个标准的 PTS 捕捉并再现了所有这些东西。
我目前正在分析 Java 源代码。我通过使用编译器树 API 来解析源代码来完成 AST 分析。但是我在将新的 AST 节点(例如插入表达式或语句)添加到编译单元时遇到问题,稍后可以由 Java 编译器编译。我没有找到任何方法或 class 可以做到这一点。
我不认为 Java 编译器旨在让您从 AST 重新生成源代码。毕竟,它不需要那个。
如果要修改程序,可以考虑使用源到源program transformation system (PTS)。这些是解析源代码(构建 AST)的工具,允许您使用以已解析源代码的语法编写的源到源转换规则,对 AST 进行更改,并且 can 从 AST 重新生成源文本。
PTS 规则本质上说,"if you see this, replace it by that"。我们的 PTS(DMS 软件再造工具包)示例:
rule convert_square_to_multiply:(b: primitive_expression):product -> product
= " \b ** 2 " -> " \b * \b "
if no_side_effects(b);
此规则找到一个表达式,提高到 2 次方,并应用经典编译器 "strength reduction" 以降低计算成本。注意 b 上的额外语义检查约束;你的 PTS 必须能够帮助你实现这样的 "analyses"。
该规则适用于:
- 将已解析源程序的 AST 与规则左侧的模式隐含的 AST 相匹配 ("if you see this...")
- 匹配时,模式变量("b")绑定到相应的子树
- 正在检查 "if" 条件以验证其是否为真,
- 如果是,匹配的子树将被删除并替换为一棵树,其形状由规则右侧暗示 ("replace it by this")
所有这一切的美妙之处在于无需编写繁琐的程序代码即可在树上爬上爬下、检查节点类型、将节点拼接进出等操作 AST。源代码到源代码的重写更容易编写, 检查和维护。
如果你不会使用 PTS,你可以考虑构建你自己的 prettyprinter; see my SO answer on how to do that。我怀疑 Java 编译器捕获了足够的信息来重新生成 "pretty" 源代码;它可能足以重新生成可编译的源代码。例如,我很确定 Java 编译器 AST 不会保留注释;因此,它们将很难再生。一个标准的 PTS 捕捉并再现了所有这些东西。