Tree Differencer 标识树级别的更改基于抽象语法树的 Differencer 首先负责在两个源文件之间识别实际的编辑痕迹,例如针对同一文件的连续修订。举例来说,它会检测以下粒度的编辑:使用 if 打包语句、添加的 @Nullableannotation 或者 import,以及将条件提前返回至某一现有方法之内等等。在以下示例中,插入条件判断语句 if dog is null 并提前返回、将 public 重新命名为 private、方法的移动都会被检测为实际编辑。而基于行的 diffing 工具只会将方法标记为完全移除与插入,Tree Differencer 则能够检测到这一移动并将移动方法之内的插入操作视为实际编辑。
Tree Differencer 的主要挑战在于如何有效且精确地对树级别中的“之前”与“之后”部分进行对齐,从而识别出正确的实际编辑及其映射关系。
新的修复模式挖掘方法Getafix 通过利用新的层次聚类技术以及反合一方法(即一种能够在不同符号表达式之间实现泛化的现有方法)进行模式挖掘。在此之后,它会建立可能相关的树差异集合,进而选择该集合中最为常见的程序并转换为修复模式。这些模式可能是抽象的,且包含程序转换所面向的不同“漏洞”。
以下示例图像展示了一组层次结构,即树状图,其通过一组编辑生成。(在本示例中,我们直接采用上个示例中的编辑结果。)每一行皆展示出一种编辑模式——其中紫色代表“之前”,蓝色代表“之后”——以及一些元数据。每个垂直黑条对应于层次结构中的具体层级,其中黑条顶部的编辑模式代表着通过对该结构中所有同一层级的其它编辑进行反合一所获得的模式。其它编辑由较细的黑色线条连接。反合一将来自上一示例中的“如果 dog 为 null 则提前返回”条件与另一条编辑相结合——后者的唯一区别在于“dog 正在饮水”。结果是,其将生成一个代表共性的抽象修复模式。由反合一引入的符号 h0 代表着可以基于上下文实现实例化的“漏洞”。