18

我有界面

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

此外,该项目有很多实现非通用版本接口的类。

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

是否可以自动转换所有这些类,以便它们实现了接口的通用版本?

自动重构为此:

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

是否有内置或插件 Intellij IDEA?还是在其他IDE中?

4

5 回答 5

6

我会做什么:搜索implements ObjectBuilder并自动将所有出现的内容替换为无法编译的内容,例如

implements ObjectBuilder<FIXME>

然后尝试编译,并手动修复所有中断。这可能比尝试使用更高级的方法更快......

于 2012-12-18T14:22:51.053 回答
3

您可以使用结构搜索和替换功能。不过它只在终极版中可用。

于 2012-11-07T13:17:03.623 回答
2

NetBeans 提供了一个名为Inspect and Transform的功能,它允许您编写自定义检查转换,格式如下:

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

例如:

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

您可以在博客文章中找到更多此类转换的示例。

同样,IntelliJ 通过名为Structural Search and Replace的功能支持自定义代码转换规则。使用 IntelliJ 的此功能,您可以进行如下转换:

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

但是,我不确定上述规则语言是否足够表达以支持您所需的转换。如果他们无法表达您的转换,您始终可以求助于 IDE 的重构 API 来自动化您的自定义转换,例如:

于 2012-12-20T16:12:05.780 回答
1

是否可以自动转换所有这些类,以便它们实现了接口的通用版本?

是的,对于“自动”的适当定义,这是可能的:)

是否有内置或插件 Intellij IDEA?还是在其他IDE中?

您正在寻找的转换非常复杂:

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. 

您可能可以编写一个插件来执行此操作,但我怀疑没有现有的插件具有足够表达的脚本语言来描述这一点。

另一方面,硬编码脚本似乎一点也不难。我对 IntelliJ IDEA 没有任何经验,但我可以看到即使在 Emnacs Lisp 中使用简单的搜索/替换也可以做到这一点。

于 2012-12-21T18:57:22.013 回答
1

您可能会对Program Transformation Systems感兴趣。

此类工具允许您根据源代码模式声明对代码的更改:“如果您看到this,则用that替换它”。(这有点像另一个答案中提到的可编程“结构搜索和替换”)。此类别中更强大的工具提供有关类型的信息(“符号表”)并使其可用于控制转换(您肯定需要它,因为您只对将更改应用于与特定接口相关的实体感兴趣。)

此类工具还允许元编程,以对此类转换的应用进行排序。有了这两个想法,一个人就可以实现工具来进行“大规模”的改变,比如你考虑的那种。

于 2012-12-18T14:15:12.683 回答