简体   繁体   English

自动生成非通用接口实现

[英]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? 是否有内置或插件Intellij IDEA? Or in other IDE? 还是在其他IDE?

What I would do: search for implements ObjectBuilder and automatically replace all occurences with something that doesn't compile, like 我会做什么:搜索implements ObjectBuilder并自动将所有出现的内容替换为无法编译的内容,例如

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... 这可能比尝试使用更先进的方法更快......

You can use Structural Search and Replace feature . 您可以使用“ 结构搜索和替换”功能 It is only available in Ultimate edition though. 它仅适用于Ultimate版本。

NetBeans offers a feature called Inspect and Transform , which allows you to write custom inspections and transformations , of the form: NetBeans提供了一个名为Inspect and Transform的功能,允许您编写以下形式的自定义检查转换

<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 . 同样,IntelliJ通过名为Structural Search and Replace的功能支持自定义代码转换规则。 Using this feature of IntelliJ, you can make transformations like the following: 使用IntelliJ的此功能,您可以进行如下转换:

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, eg: 如果他们无法表达您的转换,您可以随时使用IDE的重构API来自动化您的自定义转换,例如:

You would probably be interested Program Transformation Systems . 您可能会对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. 有了这两个想法,人们就可以实现工具来实现“大规模”的改变,例如你所考虑的那种。

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" :) 是的,对于“auto”:)的适当定义是可能的:)

Is there a built-in or plug-in Intellij IDEA? 是否有内置或插件Intellij IDEA? Or in other IDE? 还是在其他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. 我对IntelliJ IDEA没有任何经验,但我可以看到即使在Emnacs Lisp中使用简单的搜索/替换也可以做到这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM