Question

I have a number of occurrences in a new code base where there are a sequence of method calls like,

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

in consecutive lines. I would like to find / count the total number of such a sequence in my code where the name of object "something" could be different, but I want treated the same.

I want to pull these out as a method and see all the locations where this needs to be refactored. How do I go about doing something like this?

Was it helpful?

Solution 3

You could use a regex - for example in Netbeans, this regex:

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

finds all lines like:

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

where xyz can be anything, provided it is the same on the first and last line.

OTHER TIPS

Intellij IDEA (incl. the free community version) does duplicated code detection & replacement.

If you carve out one of such occurrence into a method using its refactoring feature, it goes through the code base and asks you if you want to replace it in other places, too.

There are tools that can do this off-the-shelf, and they are called program transformation tools.

If you really want to recognize these as consecutive line, with our DMS Software Reengineering Toolkit program transformation engine, using its Rule Specification Language (RSL). RSL lets you write patterns in terms of the language syntax of a language whose grammar is already known to 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";

This defines a pattern in terms of the surface syntax of the designated notation ("domain Java~v7"). Each pattern has a name ("odd_pattern") so that you can distinguish between many patterns. A pattern has a set of forced (clean grammar) syntax-category specified sub-patterns, named as <(non)terminal:name>. This pattern has several distinct identifiers, pattern-names o, foo, bar, foobar. I guessed you meant that something was some kind of qualifying path, but maybe you meant it to be just an identifier, too.

The pattern contents are defined in meta quotes " to distinguish the RSL pattern language text from the target language (Java) pattern text. Inside the meta quotes, \baz means the pattern variable baz of syntax category N where baz was defined as N:baz in the pattern parameter list. The same pattern variable occurring in multiple places requires identical substitutions.

Given this pattern, you can ask DMS where is matches a (Java) AST. By matching against an AST, al the problems of whitespace, comments, unnormalized strings/identifiers/numbers/etc. are eliminated. By simply counting matches, you get OP's original desired metric. [We have largely completed an extension to RSL patterns in which the elements are connected by dataflows rather than code syntax].

Presumably he wants to transform these instances into some other code, which he can do by writing, in RSL,

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

mentioning some other "replacement_pattern" written similarly.

If OP only has a modest number of such patterns, he's probably better using regex or just slugging it out rather than getting DMS (or another program transformation tool) and setting it up. If he does this a lot, or they are scattered over very big piles of code, the patterns are complex, or he has many similar kinds of things to do, the tradeoff might tip the other way.

If your code is Java 1.6 or below, you could use Eclipse MoDisco to generate an EMF model instance of your Java projects. Then you can implement a Model Query to search for the pattern you describe. Even though the MoDisco Java model is based on Java 1.5 you can also use it for 1.6, because no syntax changes were introduced in 1.6.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top