I've got a library that was changed to introduce a factory method to replace a constructor (the reasons aren't important right now, in the current case it was for improved type inference mostly).
Assuming that there is an Eclipse refactoring script for it (so I pretty much have a nice computer-readable description of the change), is there some way to apply that script to a project that only uses that library (i.e. it only has a reference to a compiled version of the library)?
For example, I start with this simple class:
public class MyContainer<T> {
private final T content;
public MyContainer(final T content) {
this.content = content;
}
public T getContent() {
return content;
}
}
Now I introduce a factory (without making the constructor private, but that isn't really relevant right now), the factory method looks like this:
public static <T> MyContainer<T> holding(T content) {
return new MyContainer<T>(content);
}
When I now export a migration script it looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<session version="1.0">
<refactoring comment="Introduce factory 'holding' in 'scratch.MyContainer' for constructor 'scratch.MyContainer.MyContainer()'
- Original project: 'scratch'
- Original element: 'scratch.MyContainer.MyContainer()'
- Factory name: 'holding'
- Owner class: 'scratch.MyContainer'"
description="Introduce factory for 'MyContainer'"
element1="/src<scratch{MyContainer.java[MyContainer"
flags="589830" id="org.eclipse.jdt.ui.introduce.factory"
input="/src<scratch{MyContainer.java"
name="holding" project="scratch" protect="false"
selection="89 0" version="1.0"/>
</session>
This should hold enough information to apply the refactoring to another project that references (a current version) of the class via a jar file.
But trying to apply the refactoring gives me this error:
The refatoring 'Introduce Factory' (org.eclipse.jdt.ui.introduce.factory) cannot be performed, since its input 'scratch.MyContainer.java' does not exist.
Note that it explicitly mentions .java
, so it's looking for a source file and isn't content with applying the refactoring to the binary type.
Note: I don't want to patch the binary library. I just want the callers of the original constructor to be converted to calling the factory method instead.
Note 2: Search-and-replace won't help in my specific case. The reason is that I have two constructors, one taking an Object
and the other takes a String
. They should be mapped on two different factory methods, so I'd need the search-and-replace function to look at the type information of the argument as well.
Note 3: even a way to manually specify "replace instantiations of object X
with this constructor with calls to this method instead" would be appreciated.
Update: There is a bugzilla entry on the Eclipse bugzilla that is about adding a replace invocation refactoring. An implementation of that feature might be able to solve my problem, if "invocation" includes object instantiation via a given constructor. Unfortunately it saw no activity in the last few years (although it was planned for 3.2).