diff --git a/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocFormatter.java b/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocFormatter.java index 0f49edf43..83d997476 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocFormatter.java +++ b/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocFormatter.java @@ -236,15 +236,29 @@ private static String classicCommentText(String input) { // The end result should not strip the `*` from `* foo`. List processedLines = new ArrayList<>(); processedLines.add(lines.get(0)); - for (String line : lines.subList(1, lines.size())) { + List continuations = lines.subList(1, lines.size()); + int starPrefixLength = + continuations.stream() + .map(CLASSIC_PREFIX_PATTERN::matcher) + .filter(Matcher::find) + .mapToInt(Matcher::end) + .min() + .orElse(0); + int nonStarMinLeading = + continuations.stream() + .filter(line -> !CLASSIC_PREFIX_PATTERN.matcher(line).find()) + .filter(line -> NOT_SPACE_OR_TAB.matchesAnyOf(line)) + .mapToInt(NOT_SPACE_OR_TAB::indexIn) + .min() + .orElse(0); + int nonStarStripCount = Math.min(starPrefixLength, nonStarMinLeading); + for (String line : continuations) { Matcher m = CLASSIC_PREFIX_PATTERN.matcher(line); if (m.find()) { processedLines.add(m.replaceFirst("")); } else { - // Input line did not have leading `*`. In that case, it's hard to know what is supposed to - // be indentation of the comment as a whole and what is supposed to be indentation of the - // content. We just strip all leading whitespace. - processedLines.add(line.stripLeading()); + processedLines.add( + line.length() >= nonStarStripCount ? line.substring(nonStarStripCount) : ""); } } // Unlike Markdown comments, stripping common leading whitespace is not mandated by any diff --git a/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java b/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java index c95358f6c..1fc5d0b74 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java @@ -2534,6 +2534,43 @@ class Test {} doFormatTest(input, expected); } + @Test + public void preCodeWithoutLeadingStarPreservesIndent() { + String input = + """ + /** + *
{@code
+        class Demo {
+          // Comment
+          static final int X = 1;
+
+          public static void example() {
+            int y = 2;
+          }
+        }
+         * }
+ */ + class Test {} + """; + String expected = + """ + /** + *
{@code
+         * class Demo {
+         *   // Comment
+         *   static final int X = 1;
+         *
+         *   public static void example() {
+         *     int y = 2;
+         *   }
+         * }
+         * }
+ */ + class Test {} + """; + doFormatTest(input, expected); + } + // TODO: b/346668798 - Test the following Markdown constructs, and make the tests work as needed. // We can assume that the CommonMark parser correctly handles Markdown, so the question is whether // they are subsequently mishandled by our formatting logic. So for example the CommonMark parser