Repository navigation
Keep a wrapped trailing line comment where the first run put it - #169
Merged
Merged
Conversation
A trailing line comment too long for its line was wrapped in its own column, and the next run read the wrapped part as a comment of its own and moved it to the indentation of the code. The code before such a comment was broken, too, for room the comment never got, and the next run, seeing a shorter first line, joined it again. A line comment that starts a line in the column of the trailing line comment above now continues that comment: JavaInput makes them one tok, as it is for a run of /// lines from JDK 23 on. A line comment that spans lines counts only its slashes and first word for the layout, so the code before it stays as it would be without it; a level that fits on one line and holds such a comment is laid out instead of written flat, so that the comment is still wrapped. A trailing comment of one line that comes out wrapped, because it did not fit however the code before it was broken, is laid out once more that way, as the next run lays it out. A comment that fits once the code breaks still breaks it. The column of the trailing comment, and whether code comes before it on its line, are read in the text, since Tok.getColumn() counts an operator such as == once for each of its characters. A block comment between the code and the trailing comment changes neither. wrapLineComment moves from FormatterTest into a case, with five more. Of the 15,747 files of the JDK 21 sources, 129 format differently: in 118 only comment lines move, continuation lines that now stay under their comment, and in 11 the code before a wrapped comment is no longer broken for it. 67 files change on a second run instead of 80, and none that was stable is not. Tests on JDK 21: FormatterCasesTest 880 -> 886, FormatterTest 19 -> 18; 1407 tests in the module, which pass on JDK 25 and 27 as well.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The fix for google/google-java-format#211, open upstream since 2017 and reported there again as google/google-java-format#1211 and google/google-java-format#1221; this repository had no issue for it. The input of google/google-java-format#1211 changes on a second run here too and no longer does; the one of google/google-java-format#1221 formats the same before and after, as its comment fits once the code breaks.
A trailing
//comment too long for its line was wrapped in its own column, and the next run read the wrapped part as a comment of its own and moved it to the indentation of the code, so formatting the formatter's output changed it. This inputcame out of the first run as
and out of the second as
The code changed too: the first run broke it as far as it could for room the comment never got, and the second, with a shorter first line, joined
String[] argsagain. A continuation line that the author had aligned under a trailing comment by hand moved to the indentation of the code the same way. Both runs now giveHow
JavaInputmakes the two one tok, as javac does for a run of///lines from JDK 23 on. The column, and whether code comes before the comment on its line, are read in the text, becauseTok.getColumn()counts an operator such as==once for each of its characters. A block comment between the code and the trailing comment changes neither.Formatter.formatthen lays the file out once more with that comment counted by its first word, which is how the next run lays out the wrapped comment it reads.That is the rule picked from three variants, by examples. The other two counted a comment that spans lines by its joined text, so a hand-wrapped comment broke the code before it, or never broke code for a comment, so short comments wrapped at the right edge.
Effect
Of the 15,747 files of the JDK 21 sources, 129 format differently. In 118 only comment lines move: continuation lines that now stay under their comment, as in
java/lang/Enum.java:@SuppressWarnings("serial") // No serialVersionUID needed due to -// special-casing of enum classes. + // special-casing of enum classes.In 11 the code before a wrapped comment is no longer broken for it, as in
com/apple/laf/AquaTreeUI.java:67 files change on a second run instead of 80: 13 are fixed and none is new. None of the 67 changes a line with a
//comment on its second run; they are other bugs.The CLI and the plugins format such files differently, so this is an output change.
Tests
wrapLineCommentmoves fromFormatterTestinto a case, now that a second run keeps its output, with five more cases: a continuation next to a comment of its own, after operators, after a block comment, in an array initializer, and a comment that fits once the code breaks. FormatterCasesTest 880 → 886, FormatterTest 19 → 18../gradlew testpasses on JDK 21, and the formatter module's 1407 tests on JDK 25 and 27 as well.Left for later
Tok.getColumn()is off after a multi-character operator. The column also feeds the argument-table detection throughactualColumn, so a fix there can move code, and it is a change of its own.