Skip to content

Commit 24680f3

Browse files
awturnercpovirk
authored andcommitted
google-java-formatter: reformat portions of the text affected by reflowing
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=263545728
1 parent edfc2ab commit 24680f3

File tree

5 files changed

+93
-30
lines changed

5 files changed

+93
-30
lines changed

core/src/main/java/com/google/googlejavaformat/java/FormatFileCallable.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,11 @@ public String call() throws FormatterException {
4141
return fixImports(input);
4242
}
4343

44-
String formatted =
45-
new Formatter(options).formatSource(input, characterRanges(input).asRanges());
44+
Formatter formatter = new Formatter(options);
45+
String formatted = formatter.formatSource(input, characterRanges(input).asRanges());
4646
formatted = fixImports(formatted);
4747
if (parameters.reflowLongStrings()) {
48-
formatted = StringWrapper.wrap(Formatter.MAX_LINE_LENGTH, formatted);
48+
formatted = StringWrapper.wrap(Formatter.MAX_LINE_LENGTH, formatted, formatter);
4949
}
5050
return formatted;
5151
}

core/src/main/java/com/google/googlejavaformat/java/Formatter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ public String formatSourceAndFixImports(String input) throws FormatterException
219219
input = ImportOrderer.reorderImports(input, options.style());
220220
input = RemoveUnusedImports.removeUnusedImports(input);
221221
String formatted = formatSource(input);
222-
formatted = StringWrapper.wrap(formatted);
222+
formatted = StringWrapper.wrap(formatted, this);
223223
return formatted;
224224
}
225225

core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -62,19 +62,52 @@
6262
/** Wraps string literals that exceed the column limit. */
6363
public final class StringWrapper {
6464
/** Reflows long string literals in the given Java source code. */
65-
public static String wrap(String input) throws FormatterException {
66-
return StringWrapper.wrap(Formatter.MAX_LINE_LENGTH, input);
65+
public static String wrap(String input, Formatter formatter) throws FormatterException {
66+
return StringWrapper.wrap(Formatter.MAX_LINE_LENGTH, input, formatter);
6767
}
6868

6969
/**
7070
* Reflows string literals in the given Java source code that extend past the given column limit.
7171
*/
72-
static String wrap(final int columnLimit, final String input) throws FormatterException {
72+
static String wrap(final int columnLimit, String input, Formatter formatter)
73+
throws FormatterException {
7374
if (!longLines(columnLimit, input)) {
7475
// fast path
7576
return input;
7677
}
7778

79+
TreeRangeMap<Integer, String> replacements = getReflowReplacements(columnLimit, input);
80+
String firstPass = formatter.formatSource(input, replacements.asMapOfRanges().keySet());
81+
82+
if (!firstPass.equals(input)) {
83+
// If formatting the replacement ranges resulted in a change, recalculate the replacements on
84+
// the updated input.
85+
input = firstPass;
86+
replacements = getReflowReplacements(columnLimit, input);
87+
}
88+
89+
String result = applyReplacements(input, replacements);
90+
91+
{
92+
// We really don't want bugs in this pass to change the behaviour of programs we're
93+
// formatting, so check that the pretty-printed AST is the same before and after reformatting.
94+
String expected = parse(input, /* allowStringFolding= */ true).toString();
95+
String actual = parse(result, /* allowStringFolding= */ true).toString();
96+
if (!expected.equals(actual)) {
97+
throw new FormatterException(
98+
String.format(
99+
"Something has gone terribly wrong. Please file a bug: "
100+
+ "https://github.com/google/google-java-format/issues/new"
101+
+ "\n\n=== Actual: ===\n%s\n=== Expected: ===\n%s\n",
102+
actual, expected));
103+
}
104+
}
105+
106+
return result;
107+
}
108+
109+
private static TreeRangeMap<Integer, String> getReflowReplacements(
110+
int columnLimit, final String input) throws FormatterException {
78111
JCTree.JCCompilationUnit unit = parse(input, /* allowStringFolding= */ false);
79112
String separator = Newlines.guessLineSeparator(input);
80113

@@ -137,24 +170,7 @@ public Void visitLiteral(LiteralTree literalTree, Void aVoid) {
137170
Range.closedOpen(getStartPosition(flat.get(0)), getEndPosition(unit, getLast(flat))),
138171
reflow(separator, columnLimit, startColumn, trailing, components, first.get()));
139172
}
140-
String result = applyReplacements(input, replacements);
141-
142-
{
143-
// We really don't want bugs in this pass to change the behaviour of programs we're
144-
// formatting, so check that the pretty-printed AST is the same before and after reformatting.
145-
String expected = parse(input, /* allowStringFolding= */ true).toString();
146-
String actual = parse(result, /* allowStringFolding= */ true).toString();
147-
if (!expected.equals(actual)) {
148-
throw new FormatterException(
149-
String.format(
150-
"Something has gone terribly wrong. Please file a bug: "
151-
+ "https://github.com/google/google-java-format/issues/new"
152-
+ "\n\n=== Actual: ===\n%s\n=== Expected: ===\n%s\n",
153-
actual, expected));
154-
}
155-
}
156-
157-
return result;
173+
return replacements;
158174
}
159175

160176
/**

core/src/test/java/com/google/googlejavaformat/java/StringWrapperIntegrationTest.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,8 @@ public static Collection<Object[]> parameters() {
378378
.collect(toImmutableList());
379379
}
380380

381+
private final Formatter formatter = new Formatter();
382+
381383
private final String input;
382384
private final String output;
383385

@@ -388,24 +390,25 @@ public StringWrapperIntegrationTest(String input, String output) {
388390

389391
@Test
390392
public void test() throws Exception {
391-
assertThat(StringWrapper.wrap(40, new Formatter().formatSource(input))).isEqualTo(output);
393+
assertThat(StringWrapper.wrap(40, formatter.formatSource(input), formatter)).isEqualTo(output);
392394
}
393395

394396
@Test
395397
public void testCR() throws Exception {
396-
assertThat(StringWrapper.wrap(40, new Formatter().formatSource(input.replace("\n", "\r"))))
398+
assertThat(StringWrapper.wrap(40, formatter.formatSource(input.replace("\n", "\r")), formatter))
397399
.isEqualTo(output.replace("\n", "\r"));
398400
}
399401

400402
@Test
401403
public void testCRLF() throws Exception {
402-
assertThat(StringWrapper.wrap(40, new Formatter().formatSource(input.replace("\n", "\r\n"))))
404+
assertThat(
405+
StringWrapper.wrap(40, formatter.formatSource(input.replace("\n", "\r\n")), formatter))
403406
.isEqualTo(output.replace("\n", "\r\n"));
404407
}
405408

406409
@Test
407410
public void idempotent() throws Exception {
408-
String wrap = StringWrapper.wrap(40, new Formatter().formatSource(input));
409-
assertThat(wrap).isEqualTo(new Formatter().formatSource(wrap));
411+
String wrap = StringWrapper.wrap(40, formatter.formatSource(input), formatter);
412+
assertThat(wrap).isEqualTo(formatter.formatSource(wrap));
410413
}
411414
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.google.googlejavaformat.java;
2+
3+
import static com.google.common.truth.Truth.assertThat;
4+
5+
import com.google.common.base.Joiner;
6+
import org.junit.Test;
7+
import org.junit.runner.RunWith;
8+
import org.junit.runners.JUnit4;
9+
10+
/** {@link StringWrapper}Test */
11+
@RunWith(JUnit4.class)
12+
public class StringWrapperTest {
13+
@Test
14+
public void testAwkwardLineEndWrapping() throws Exception {
15+
String input =
16+
lines(
17+
"class T {",
18+
// This is a wide line, but has to be split in code because of 100-char limit.
19+
" String s = someMethodWithQuiteALongNameThatWillGetUsUpCloseToTheColumnLimit() "
20+
+ "+ \"foo bar foo bar foo bar\";",
21+
"",
22+
" String someMethodWithQuiteALongNameThatWillGetUsUpCloseToTheColumnLimit() {",
23+
" return null;",
24+
" }",
25+
"}");
26+
String output =
27+
lines(
28+
"class T {",
29+
" String s =",
30+
" someMethodWithQuiteALongNameThatWillGetUsUpCloseToTheColumnLimit()",
31+
" + \"foo bar foo bar foo bar\";",
32+
"",
33+
" String someMethodWithQuiteALongNameThatWillGetUsUpCloseToTheColumnLimit() {",
34+
" return null;",
35+
" }",
36+
"}");
37+
38+
assertThat(StringWrapper.wrap(100, input, new Formatter())).isEqualTo(output);
39+
}
40+
41+
private static String lines(String... line) {
42+
return Joiner.on('\n').join(line) + '\n';
43+
}
44+
}

0 commit comments

Comments
 (0)