Skip to content

Adding and Removing Imports

Jon Schneider edited this page Nov 28, 2016 · 3 revisions

Adding an import

Starting with a barebones class:

import java.util.Collection;
import java.util.Set;
class A {}

Adding an import looks like this:

Tr.CompilationUnit cu = parser.parse(a)

cu.refactor().addImport("java.util.List").fix();          // 1
cu.refactor(tx -> tx.addImport("java.util.List")).fix()   // 2
cu.refactor().addImport(List.class).fix();                // 3
  1. The simplest incarnation if you wish to add an import regardless.
  2. Add more searching or conditional logic to the lambda and only call tx.addImport(..) if certain conditions are met. Calling fix() on a refactoring that has no changes has no effect.
  3. Using a class reference instead of spelling out the fully qualified name of the class to import.

In all cases, rewrite will order the new import correctly between the Collection and Set imports.

Adding static imports

Reusing our barebones class A from above, we can add static imports with:

Tr.CompilationUnit cu = parser.parse(a)

cu.refactor().addImport("java.util.Collections", "emptyList").fix();
cu.refactor().addImport(Collections.class, "emptyList").fix();

Static imports are added after any non-static imports, similar to IntelliJ IDEA's default import ordering.

Adding imports only if the type is referenced

Passing true to an optional last parameter adds the import only if a reference to the type is found somewhere in the AST. This feature is used by Change Type to add an import only if a type was changed somewhere in the file (and of course if that import didn't already exist).

cu.refactor()
	.addImport(List.class, true)
	.fix();

Removing imports

Starting with a class with an unnecessary dependency:

import java.util.List;
import java.util.Set;
import static java.util.Collections.emptyList;
class A {
	List l;
}

The remove import refactoring operation is conditioned upon the existing import's usage:

Tr.CompilationUnit cu = parser.parse(a);

cu.refactor().removeImport(Set.class).fix();        // 1
cu.refactor().removeImport("java.util.Set").fix();  // 2
cu.refactor().removeImport(List.class).fix();       // 3
cu.refactor().removeImport(Collections.class, "emptyList");
  1. Removes the Set import, because it is unused in A
  2. Same as (1), but uses the fully qualified name instead.
  3. Does not result in a removed List import, because rewrite can determine that List is still in use.

Additionally:

  1. Star imports are replaced with named imports if only one type in the same package of the type you are trying to remove remains in use in the source file.
  2. Similar to (1), but static star imports are replaced with named methods if only one method remains on the type you are removing a star import for.

The remove import refactoring operation is used by other refactoring operations as well, e.g. the changeTarget method invocation refactoring will attempt to optimistically remove the import against the original target type. This is made safe by the fact that the remove will not be effective unless that type is not used anywhere else in the source file.