From e16386221d907e076741f4933964e16f8a7fff27 Mon Sep 17 00:00:00 2001 From: Albert Meltzer <7529386+kitbellew@users.noreply.github.com> Date: Wed, 17 Jun 2020 09:40:47 -0700 Subject: [PATCH 1/3] Add failing tests with docstrings.oneline --- .../src/test/resources/test/JavaDoc.stat | 190 ++++++++++++++++++ 1 file changed, 190 insertions(+) diff --git a/scalafmt-tests/src/test/resources/test/JavaDoc.stat b/scalafmt-tests/src/test/resources/test/JavaDoc.stat index 75fe68dcd1..f32e7276ea 100644 --- a/scalafmt-tests/src/test/resources/test/JavaDoc.stat +++ b/scalafmt-tests/src/test/resources/test/JavaDoc.stat @@ -992,3 +992,193 @@ object a { */ class QueueSequentialBenchmark {} } +<<< #2028 Asterisk keep +docstrings.style = Asterisk +docstrings.oneline = keep +=== +object a { + /** alias for [[literal]] */ + /** + * + * alias for [[literal]] + * + */ +} +>>> +object a { + + /** + * alias for [[literal]] */ + /** + * alias for [[literal]] + */ +} +<<< #2028 Asterisk fold +docstrings.style = Asterisk +docstrings.oneline = fold +=== +object a { + /** alias for [[literal]] */ + /** + * + * alias for [[literal]] + * + */ +} +>>> +Idempotency violated +object a { + + /** alias for [[literal]] */ + /** + * alias for [[literal]] + */ +} +<<< #2028 Asterisk unfold +docstrings.style = Asterisk +docstrings.oneline = unfold +=== +object a { + /** alias for [[literal]] */ + /** + * + * alias for [[literal]] + * + */ +} +>>> +object a { + + /** + * alias for [[literal]] + */ + /** + * alias for [[literal]] + */ +} +<<< #2028 SpaceAsterisk keep +docstrings.style = SpaceAsterisk +docstrings.oneline = keep +=== +object a { + /** alias for [[literal]] */ + /** + * + * alias for [[literal]] + * + */ +} +>>> +object a { + + /** alias for [[literal]] */ + /** + * alias for [[literal]] + */ +} +<<< #2028 SpaceAsterisk fold +docstrings.style = SpaceAsterisk +docstrings.oneline = fold +=== +object a { + /** alias for [[literal]] */ + /** + * + * alias for [[literal]] + * + */ +} +>>> +Idempotency violated +object a { + + /** alias for [[literal]] */ + /** + * alias for [[literal]] + */ +} +<<< #2028 SpaceAsterisk unfold +docstrings.style = SpaceAsterisk +docstrings.oneline = unfold +=== +object a { + /** alias for [[literal]] */ + /** + * + * alias for [[literal]] + * + */ +} +>>> +object a { + + /** + * alias for [[literal]] + */ + /** + * alias for [[literal]] + */ +} +<<< #2028 AsteriskSpace keep +docstrings.style = AsteriskSpace +docstrings.oneline = keep +=== +object a { + /** alias for [[literal]] */ + /** + * + * alias for [[literal]] + * + */ +} +>>> +object a { + + /** alias for [[literal]] */ + /** + * alias for [[literal]] + */ +} +<<< #2028 AsteriskSpace fold +docstrings.style = AsteriskSpace +docstrings.oneline = fold +=== +object a { + /** alias for [[literal]] */ + /** + * + * alias for [[literal]] + * + */ +} +>>> +Idempotency violated +object a { + + /** alias for [[literal]] */ + /** + * alias for [[literal]] + */ +} +<<< #2028 AsteriskSpace unfold +docstrings.style = AsteriskSpace +docstrings.oneline = unfold +=== +object a { + /** alias for [[literal]] */ + /** + * + * alias for [[literal]] + * + */ +} +>>> +object a { + + /** + * alias for [[literal]] + */ + /** + * alias for [[literal]] + */ +} From 52e7b62dc701ab715b7cf23ba2a6cdedc34e89be Mon Sep 17 00:00:00 2001 From: Albert Meltzer <7529386+kitbellew@users.noreply.github.com> Date: Wed, 17 Jun 2020 22:05:28 -0700 Subject: [PATCH 2/3] FormatWriter: fix handling of one-line docstrings --- .../org/scalafmt/config/Docstrings.scala | 20 ++++++-- .../org/scalafmt/internal/FormatWriter.scala | 48 ++++++++---------- .../src/test/resources/test/JavaDoc.stat | 49 +++++++------------ 3 files changed, 52 insertions(+), 65 deletions(-) diff --git a/scalafmt-core/shared/src/main/scala/org/scalafmt/config/Docstrings.scala b/scalafmt-core/shared/src/main/scala/org/scalafmt/config/Docstrings.scala index b1ea1dbd3a..865b5950ea 100644 --- a/scalafmt-core/shared/src/main/scala/org/scalafmt/config/Docstrings.scala +++ b/scalafmt-core/shared/src/main/scala/org/scalafmt/config/Docstrings.scala @@ -6,6 +6,7 @@ import metaconfig._ * @param oneline * - if fold, try to fold short docstrings into a single line * - if unfold, unfold a single-line docstring into multiple lines + * - if keep, preserve the current formatting * @param wrap * if yes, allow reformatting/rewrapping the contents of the docstring * @param style @@ -23,7 +24,8 @@ case class Docstrings( ) { import Docstrings._ - def isAsterisk: Boolean = style.contains(Asterisk) + @inline + def skipFirstLine: Boolean = style.exists(_.skipFirstLine) def isSpaceAsterisk: Boolean = style.contains(SpaceAsterisk) def isAsteriskSpace: Boolean = style.contains(AsteriskSpace) @@ -53,10 +55,18 @@ object Docstrings { generic.deriveSurface[Docstrings] implicit val encoder = generic.deriveEncoder[Docstrings] - sealed abstract class Style - case object Asterisk extends Style - case object SpaceAsterisk extends Style - case object AsteriskSpace extends Style + sealed abstract class Style { + def skipFirstLine: Boolean + } + case object Asterisk extends Style { + override def skipFirstLine: Boolean = true + } + case object SpaceAsterisk extends Style { + override def skipFirstLine: Boolean = false + } + case object AsteriskSpace extends Style { + override def skipFirstLine: Boolean = false + } implicit val reader: ConfCodec[Style] = ReaderUtil.oneOf[Style](Asterisk, SpaceAsterisk, AsteriskSpace) 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 7f5bccc601..10efd98c32 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 @@ -396,25 +396,19 @@ class FormatWriter(formatOps: FormatOps) { private def formatOnelineDocstring( text: String )(implicit sb: StringBuilder): Boolean = { - if (style.docstrings.oneline eq Docstrings.Oneline.keep) false - else if (!curr.isStandalone) false - else { + curr.isStandalone && { val matcher = onelineDocstring.matcher(text) - matcher.find() && { - style.docstrings.oneline match { - case Docstrings.Oneline.fold => - sb.append("/** ").append(matcher.group(1)).append(" */") - true - case Docstrings.Oneline.unfold => - val extraIndent = if (style.docstrings.isSpaceAsterisk) 2 else 1 - val spaces = getIndentation(prevState.indentation + extraIndent) - sb.append("/**\n").append(spaces).append("* ") - if (style.docstrings.isAsteriskSpace) sb.append(' ') - sb.append(matcher.group(1)) - sb.append('\n').append(spaces).append("*/") - true - case _ => false - } + matcher.matches() && (style.docstrings.oneline match { + case Docstrings.Oneline.fold => true + case Docstrings.Oneline.unfold => false + case Docstrings.Oneline.keep => + matcher.start(1) == -1 && matcher.start(3) == -1 + }) && { + val content = matcher.group(2) + val folding = // 7 is the length of "/** " and " */" + content.length <= style.maxColumn - prevState.indentation - 7 + if (folding) sb.append("/** ").append(content).append(" */") + folding } } } @@ -606,7 +600,7 @@ class FormatWriter(formatOps: FormatOps) { private def formatWithWrap(doc: Scaladoc): Unit = { sb.append("/**") - if (style.docstrings.isAsterisk) appendBreak() + if (style.docstrings.skipFirstLine) appendBreak() sb.append(' ') val sbLen = sb.length() val paras = doc.para.iterator @@ -738,7 +732,7 @@ class FormatWriter(formatOps: FormatOps) { val matcher = docstringLine.matcher(trimmed) sb.append("/**") val sbLen = sb.length() - var prevWasBlank = style.docstrings.isAsterisk + var prevWasBlank = style.docstrings.skipFirstLine while (matcher.find()) { val contentBeg = matcher.start(2) val contentEnd = matcher.end(2) @@ -756,11 +750,8 @@ class FormatWriter(formatOps: FormatOps) { sb.append(CharBuffer.wrap(trimmed, contentBeg, contentEnd)) } } - if (!prevWasBlank) sb.append(" */") - else { - appendBreak - sb.append('/') - } + appendBreak + sb.append('/') } private def appendBreak(): Unit = @@ -1301,9 +1292,10 @@ object FormatWriter { private val leadingAsteriskSpace = Pattern.compile("(?<=\n)\\h*+(?=[*][^*])") private val docstringLine = Pattern.compile("^(?:\\h*+\\*)?(\\h*+)(.*?)\\h*+$", Pattern.MULTILINE) - private val onelineDocstring = Pattern.compile( - "^/\\*\\*(?:\n\\h*+\\*?)?\\h*+([^*][^\n]*[^\n\\h])(?:\n\\h*+\\**?)?\\h*+\\*/$" - ) + private val onelineDocstring = { + val empty = "\\h*+(\n\\h*+\\*?\\h*+)*" + Pattern.compile(s"^/\\*\\*$empty([^*][^\n]*[^\n\\h])$empty\\*/$$") + } private val docstringLeadingSpace = Pattern.compile("^\\h++") @inline diff --git a/scalafmt-tests/src/test/resources/test/JavaDoc.stat b/scalafmt-tests/src/test/resources/test/JavaDoc.stat index f32e7276ea..766bf247a5 100644 --- a/scalafmt-tests/src/test/resources/test/JavaDoc.stat +++ b/scalafmt-tests/src/test/resources/test/JavaDoc.stat @@ -178,8 +178,7 @@ docstrings.style = SpaceAsterisk /** Main entry-point. */ class Main >>> -/** - * Main entry-point. +/** Main entry-point. */ class Main <<< #1403 3: unfold AsteriskSpace @@ -189,8 +188,7 @@ docstrings.style = AsteriskSpace /** Main entry-point. */ class Main >>> -/** - * Main entry-point. +/** Main entry-point. */ class Main <<< #1387 1 Asterisk @@ -865,9 +863,7 @@ object a { >>> object a { - /** - * [[ref]]!.. {{{foo}}}??? - */ + /** [[ref]]!.. {{{foo}}}??? */ } <<< #1887 8 SpaceAsterisk: punctuation after link/code docstrings.wrap = yes @@ -879,8 +875,7 @@ object a { >>> object a { - /** [[ref]]!.. {{{foo}}}??? - */ + /** [[ref]]!.. {{{foo}}}??? */ } <<< #1887 8 AsteriskSpace: punctuation after link/code docstrings.wrap = yes @@ -892,8 +887,7 @@ object a { >>> object a { - /** [[ref]]!.. {{{foo}}}??? - */ + /** [[ref]]!.. {{{foo}}}??? */ } <<< keep inner asterisks, Asterisk docstrings.style = Asterisk @@ -907,7 +901,8 @@ object a { /** * *************** tests ****************** - * *************** tests ****************** */ + * *************** tests ****************** + */ } <<< keep inner asterisks, SpaceAsterisk docstrings.style = SpaceAsterisk @@ -920,7 +915,8 @@ object a { object a { /** *************** tests ****************** - * *************** tests ****************** */ + * *************** tests ****************** + */ } <<< keep inner asterisks, AsteriskSpace docstrings.style = AsteriskSpace @@ -933,7 +929,8 @@ object a { object a { /** *************** tests ****************** - * *************** tests ****************** */ + * *************** tests ****************** + */ } <<< empty comment object a { @@ -1007,8 +1004,7 @@ object a { >>> object a { - /** - * alias for [[literal]] */ + /** alias for [[literal]] */ /** * alias for [[literal]] */ @@ -1026,13 +1022,10 @@ object a { */ } >>> -Idempotency violated object a { /** alias for [[literal]] */ - /** - * alias for [[literal]] - */ + /** alias for [[literal]] */ } <<< #2028 Asterisk unfold docstrings.style = Asterisk @@ -1089,13 +1082,10 @@ object a { */ } >>> -Idempotency violated object a { /** alias for [[literal]] */ - /** - * alias for [[literal]] - */ + /** alias for [[literal]] */ } <<< #2028 SpaceAsterisk unfold docstrings.style = SpaceAsterisk @@ -1112,8 +1102,7 @@ object a { >>> object a { - /** - * alias for [[literal]] + /** alias for [[literal]] */ /** * alias for [[literal]] @@ -1152,13 +1141,10 @@ object a { */ } >>> -Idempotency violated object a { /** alias for [[literal]] */ - /** - * alias for [[literal]] - */ + /** alias for [[literal]] */ } <<< #2028 AsteriskSpace unfold docstrings.style = AsteriskSpace @@ -1175,8 +1161,7 @@ object a { >>> object a { - /** - * alias for [[literal]] + /** alias for [[literal]] */ /** * alias for [[literal]] From 857354d8b318dec0c0420750d6258ff7f62009b4 Mon Sep 17 00:00:00 2001 From: Albert Meltzer <7529386+kitbellew@users.noreply.github.com> Date: Wed, 17 Jun 2020 17:47:29 -0700 Subject: [PATCH 3/3] Documentation: augment docstrings.oneline --- docs/configuration.md | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 1d7868ff03..01f2d2476f 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -1703,20 +1703,42 @@ docstrings.style = AsteriskSpace docstrings.oneline ``` +- `fold` + ```scala mdoc:scalafmt +docstrings.style = Asterisk docstrings.oneline = fold --- +/** Scaladoc oneline */ /** - * Align by second asterisk. + * Scaladoc multiline */ val a = 1 ``` +- `unfold` + ```scala mdoc:scalafmt docstrings.style = Asterisk docstrings.oneline = unfold --- -/** Align by first asterisk. */ +/** Scaladoc oneline */ +/** + * Scaladoc multiline + */ +val a = 1 +``` + +- `keep` + +```scala mdoc:scalafmt +docstrings.style = Asterisk +docstrings.oneline = keep +--- +/** Scaladoc oneline */ +/** + * Scaladoc multiline + */ val a = 1 ```