自动重构工具,为Java / Javascript找到类似的重复源代码?

我正在寻找一种工具来查找重复或类似的Java / Javascript代码。 我不能说出“ 相似 ”的确切定义,但我希望该工具足够聪明,并给我建议重构代码,例如,

(1)A类和B类有相似的方法(例如,有5个方法在两个类中都有相同的方法名,参数和类似的实现),那么它应该建议将这些类似的方法移到基类中。
(2)A类在不同的地方有多次相似的代码行,工具应该建议将这些相似的代码行移动到一个方法中。

我试过PMD可以找到重复的代码行,但它不够聪明。 它没有找到那些在我的项目中广泛传播的类似源代码。

有这样的工具吗?

我们的CloneDR工具通过比较解析器中的抽象语法树来查找重复的代码。 (它包含许多语言的特定语言版本,包括Java和JavaScript)。

这意味着它可以找到克隆的代码,尽管格式改变和克隆体的修改,这两者通常在克隆时完成。 找到的克隆匹配语言概念,例如表达式声明语句函数甚至 。 报告相似的克隆以及作为建议参数的差异/变化点。

它可以找到具有多个实例的克隆集(我们的一些应用程序具有数百个单个代码的克隆),并且它可以在许多源文件中找到克隆。

它生成可由人们直接读取的HTML报告,以及可由其他下游工具处理的XML报告。 (您可以通过链接查看一些示例HTML报告)。

相似性很难定义,实际上您可以通过多种方式定义它。 CloneDR将其定义为克隆集中相同元素(技术上,AST节点)的比率除以克隆集中的元素总数。 该比率是介于0和1之间的值。将其与阈值进行比较; 我们发现,就报告的克隆质量而言,95%作为阈值令人惊讶地强大。

为有趣的克隆建立最小大小很有用。 a*bx*y的克隆(带有2个参数),但由于它太小而无法报告。 CloneDR也使用我们称之为“行数”的大小阈值,但实际上是元素中克隆的大小除以整个代码库中每行的平均元素数。 这会生成通常具有比阈值更多的行的克隆,但是它会找到一行中的巨大表达式的克隆。 我们发现5-6“线”在报告的克隆质量方面也相当稳健。

该表显示了将CloneDR的AST匹配方法与许多其他克隆检测工具(将其“非常好”排名)进行比较的有效性。 唯一接近的是CCDIML …. 这是CloneDR方法的学术重新实现。 还有其他方法(即基于PDG的方法)可以检测更有效地散布的克隆,但实际上,根据我的个人经验,克隆代码的人通常不会将克隆的部分切割成一堆独立的部分。分散他们; 他们太懒了。 因人而异。

在此处输入图像描述

[表来自:Roy,Cordy,Koschke:代码克隆检测技术和工具的比较和评估:定性方法,计算机程序设计科学,第74卷,第7期,2009年5月。本文概述了许多不同的克隆检测方法并评估它们的效力。]

[PMD未列出,但根据上表显然使用Rabin-Karp字符串匹配,“基于文本”,而不是AST匹配。]

Re OP的要求:

如果这些方法在不同的类中以不同的顺序出现,CloneDR(实际上没有我知道的工具)将不会在多个方法中找到一组类似的方法。 在这种情况下,CloneDR更有可能将各个方法报告为克隆; 最终结果是一样的。 如果成员在不同的类中以相同的顺序顺序出现,它将找到这样的集合,就像从一个类体被批量复制时发生的那样。

跨多种方法的类似代码块通常被检测到。 生成的报告显示了相似代码块是如何相关的,包括代码的抽象版本,它本质上是方法体所需的参数化代码块。

你绝对可以看看猿猴 。
据我所知,它或多或少只能用于构建服务器。
您也可以通过命令行执行它,或者将其集成到像ant这样的本地构建工具中。

它有多个选项可供配置,例如需要多少行来“识别”副本等等。 唯一不是最好的是IMHO生成的输出(xml),但我认为这也是可配置的。

希望这可以帮助 !

编辑 :PMD确实是一个非常好的工具,也许尝试与simian一起使用它。 PMD也非常好地支持将它作为插件集成到IDE或编辑器中。

我之前没有使用过IntelliJ IDEA ,但我发现它支持使用它的ulimate版本分析Duplicates 。