Skip to content

Type reference refactor

Joseph Hoare edited this page Mar 11, 2021 · 2 revisions

Let's imagine that we have two types, A and B. We want to update all references from one to the other, as shown below:

Before After
import org.alfasoftware.astra.exampleTypes.A;
 
public class Example {
  A field = A.staticMethod();
}
      
import org.alfasoftware.astra.exampleTypes.B;
 
public class ExampleAfter {
  B field = B.staticMethod();
}
      

We can write a simple TypeReferenceRefactor to achieve that. All it needs is the fully qualified names of the type we want to refactor and the name we want to swap it to, shown here bundled into a UseCase:

public class AtoBUseCase implements UseCase {
   
  @Override
  public Set<? extends ASTOperation> getOperations() {
    return new HashSet<>(Arrays.asList(
      TypeReferenceRefactor.builder()
        .fromType("org.alfasoftware.astra.exampleTypes.A")
        .toType("org.alfasoftware.astra.exampleTypes.B")
        .build()
    ));
  }
  
  @Override
  public Set<String> getAdditionalClassPathEntries() {
    return new HashSet<>(Arrays.asList(
      "C:\Users\Me\.m2\repository\com\example\1.0-SNAPSHOT\type-a-1.0-SNAPSHOT.jar"
    ));
  }
}

We've supplied the classpath by overriding UseCase.getAdditionalClassPathEntries(), providing the absolute path to a local jar file containing our type A. It's a good idea to provide Astra with the full classpath necessary for compiling your source code - this will help it to understand the meaning of your code, allowing it to make inferences such as whether a reference to a simple type A is actually org.alfasoftware.astra.exampleTypes.A, or some other type named A, but from a different package.

Now that we have our UseCase, we can use it as a parameter to AstraCore.run, which could look something like the below:

public class ManualRunner {
  private static final String directoryPath = "C:/Code/MyRepository";
  private static final UseCase useCase = new AtoBUseCase();

  public static void main(String[] args) {
    AstraCore.run(directoryPath, useCase);
  }
}

And that's it! Astra should now update all the references from type A to B in all the source files in "C:/Code/MyRepository".