Skip to content

Bring over upstream PR #1784: run the string wrapping pass to a fixed point #34

Description

@abashev

What

palantir/palantir-java-format#1784 by Zayan Khan makes the formatter idempotent for text blocks inside nested array initialisers. It fixes upstream #1343, is 4 files and +83 −0, and has been open since 2026-09-15 with the CLA unsigned — where palantir#1707, palantir#1786 and palantir#1731 are.

It reproduces here on 2.98.0.2. Format this file twice:

class T {
    String[][] x = {
        {
            """
            // tmp fix
            @Deprecated
            class Test {}
            """
        },
        {
            """

            @Deprecated
            class Test {}
            """
        }
    };
}

The second pass moves the second text block's content four columns left. So open-java-format --replace writes a file that open-java-format --dry-run --set-exit-if-changed then reports as unformatted: our own GitHub Action fails on output the formatter just produced.

Why it happens

StringWrapper derives a text block's indentation from the layout around it, and the same pass moves that layout, so one round is not always a fixed point. wrap already knows this — it recomputes its replacements after reformatting, twice — it just stops at two rounds, and nested array initialisers need three. The upstream change extracts the body as wrapOnce and iterates while it keeps changing the source, bounded by MAX_ROUNDS = 5.

Why it fits the 2.x promise better than most

Output only changes for files that were never stable to begin with: for a file that is already a fixed point, one round is unchanged. Upstream says every existing golden regenerates identically, and the same held here when I tried it. That still needs to be shown on a corpus before it ships.

Tried here

Cherry-picked onto main to see what it takes; the branch was thrown away, nothing is pushed.

Done when

  • the change is on main with Zayan Khan as the author and the upstream PR named in the commit message;
  • a corpus run says how many files it moves, and each of them is a file the old code did not reach a fixed point on;
  • the new golden is in, and FormatterIntegrationTest's idempotence cases cover it;
  • it ships in a release, with the version question of Bring over upstream PRs #1707 (Java 25 syntax) and #1786 (JDK 27 end positions) #22 answered.

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

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions