7

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

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

在连续的行中。我想在我的代码中查找/计算这样一个序列的总数,其中对象“某物”的名称可能不同,但我希望得到相同的处理。

我想将这些作为一种方法提取出来,并查看需要重构的所有位置。我该怎么做这样的事情?

4

4 回答 4

2

有一些现成的工具可以做到这一点,它们被称为程序转换工具

如果您真的想将这些识别为连续行,请使用我们的 DMS Software Reengineering Toolkit 程序转换引擎,使用其规则规范语言 (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";

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

模式内容在元引号中定义,以区分 RSL 模式语言文本和目标语言 (Java) 模式文本。在元引号内,\baz 表示语法类别 N 的模式变量 baz,其中 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(或其他程序转换工具)并进行设置。如果他经常这样做,或者它们分散在非常大的代码堆中,模式很复杂,或者他有许多类似的事情要做,那么权衡可能会相反。

于 2013-10-01T02:53:06.180 回答
2

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

如果您使用其重构功能将此类事件中的一个分割成一个方法,它会遍历代码库并询问您是否也想在其他地方替换它。

于 2013-09-27T06:57:10.710 回答
1

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

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

查找所有行,例如:

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

wherexyz可以是任何东西,只要第一行和最后一行相同。

于 2013-09-27T07:39:20.180 回答
1

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

于 2013-09-27T07:03:24.937 回答