Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Auto generify non-generic interface implementation

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?

like image 470
turbanoff Avatar asked Nov 07 '12 11:11

turbanoff


4 Answers

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...

like image 134
Guillaume Avatar answered Nov 07 '22 13:11

Guillaume


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

like image 43
Vic Avatar answered Nov 07 '22 15:11

Vic


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.:

  • NetBeans Refactoring API
  • NetBeans Java Hint Module Tutorial
  • Eclipse Java Code Manipulation
like image 2
reprogrammer Avatar answered Nov 07 '22 14:11

reprogrammer


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.

like image 1
Ira Baxter Avatar answered Nov 07 '22 14:11

Ira Baxter