Skip to content

Run import cleanup and modifier reordering as one pre-formatting pass #157

Open

Description

@abashev

Upstream: google/google-java-format#1488
Kind: idea | Priority: medium

google-java-format#1488 (merged 2026-10-20, a Google-internal change exported by copybara) folds unused-import removal, import sorting and modifier reordering into a single "cleanups" stage that runs before layout. Unused imports are removed and imports sorted first, and when no pass changes non-whitespace text the already parsed compilation unit is reused for formatting. As a consequence getFormatReplacements became strictly whitespace-only and no longer reorders modifiers; callers that want modifier reordering on character ranges must go through formatSource.

Why it matters: our Formatter.getFormatReplacements still reorders modifiers internally, and an existing code comment there admits this is only safe because modifier order does not affect whitespace. IDE integrations (IntelliJ import optimizer, Eclipse plugin) that consume replacements are the ones exposed to that quirk. The parse reuse is also a small performance gain. The change touches the public API contract, so it is a deliberate decision rather than a mechanical port, and it has no effect on formatted output.

Affected files in our repo:

  • open-java-format/src/main/java/com/palantir/javaformat/java/Formatter.java (getFormatReplacements, and the import steps in formatSource and formatSourceAndFixImports)
  • open-java-format/src/main/java/com/palantir/javaformat/java/FormatFileCallable.java (import removal and ordering before formatting)
  • open-java-format/src/main/java/com/palantir/javaformat/java/ModifierOrderer.java, RemoveUnusedImports.java, ImportOrderer.java
  • open-java-format-idea-plugin (import optimizer integration)

Suggested action: investigate. Read the upstream diff (new CleanupPass and Cleanups classes plus a large test), decide whether we want the whitespace-only guarantee for getFormatReplacements, and if so adopt the idea, noting the API change in our release notes. Related earlier refactor (replacement-returning orderers) was skipped as no behaviour change.


Filed from an upstream-watch ticket after manual review.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions