Repository navigation
Description
The question
Should the imports be fixed before the code is laid out, or after it? Every route has to do it in the same order, or the same file comes out differently (#219). #220 makes them all fix the imports after formatting, as the command line, the native binary and the GitHub Action already did. google-java-format has just gone the other way: google/google-java-format@633ce6be (2026-10-20) runs unused-import removal, modifier reordering and import sorting as one pass before the layout, on the command line too, and remaps the requested character ranges through each of its edits.
What depends on the order
ImportOrderer moves a comment along with its import, and RemoveUnusedImports leaves the comment of an import it removes behind, so the order decides where that comment ends up. It also decides whether an extraneous semicolon between imports is dropped or fails the file. Over 3,865 real files, as they are and with an unused import added to each, the two orders differ in one, CharsetEncoder of JDK 21; each order passes its check on what the other wrote. Four cases, ready for test-cases/imports in #225, pin the differences: commentOfARemovedImportGoesWithTheImportAboveIt, commentOfARemovedOwnPackageImportGoesWithTheImportAboveIt, commentUnderARemovedImportStaysOnTheClass and semicolonAfterTheLastImportStaysOnALineOfItsOwn.
For and against
Before the layout (google-java-format now, formatSourceAndFixImports before #220) |
After the layout (#220, the command line, the native binary, the GitHub Action) | |
|---|---|---|
| Output of the command line and the GitHub Action | changes in the rare cases above | stays as it is |
| Porting from google-java-format | follows its Cleanups |
conflicts with it |
import a.B;; followed by another import |
formatted: ImportOrderer drops the semicolon |
fails with extraneous semicolon, as javac 21 does with --release 21 |
| A comment under a removed import | a blank line stays between it and the class | stays on the class |
| Reformat Code with "Optimize imports" in IntelliJ IDEA (#222) | the same order: the IDE runs the optimizer first | differs, unless a whole-file Reformat runs in one pass |
Ranges (--lines, --output-replacements, IntelliJ IDEA, formatDiff) |
the ranges have to be remapped through the import edits, as google-java-format does | the ranges are offsets into the input and work as they are |
| Work | ImportOrderer and RemoveUnusedImports return replacements instead of text; the import commit of #220 is redone |
done in #220 |
Proposal
Keep "after" for now: the command line is what every check compares with, and it does not change. Revisit when porting google-java-format's Cleanups, which would bring "before" together with the range remapping it needs.
Activity