18

I have interface

public interface ObjectBuilder<E> {  
   E buildObject();
}

Also, the project has a lot of classes that implement non-generic version of the interface.

class MyClassBuilder implements ObjectBuilder {
    public MyClass buildObject() {/**/}
}

Is it possible to auto convert all of these classes, so that they have implemented a generic version of the interface?

auto refactoring to this:

class MyClassBuilder implements ObjectBuilder<MyClass> {
    public MyClass buildObject() {/**/}
}

Is there a built-in or plug-in Intellij IDEA? Or in other IDE?

turbanoff
  • 2,439
  • 6
  • 42
  • 99

5 Answers5

6

What I would do: search for implements ObjectBuilder and automatically replace all occurences with something that doesn't compile, like

implements ObjectBuilder<FIXME>

Then try to compile, and manually fix all breaks. That would probably be quicker than trying to use a more advanced method...

Guillaume
  • 22,694
  • 14
  • 56
  • 70
  • it would break existing, properly interface implementation – turbanoff Dec 18 '12 at 16:38
  • Just search for regexp "implements\s+ObjectBuilder\s*{". Eclipse can do that (Ctrl+H, File tab, replace button is at the bottom). – mabn Dec 19 '12 at 19:17
3

You can use Structural Search and Replace feature. It is only available in Ultimate edition though.

Vic
  • 21,473
  • 11
  • 76
  • 97
2

NetBeans offers a feature called Inspect and Transform, which allows you to write custom inspections and transformations, of the form:

<source-pattern> :: <conditions>
=> <target-pattern> :: <conditions>
;;

For example:

$f.toURL() :: $f instanceof java.io.File
=> $f.toURI().toURL()
;;

You can find more examples of such transformations in a blog post.

Similarly, IntelliJ supports custom code transformation rules through a feature called Structural Search and Replace. Using this feature of IntelliJ, you can make transformations like the following:

class $TestCase$ extends TestCase {
  $MyClassContent$
}
=>
class $TestCase$ extends OurHomeGrownTestCase {
  $MyClassContent$
}

However, I'm not sure if the above rule languages are expressive enough to support your desired transformation. If they cannot express your transformation, you can always resort to the refactoring API of an IDE to automate your custom transformation, e.g.:

reprogrammer
  • 14,298
  • 16
  • 57
  • 93
1

You would probably be interested Program Transformation Systems.

Such tools allow you to state changes to code in terms of source code patterns: "if you see this, then replace it by that". (This is kind of like a programmable "structural search and replace" mentioned in another answer). The stronger tools in this category provide information about types ("symbol tables") and make that available to control the transformations (you surely need that because you are only interested in applying changes to entities related to a specific interface.)

Such tools also allow metaprogramming, to sequence the application of such transformations. With these two ideas, one can implement tools to carry out "massive" changes such as the kind you contemplate.

Ira Baxter
  • 93,541
  • 22
  • 172
  • 341
1

Is it possible to auto convert all of these classes, so that they have implemented a generic version of the interface?

Yes it is possible, for appropriate definition of "auto" :)

Is there a built-in or plug-in Intellij IDEA? Or in other IDE?

The transformation you are looking for is quite complex:

for each class (interface) that implements ObjectBuilder (not ObjectBuilder<.*>) 
  if the class declares/defines the method buildObject with return type X 
  then 
    modify the class to implement ObjectBuilder<X> instead of ObjectBuilder. 

You can probably write a plug-in to do this, but I suspect there is no exiting plugin that has a scripting language expressive enough to describe this.

On the other hand, a hard-coded script does not seem difficult at all. I don't have any experience with IntelliJ IDEA but I can see how this can be done even using simple search/replace in Emnacs Lisp.

Miserable Variable
  • 28,432
  • 15
  • 72
  • 133