From 2583145ffa39437ade15b664d28b7784bab31150 Mon Sep 17 00:00:00 2001 From: Albert Meltzer <7529386+kitbellew@users.noreply.github.com> Date: Fri, 31 Jan 2025 09:14:10 -0800 Subject: [PATCH] RegexCompat: fix docstring patterns for `\r` --- .../org/scalafmt/internal/RegexCompat.scala | 10 ++++---- .../org/scalafmt/internal/RegexCompat.scala | 10 ++++---- .../org/scalafmt/internal/FormatWriter.scala | 23 ++++++++++++------- 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/scalafmt-core/jvm/src/main/scala/org/scalafmt/internal/RegexCompat.scala b/scalafmt-core/jvm/src/main/scala/org/scalafmt/internal/RegexCompat.scala index 60a190fd77..f3bab3e144 100644 --- a/scalafmt-core/jvm/src/main/scala/org/scalafmt/internal/RegexCompat.scala +++ b/scalafmt-core/jvm/src/main/scala/org/scalafmt/internal/RegexCompat.scala @@ -21,15 +21,15 @@ private[scalafmt] object RegexCompat { val leadingAsteriskSpace = Pattern.compile("\\h*\\r*\\n(\\h*+)(?:[*][^*])?") val docstringLine = Pattern - .compile("^(?:\\h*+\\*)?(\\h*+)(.*?)\\h*+$", Pattern.MULTILINE) + .compile("^(\\h*+)([*]\\h*+)?.*$", Pattern.MULTILINE) - private val emptyLines = "\\h*+(\n\\h*+\\*?\\h*+)*" + private val emptyLines = "\\h*(\\r*\\n\\h*+\\*?\\h*+)*" - val emptyDocstring = Pattern.compile(s"^/\\*\\*$emptyLines\\*/$$") + val emptyDocstring = Pattern.compile(s"^/\\*\\*$emptyLines\\*/\\h*+\\r*+$$") val onelineDocstring = { - val oneline = "[^*\n\\h](?:[^\n]*[^\n\\h])?" - Pattern.compile(s"^/\\*\\*$emptyLines($oneline)$emptyLines\\*/$$") + val oneline = "[^*\\s\\h](?:.*?[^\\s\\h])?" + Pattern.compile(s"^/\\*\\*$emptyLines($oneline)$emptyLines\\*/\\h*+\\r*+$$") } val docstringLeadingSpace = Pattern.compile("^\\h++") diff --git a/scalafmt-core/native/src/main/scala/org/scalafmt/internal/RegexCompat.scala b/scalafmt-core/native/src/main/scala/org/scalafmt/internal/RegexCompat.scala index b4aa2f2b3b..145fcda4e5 100644 --- a/scalafmt-core/native/src/main/scala/org/scalafmt/internal/RegexCompat.scala +++ b/scalafmt-core/native/src/main/scala/org/scalafmt/internal/RegexCompat.scala @@ -68,15 +68,15 @@ object RegexCompat { val leadingAsteriskSpace = pat("\\h*\\r*\\n(\\h*)(?:[*][^*])?") - val docstringLine = pat("^(?:\\h*\\*)?(\\h*)(.*?)\\h*$", Pattern.MULTILINE) + val docstringLine = pat("^(\\h*)([*]\\h*)?.*$", Pattern.MULTILINE) - val emptyLines = fixHorizontalSpaceInRegex("\\h*(\n\\h*\\*?\\h*)*") + private val emptyLines = "\\h*(\\r*\\n\\h*\\*?\\h*)*" - val emptyDocstring = pat(s"^/\\*\\*$emptyLines\\*/$$") + val emptyDocstring = pat(s"^/\\*\\*$emptyLines\\*/\\h*\\r*$$") val onelineDocstring = { - val oneline = fixHorizontalSpaceInRegex("[^*\n\\h](?:[^\n]*[^\n\\h])?") - pat(s"^/\\*\\*$emptyLines($oneline)$emptyLines\\*/$$") + val oneline = "[^*\\s\\h](?:.*?[^\\s\\h])?" + pat(s"^/\\*\\*$emptyLines($oneline)$emptyLines\\*/\\h*\\r*$$") } val docstringLeadingSpace = pat("^\\h+") diff --git a/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/FormatWriter.scala b/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/FormatWriter.scala index f49ea04188..456af37ce3 100644 --- a/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/FormatWriter.scala +++ b/scalafmt-core/shared/src/main/scala/org/scalafmt/internal/FormatWriter.scala @@ -1098,15 +1098,23 @@ class FormatWriter(formatOps: FormatOps) { private def formatNoWrap(): Unit = { // remove "/*" (keep one asterisk) and "*/" - val trimmed = CharBuffer.wrap(text, 2, text.length - 2) - val matcher = docstringLine.matcher(trimmed) + val off = 2 // matcher.region is broken in scala-native + val matcher = docstringLine + .matcher(CharBuffer.wrap(text, off, text.length - 2)) sb.append("/**") val sbLen = sb.length @tailrec def iter(prevWasBlank: Boolean): Unit = if (matcher.find()) { - val contentBeg = matcher.start(2) - val contentEnd = matcher.end(2) - if (contentBeg == contentEnd) iter(true) + val (marginBeg, marginEnd) = { + val beg2 = matcher.start(2) + // +1 is for leading asterisk + if (beg2 >= 0) (beg2 + 1, matcher.end(2)) + else (matcher.start(), matcher.end(1)) + } + val contentBeg = marginEnd + off + val contentLen = State + .getLineLength(text, contentBeg, off + matcher.end()) + if (contentLen == 0) iter(true) else { if (sb.length != sbLen) { if (prevWasBlank) appendBreak() @@ -1114,10 +1122,9 @@ class FormatWriter(formatOps: FormatOps) { } else if (style.docstrings.skipFirstLineIf(prevWasBlank)) appendBreak().append(margin) else sb.append(' ') - val extraMargin = matcher.end(1) - matcher.start(1) - - margin.length + val extraMargin = marginEnd - marginBeg - margin.length if (extraMargin > 0) sb.append(getIndentation(extraMargin)) - sb.add(trimmed, contentBeg, contentEnd) + sb.add(text, contentBeg, contentBeg + contentLen) iter(false) } }