静态代码分析器,检测代码模式

时间:2013-09-23 04:01:22

标签: java static-analysis

我在新的代码库中出现过多次,其中有一系列方法调用,如

object o = something.foo();
bar(o);
something.foobar();

在连续的行中。我想在我的代码中找到/计算这样一个序列的总数,其中对象“某事物”的名称可能不同,但我想要对待它。

我希望将这些作为一种方法拉出来,并查看需要重构的所有位置。我该如何做这样的事情?

4 个答案:

答案 0 :(得分:2)

Intellij IDEA(包括免费社区版)进行重复代码检测&替换。

如果你使用其重构功能将这种事件之一划分为一个方法,它会通过代码库并询问你是否要在其他地方替换它。

答案 1 :(得分:2)

现成的工具可以做到这一点,它们被称为program transformation tools

如果您真的希望将这些视为连续行,请使用我们的DMS软件重新设计工具包程序转换引擎,使用其规则规范语言(RSL)。 RSL允许您根据DMS语法已知的语言的语言语法编写模式:

domain Java~v7;

pattern odd_pattern(IDENTIFIER: o,
                    qualifier: something,
                    IDENTIFIER: foo 
                    IDENTIFIER: bar,
                    IDENTIFIER: foobar, 
                    more: stmt_sequence): stmt_sequence
= " Object \o = \something.\foo;
    \bar(\o);
    \something.\foobar();
    \more";

这根据指定表示法(“域Java~v7”)的表面语法定义了一个模式。每个模式都有一个名称(“odd_pattern”),以便您可以区分许多模式。模式具有一组强制(清晰语法)语法类别指定的子模式,命名为<(非)终端:name>。这种模式有几个不同的标识符,模式名称o,foo,bar,foobar。我猜你的意思是某种东西是某种合格的路径,但也许你的意思是它只是一个标识符。

模式内容在元引号中定义,以区分RSL模式语言文本和目标语言(Java)模式文本。在元引号内,\ baz表示语法的模式变量baz类别N其中baz在模式参数列表中被定义为N:baz。在多个地方出现的相同的模式变量需要相同的替换。

鉴于此模式,您可以询问DMS在哪里匹配(Java)AST。通过匹配AST,还有空白,注释,非标准化字符串/标识符/数字等的问题。被淘汰了。通过简单地计算匹配,您可以获得OP的原始所需指标。 [我们已基本完成了对RSL模式的扩展,其中元素通过数据流而不是代码语法连接]。

据推测,他希望这些实例转换为其他代码,他可以通过在RSL中编写来完成

 rule rewrite_odd_pattern(parms): stmt_sequence
       odd_pattern(parms) -> replacement_pattern(parms);

提及其他一些类似的“replacement_pattern”。

如果OP只有适度数量的这种模式,他可能更好地使用正则表达式或者只是将其推出而不是获得DMS(或其他程序转换工具)并进行设置。如果他做了很多,或者他们分散在大量的代码中,模式很复杂,或者他有很多类似的事情要做,权衡可能会反过来。

答案 2 :(得分:1)

如果您的代码是Java 1.6或更低版本,则可以使用Eclipse MoDisco生成Java项目的EMF model实例。然后,您可以实现Model Query来搜索您描述的模式。即使MoDisco Java模型基于Java 1.5,您也可以将其用于1.6,因为1.6中没有引入语法更改。

答案 3 :(得分:1)

你可以使用正则表达式 - 例如在Netbeans中,这个正则表达式:

(?s)object o = (.*?)\.foo\(\);\s+bar\(o\);\s+(\1)\.foobar\(\);

找到所有行:

object o = xyz.foo();
bar(o);
xyz.foobar();

其中xyz可以是任何内容,前提是它在第一行和最后一行是相同的。