Skip to content

Commit 17f6a1b

Browse files
Eckaaaaaatabashev
authored andcommitted
Drop trailing tabs from comments instead of writing them out
A line comment that ended in tabs, "// comment\t\t\t", kept them in the output, so the formatted file had trailing whitespace where the same comment ending in spaces had none. JavaOutput collected pending spaces in a counter and wrote them only in front of the next non-blank character, which is what drops trailing spaces; a tab fell through to the default case and was written straight away. This ports google/google-java-format#423 by Alexander Eckert (upstream commit 05f57ec9, fixing google/google-java-format#422): pending whitespace is kept as text, tabs included, and written out only when something follows it on the line, so a tab inside a comment stays and a tab at the end of one goes. The removeTrailingTabsInComments test comes from upstream, in this project's style. The 15,747 files of the JDK 21 sources format exactly as before.
1 parent 746fb60 commit 17f6a1b

2 files changed

Lines changed: 24 additions & 9 deletions

File tree

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

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,11 @@ public final class JavaOutput extends Output {
5050
private final InputMetadata inputMetadata;
5151
private int iLine = 0; // Closest corresponding line number on input.
5252
private int lastK = -1; // Last {@link Tok} index output.
53-
private int spacesPending = 0;
5453
private int newlinesPending = 0;
5554
private StringBuilder lineBuilder = new StringBuilder();
55+
// Spaces and tabs seen since the last non-blank character. Written out in front of the next one, so that a line
56+
// never ends in whitespace: trailing tabs inside a comment were kept before, and only a second run removed them.
57+
private StringBuilder spacesPending = new StringBuilder();
5658

5759
/**
5860
* {@code JavaOutput} constructor.
@@ -99,23 +101,26 @@ public void append(State state, String text, Range<Integer> range) {
99101
if (newlinesPending == 0) {
100102
++newlinesPending;
101103
}
102-
spacesPending = 0;
104+
spacesPending = new StringBuilder();
103105
} else {
104106
boolean rangesSet = false;
105107
int textN = text.length();
106108
for (int i = 0; i < textN; i++) {
107109
char c = text.charAt(i);
108110
switch (c) {
109111
case ' ':
110-
++spacesPending;
112+
spacesPending.append(' ');
113+
break;
114+
case '\t':
115+
spacesPending.append('\t');
111116
break;
112117
case '\r':
113118
if (i + 1 < text.length() && text.charAt(i + 1) == '\n') {
114119
i++;
115120
}
116121
// falls through
117122
case '\n':
118-
spacesPending = 0;
123+
spacesPending = new StringBuilder();
119124
++newlinesPending;
120125
break;
121126
default:
@@ -128,9 +133,9 @@ public void append(State state, String text, Range<Integer> range) {
128133
rangesSet = false;
129134
--newlinesPending;
130135
}
131-
while (spacesPending > 0) {
132-
lineBuilder.append(' ');
133-
--spacesPending;
136+
if (spacesPending.length() > 0) {
137+
lineBuilder.append(spacesPending);
138+
spacesPending = new StringBuilder();
134139
}
135140
lineBuilder.append(c);
136141
if (!range.isEmpty()) {
@@ -152,7 +157,7 @@ public void append(State state, String text, Range<Integer> range) {
152157

153158
@Override
154159
public void indent(int indent) {
155-
spacesPending = indent;
160+
spacesPending.append(" ".repeat(indent));
156161
}
157162

158163
/** Flush any incomplete last line, then add the EOF token into our data structures. */
@@ -354,7 +359,7 @@ public String toString() {
354359
return MoreObjects.toStringHelper(this)
355360
.add("iLine", iLine)
356361
.add("lastK", lastK)
357-
.add("spacesPending", spacesPending)
362+
.add("spacesPending", spacesPending.toString().replace("\t", "\\t"))
358363
.add("newlinesPending", newlinesPending)
359364
.add("inputMetadata", inputMetadata)
360365
.add("super", super.toString())

‎open-java-format/src/test/java/com/palantir/javaformat/java/FormatterTest.java‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,4 +508,14 @@ void indentsCommentsThatShareALineLinearly() throws FormatterException {
508508

509509
assertThat(formatter.formatSource(input.toString()).length()).isLessThan(10_000);
510510
}
511+
512+
@Test
513+
public void removeTrailingTabsInComments() throws FormatterException {
514+
String input = "class Foo {\n void f() {\n int x = 0; // comment\t\t\t\n return;\n }\n}\n";
515+
String expected = "class Foo {\n void f() {\n int x = 0; // comment\n return;\n }\n}\n";
516+
Formatter formatter = Formatter.createFormatter(
517+
JavaFormatterOptions.builder().style(Style.OJF).build());
518+
519+
assertThat(formatter.formatSource(input)).isEqualTo(expected);
520+
}
511521
}

0 commit comments

Comments
 (0)