Skip to content

Commit 24fdd35

Browse files
committed
Preserve /// markers when wrapping long line comments
When wrapping line comments that start with ///, reuse that marker on continuation lines instead of hardcoding //. Also treat the full marker length as non-breakable so long unbreakable tokens (e.g. markdown links) are left intact rather than splitting after the leading ///. Fixes #1369
1 parent c51d691 commit 24fdd35

3 files changed

Lines changed: 66 additions & 6 deletions

File tree

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

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,17 +145,28 @@ private List<String> wrapLineComments(Tok tok, List<String> lines, int column0)
145145
result.add(line);
146146
continue;
147147
}
148+
// Preserve the original line-comment marker (`//` or `///`, etc.) on wrapped continuations.
149+
// Hardcoding `//` used to inject `//` lines into `///` comments and would also break at the
150+
// space after `///`, which mangled long unbreakable tokens such as markdown links
151+
// (https://github.com/google/google-java-format/issues/1369).
152+
int slashCount = 0;
153+
while (slashCount < line.length() && line.charAt(slashCount) == '/') {
154+
slashCount++;
155+
}
156+
// Line comments always start with at least "//".
157+
String lineCommentPrefix = line.substring(0, Math.max(slashCount, 2));
158+
int prefixLength = lineCommentPrefix.length();
148159
while (line.length() + column0 > Formatter.MAX_LINE_LENGTH) {
149160
int idx = Formatter.MAX_LINE_LENGTH - column0;
150-
// only break on whitespace characters, and ignore the leading `// `
151-
while (idx >= 2 && !CharMatcher.whitespace().matches(line.charAt(idx))) {
161+
// only break on whitespace characters, and ignore the leading comment marker
162+
while (idx >= prefixLength && !CharMatcher.whitespace().matches(line.charAt(idx))) {
152163
idx--;
153164
}
154-
if (idx <= 2) {
165+
if (idx <= prefixLength) {
155166
break;
156167
}
157168
result.add(line.substring(0, idx));
158-
line = "//" + line.substring(idx);
169+
line = lineCommentPrefix + line.substring(idx);
159170
}
160171
result.add(line);
161172
}

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

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,55 @@ class T {
648648
""");
649649
}
650650

651+
// https://github.com/google/google-java-format/issues/1369
652+
@Test
653+
public void wrapTripleSlashLineCommentPreservesPrefix() throws Exception {
654+
assertThat(
655+
new Formatter()
656+
.formatSource(
657+
"""
658+
class T {
659+
void m() {
660+
/// one long incredibly unbroken sentence moving from topic to topic so that no-one had a chance to interrupt the speaker at all;
661+
}
662+
}
663+
"""))
664+
.isEqualTo(
665+
"""
666+
class T {
667+
void m() {
668+
/// one long incredibly unbroken sentence moving from topic to topic so that no-one had a chance
669+
/// to interrupt the speaker at all;
670+
}
671+
}
672+
""");
673+
}
674+
675+
// https://github.com/google/google-java-format/issues/1369
676+
@Test
677+
public void doNotBreakLongUnbreakableTripleSlashLink() throws Exception {
678+
assertThat(
679+
new Formatter()
680+
.formatSource(
681+
"""
682+
class T {
683+
void m() {
684+
/// [Design-doc](8901234567890123456789012345678901234567890123456789012345678901234567890123456789)
685+
/// [Design-doc](89012345678901234567890123456789012345678901234567890123456789012345678901234567890)
686+
}
687+
}
688+
"""))
689+
.isEqualTo(
690+
"""
691+
class T {
692+
void m() {
693+
/// [Design-doc](8901234567890123456789012345678901234567890123456789012345678901234567890123456789)
694+
/// [Design-doc](89012345678901234567890123456789012345678901234567890123456789012345678901234567890)
695+
}
696+
}
697+
""");
698+
}
699+
651700
@Test
652701
public void removeTrailingTabsInComments() throws Exception {
653702
assertThat(

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1678,14 +1678,14 @@ <T> T method() {
16781678
}
16791679
16801680
/// This long line of text looks like a javadoc comment, but is not, because it is separated from
1681-
// the actual javadoc comment by a plain comment.
1681+
/// the actual javadoc comment by a plain comment.
16821682
// This is the plain comment.
16831683
/// A third very long line of text, this time a javadoc comment on a field, which again exceeds
16841684
/// the maximum line length.
16851685
String field;
16861686
16871687
/// A fourth very long line of text, which however is not a javadoc comment so will be wrapped
1688-
// like a regular // comment.
1688+
/// like a regular // comment.
16891689
}
16901690
""";
16911691
doFormatTest(input, expected);

0 commit comments

Comments
 (0)