Skip to content

Commit e2c90fd

Browse files
ZayanKhan-12claude
authored andcommitted
Run the string wrapping pass to a fixed point
From palantir#1784 by Zayan Khan, which fixes palantir#1343 (#34 here). The indentation StringWrapper picks for a text block is derived from the layout around it, but the same pass can move that layout, so one round is not always a fixed point. In the nested array initialisers of palantir#1343 the second text block moved four columns on a second run, so a file that --replace had just written was reported by --set-exit-if-changed. wrap already recomputed its replacements after reformatting, twice; it now repeats the pass while it keeps changing the source, up to MAX_ROUNDS = 5. Adapted while bringing it over: paths moved from palantir-java-format/ to open-java-format/, and the changelog entry left out. Of the 15,747 files of the JDK 21 sources one formats differently, java/lang/Module.java, whose text block argument the old code moved again on a second run; one run now gives that second result. Formatting the sources takes no longer. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 53ac7d8 commit e2c90fd

3 files changed

Lines changed: 73 additions & 0 deletions

File tree

‎open-java-format/src/main/java/com/palantir/javaformat/java/StringWrapper.java‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,25 @@ public final class StringWrapper {
5656

5757
public static final String TEXT_BLOCK_DELIMITER = "\"\"\"";
5858

59+
/**
60+
* How many times {@link #wrapOnce} may be re-run while it is still changing the source. The indentation chosen
61+
* for a text block is derived from the layout around it, which this pass can itself move, so a single round is
62+
* not always a fixed point and the formatter would not be idempotent. See
63+
* <a href="https://github.com/palantir/open-java-format/issues/1343">#1343</a>.
64+
*/
65+
private static final int MAX_ROUNDS = 5;
66+
5967
/** Reflows string literals in the given Java source code that extend past the given column limit. */
6068
static String wrap(final int columnLimit, String input, Formatter formatter) throws FormatterException {
69+
String result = wrapOnce(columnLimit, input, formatter);
70+
for (int round = 1; round < MAX_ROUNDS && !result.equals(input); round++) {
71+
input = result;
72+
result = wrapOnce(columnLimit, input, formatter);
73+
}
74+
return result;
75+
}
76+
77+
private static String wrapOnce(final int columnLimit, String input, Formatter formatter) throws FormatterException {
6178
if (!needWrapping(columnLimit, input)) {
6279
// fast path
6380
return input;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
class PalantirIssue1343TextBlockIndentStable {
2+
String[][] withCommentFirstLine = {
3+
{
4+
"""
5+
// tmp fix
6+
@Deprecated
7+
class Test {}
8+
"""
9+
},
10+
{
11+
"""
12+
13+
@Deprecated
14+
class Test {}
15+
"""
16+
}
17+
};
18+
19+
String[][] blankLineInTheMiddle = {
20+
{
21+
"""
22+
import java.util.List;
23+
24+
@Deprecated
25+
class Test {}
26+
"""
27+
},
28+
{
29+
"""
30+
31+
class Test {}
32+
"""
33+
}
34+
};
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
class PalantirIssue1343TextBlockIndentStable {
2+
String[][] withCommentFirstLine = {{"""
3+
// tmp fix
4+
@Deprecated
5+
class Test {}
6+
"""}, {"""
7+
8+
@Deprecated
9+
class Test {}
10+
"""}};
11+
12+
String[][] blankLineInTheMiddle = {{"""
13+
import java.util.List;
14+
15+
@Deprecated
16+
class Test {}
17+
"""}, {"""
18+
19+
class Test {}
20+
"""}};
21+
}

0 commit comments

Comments
 (0)