diff --git a/mtags/src/main/scala/scala/meta/internal/metals/docstrings/MarkdownGenerator.scala b/mtags/src/main/scala/scala/meta/internal/metals/docstrings/MarkdownGenerator.scala index 80170414f46..0d3ba4cbdc1 100644 --- a/mtags/src/main/scala/scala/meta/internal/metals/docstrings/MarkdownGenerator.scala +++ b/mtags/src/main/scala/scala/meta/internal/metals/docstrings/MarkdownGenerator.scala @@ -1,6 +1,7 @@ package scala.meta.internal.docstrings import scala.collection.Seq +import scala.util.matching.Regex import scala.meta._ import scala.meta.dialects.Scala213 @@ -37,19 +38,14 @@ object MarkdownGenerator { } def toMarkdown(c: Comment, docstring: String): String = { + def sortInSection( section: String, items: Seq[(String, Body)] ): Seq[(String, Body)] = { - val sectionIdx = docstring.indexOf("@" + section) - if (sectionIdx >= 0) { - val sectionString = - docstring.substring(sectionIdx).replaceAll("\\s+", " ") - items.sortBy { case (key, _) => - sectionString.indexOf(s"@$section $key") - } - } else { - items + items.sortBy { case (key, _) => + val reg = new Regex(s"@$section\\s+$key") + reg.findFirstMatchIn(docstring).map(_.start).getOrElse(Int.MaxValue) } } @@ -103,7 +99,7 @@ object MarkdownGenerator { .map(tuple => s"- `${tuple._1}`: " + tuple._2.summary .map(inlineToMarkdown) - .getOrElse("") + blocksToMarkdown(tuple._2.blocks) + .getOrElse("") ) .mkString("", "\n", "\n") else "", diff --git a/mtags/src/main/scala/scala/meta/internal/metals/docstrings/ScaladocParser.scala b/mtags/src/main/scala/scala/meta/internal/metals/docstrings/ScaladocParser.scala index d5d2331c12a..bbda1e4ee83 100644 --- a/mtags/src/main/scala/scala/meta/internal/metals/docstrings/ScaladocParser.scala +++ b/mtags/src/main/scala/scala/meta/internal/metals/docstrings/ScaladocParser.scala @@ -585,25 +585,12 @@ object ScaladocParser { else pairs) } - def linkedExceptions: Map[String, Body] = { - val m = allSymsOneTag(SimpleTagKey("throws"), filterEmpty = false) - - m.map { case (name, body) => - val newBody = body match { - case Body(List(Paragraph(Chain(_)))) => - Body(List()) - case _ => body - } - (name, newBody) - } - } - createComment( body0 = Some(parseWikiAtSymbol(docBody.toString, pos)), authors0 = allTags(SimpleTagKey("author")), see0 = allTags(SimpleTagKey("see")), result0 = oneTag(SimpleTagKey("return")), - throws0 = linkedExceptions, + throws0 = allSymsOneTag(SimpleTagKey("throws")), valueParams0 = allSymsOneTag(SimpleTagKey("param")), typeParams0 = allSymsOneTag(SimpleTagKey("tparam")), version0 = oneTag(SimpleTagKey("version")), diff --git a/tests/cross/src/test/scala/tests/pc/CompletionDocSuite.scala b/tests/cross/src/test/scala/tests/pc/CompletionDocSuite.scala index 32b8b951b75..93ef67d4d90 100644 --- a/tests/cross/src/test/scala/tests/pc/CompletionDocSuite.scala +++ b/tests/cross/src/test/scala/tests/pc/CompletionDocSuite.scala @@ -321,9 +321,9 @@ class CompletionDocSuite extends BaseCompletionSuite { |> Base trait for companion objects of collections that require an implicit evidence. | |**Type Parameters** + |- `CC`: Collection type constructor (e.g. `ArraySeq`) |- `Ev`: Unary type constructor for the implicit evidence required for an element type | (typically `Ordering` or `ClassTag`) - |- `CC`: Collection type constructor (e.g. `ArraySeq`) |EvidenceIterableFactory scala.collection |> This trait provides default implementations for the factory methods `fromSpecific` and |`newSpecificBuilder` that need to be refined when implementing a collection type that refines @@ -648,22 +648,6 @@ class CompletionDocSuite extends BaseCompletionSuite { ), ) - val post212CatchDocs: String = - """|> A container class for catch/finally logic. - | - | Pass a different value for rethrow if you want to probably - | unwisely allow catching control exceptions and other throwables - | which the rest of the world may expect to get through. - | - |**Type Parameters** - |- `T`: result type of bodies used in try and catch blocks - | - |**Parameters** - |- `fin`: Finally logic which if defined will be invoked after catch logic - |- `rethrow`: Predicate on throwables determining when to rethrow a caught [Throwable](Throwable) - |- `pf`: Partial function used when applying catch logic to determine result value - |Catch - scala.util.control.Exception - |""".stripMargin check( "scala9", """ @@ -681,14 +665,13 @@ class CompletionDocSuite extends BaseCompletionSuite { |- `T`: result type of bodies used in try and catch blocks | |**Parameters** - |- `rethrow`: Predicate on throwables determining when to rethrow a caught [Throwable](Throwable) |- `pf`: Partial function used when applying catch logic to determine result value |- `fin`: Finally logic which if defined will be invoked after catch logic + |- `rethrow`: Predicate on throwables determining when to rethrow a caught [Throwable](Throwable) |Catch - scala.util.control.Exception |""".stripMargin, includeDocs = true, compat = Map( - "2.13" -> post212CatchDocs, "3" -> """|> A container class for catch/finally logic. | @@ -700,11 +683,11 @@ class CompletionDocSuite extends BaseCompletionSuite { |- `T`: result type of bodies used in try and catch blocks | |**Parameters** + |- `pf`: Partial function used when applying catch logic to determine result value |- `fin`: Finally logic which if defined will be invoked after catch logic |- `rethrow`: Predicate on throwables determining when to rethrow a caught [Throwable](Throwable) - |- `pf`: Partial function used when applying catch logic to determine result value |Catch[T] - scala.util.control.Exception - |""".stripMargin, + |""".stripMargin ), topLines = Some(1), // for Scala3, result contains `Catch[$0]` and `Catch` ) @@ -809,8 +792,8 @@ class CompletionDocSuite extends BaseCompletionSuite { |- `V1`: type of the values of the new bindings, a supertype of `V` | |**Parameters** - |- `value`: the value to be associated with `key` |- `key`: the key to be inserted + |- `value`: the value to be associated with `key` | |**Returns:** a new immutable tree map with the inserted binding, if it wasn't present in the map |insert[V1 >: Int](key: Int, value: V1): TreeMap[Int,V1] @@ -839,8 +822,8 @@ class CompletionDocSuite extends BaseCompletionSuite { |- `V1`: type of the values of the new bindings, a supertype of `V` | |**Parameters** - |- `value`: the value to be associated with `key` |- `key`: the key to be inserted + |- `value`: the value to be associated with `key` | |**Returns:** a new immutable tree map with the inserted binding, if it wasn't present in the map |insert[V1 >: Int](key: Int, value: V1): TreeMap[Int, V1] diff --git a/tests/cross/src/test/scala/tests/pc/SignatureHelpDocSuite.scala b/tests/cross/src/test/scala/tests/pc/SignatureHelpDocSuite.scala index 17ab4e17db6..e47693a4d1f 100644 --- a/tests/cross/src/test/scala/tests/pc/SignatureHelpDocSuite.scala +++ b/tests/cross/src/test/scala/tests/pc/SignatureHelpDocSuite.scala @@ -56,45 +56,15 @@ class SignatureHelpDocSuite extends BaseSignatureHelpSuite { """.stripMargin, s"""$foldLatestDocs |**Parameters** - |- `f`: the function to apply if nonempty. |- `ifEmpty`: the expression to evaluate if empty. + |- `f`: the function to apply if nonempty. |fold[B](ifEmpty: => B)(f: Int => B): B | ^^^^^^^^^^^ | @param ifEmpty the expression to evaluate if empty. | @param f the function to apply if nonempty. """.stripMargin, - compat = Map( - "2.12" -> - s"""$foldLatestDocs - |**Parameters** - |- `ifEmpty`: the expression to evaluate if empty. - |- `f`: the function to apply if nonempty. - |fold[B](ifEmpty: => B)(f: Int => B): B - | ^^^^^^^^^^^ - | @param ifEmpty the expression to evaluate if empty. - | @param f the function to apply if nonempty. - |""".stripMargin - ), ) - val foldOlderDocs2: String = - """|Returns the result of applying `f` to this [scala.Option](scala.Option)'s - | value if the [scala.Option](scala.Option) is nonempty. Otherwise, evaluates - | expression `ifEmpty`. - | - | - |**Notes** - |- This is equivalent to `[scala.Option](scala.Option) map f getOrElse ifEmpty`. - | - |**Parameters** - |- `ifEmpty`: the expression to evaluate if empty. - |- `f`: the function to apply if nonempty. - |fold[B](ifEmpty: => B)(f: Int => B): B - | ^^^^^^^^^^^^^ - | @param ifEmpty String the expression to evaluate if empty. - | @param f the function to apply if nonempty. - |""".stripMargin - checkDoc( "curry2", """ @@ -112,26 +82,16 @@ class SignatureHelpDocSuite extends BaseSignatureHelpSuite { | @param f the function to apply if nonempty. |""".stripMargin, compat = Map( - "2.13" -> - s"""|$foldLatestDocs - |**Parameters** - |- `f`: the function to apply if nonempty. - |- `ifEmpty`: the expression to evaluate if empty. - |fold[B](ifEmpty: => B)(f: Int => B): B - | ^^^^^^^^^^^^^ - | @param ifEmpty String the expression to evaluate if empty. - | @param f the function to apply if nonempty. - |""".stripMargin, "3" -> s"""|$foldLatestDocs |**Parameters** - |- `f`: the function to apply if nonempty. |- `ifEmpty`: the expression to evaluate if empty. + |- `f`: the function to apply if nonempty. |fold[B](ifEmpty: => B)(f: Int => B): B | ^^^^^^^^^^^^^ | @param ifEmpty the expression to evaluate if empty. | @param f the function to apply if nonempty. - |""".stripMargin, + |""".stripMargin ), ) @@ -159,8 +119,8 @@ class SignatureHelpDocSuite extends BaseSignatureHelpSuite { |- `B`: the result type of the binary operator. | |**Parameters** - |- `op`: the binary operator. |- `z`: the start value. + |- `op`: the binary operator. | |**Returns:** the result of inserting `op` between consecutive elements of this collection or iterator, | going left to right with the start value `z` on the left: @@ -270,18 +230,18 @@ class SignatureHelpDocSuite extends BaseSignatureHelpSuite { | | |**Type Parameters** + |- `B`: the element type of the returned collection. |- `That`: the class of the returned collection. Where possible, `That` is |the same class as the current collection class `Repr`, but this |depends on the element type `B` being admissible for that class, |which means that an implicit instance of type `CanBuildFrom[Repr, B, That]` |is found. - |- `B`: the element type of the returned collection. | |**Parameters** + |- `f`: the function to apply to each element. |- `bf`: an implicit value of class `CanBuildFrom` which determines |the result class `That` from the current representation type `Repr` and |the new element type `B`. - |- `f`: the function to apply to each element. | |**Returns:** a new general collection resulting from applying the given function | `f` to each element of this general collection and collecting the results. @@ -381,9 +341,9 @@ class SignatureHelpDocSuite extends BaseSignatureHelpSuite { |- `T`: result type of bodies used in try and catch blocks | |**Parameters** - |- `rethrow`: Predicate on throwables determining when to rethrow a caught [Throwable](Throwable) |- `pf`: Partial function used when applying catch logic to determine result value |- `fin`: Finally logic which if defined will be invoked after catch logic + |- `rethrow`: Predicate on throwables determining when to rethrow a caught [Throwable](Throwable) |(pf: Exception.Catcher[T], fin: Option[Exception.Finally] = None, rethrow: Throwable => Boolean = shouldRethrow): Exception.Catch[T] | ^^^^^^^^^^^^^^^^^^^^^^^^ | @param pf Partial function used when applying catch logic to determine result value @@ -391,26 +351,6 @@ class SignatureHelpDocSuite extends BaseSignatureHelpSuite { | @param rethrow Predicate on throwables determining when to rethrow a caught [Throwable](Throwable) |""".stripMargin, compat = Map( - "2.13" -> - """|A container class for catch/finally logic. - | - | Pass a different value for rethrow if you want to probably - | unwisely allow catching control exceptions and other throwables - | which the rest of the world may expect to get through. - | - |**Type Parameters** - |- `T`: result type of bodies used in try and catch blocks - | - |**Parameters** - |- `fin`: Finally logic which if defined will be invoked after catch logic - |- `rethrow`: Predicate on throwables determining when to rethrow a caught [Throwable](Throwable) - |- `pf`: Partial function used when applying catch logic to determine result value - |(pf: Exception.Catcher[T], fin: Option[Exception.Finally] = None, rethrow: Throwable => Boolean = shouldRethrow): Exception.Catch[T] - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | @param pf Partial function used when applying catch logic to determine result value - | @param fin Finally logic which if defined will be invoked after catch logic - | @param rethrow Predicate on throwables determining when to rethrow a caught [Throwable](Throwable) - |""".stripMargin, "3" -> """|A container class for catch/finally logic. | @@ -422,15 +362,15 @@ class SignatureHelpDocSuite extends BaseSignatureHelpSuite { |- `T`: result type of bodies used in try and catch blocks | |**Parameters** + |- `pf`: Partial function used when applying catch logic to determine result value |- `fin`: Finally logic which if defined will be invoked after catch logic |- `rethrow`: Predicate on throwables determining when to rethrow a caught [Throwable](Throwable) - |- `pf`: Partial function used when applying catch logic to determine result value |Catch[T](pf: scala.util.control.Exception.Catcher[T], fin: Option[scala.util.control.Exception.Finally], rethrow: Throwable => Boolean) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | @param pf Partial function used when applying catch logic to determine result value | @param fin Finally logic which if defined will be invoked after catch logic | @param rethrow Predicate on throwables determining when to rethrow a caught [Throwable](Throwable) - |""".stripMargin, + |""".stripMargin ), ) diff --git a/tests/unit/src/test/scala/tests/HoverLspSuite.scala b/tests/unit/src/test/scala/tests/HoverLspSuite.scala index 333caf4d89e..bf970069fa6 100644 --- a/tests/unit/src/test/scala/tests/HoverLspSuite.scala +++ b/tests/unit/src/test/scala/tests/HoverLspSuite.scala @@ -31,7 +31,7 @@ class HoverLspSuite extends BaseLspSuite("hover-") with TestHovers { |**Returns:** the first element of this iterable collection. | |**Throws** - |- `NoSuchElementException`: + |- `NoSuchElementException`: if the iterable collection is empty. |""".stripMargin.hover, ) } yield () @@ -64,7 +64,7 @@ class HoverLspSuite extends BaseLspSuite("hover-") with TestHovers { |**Returns:** the first element of this iterable collection. | |**Throws** - |- `NoSuchElementException`: + |- `NoSuchElementException`: if the iterable collection is empty. |""".stripMargin.hover, ) } yield () @@ -257,7 +257,7 @@ class HoverLspSuite extends BaseLspSuite("hover-") with TestHovers { |**Returns:** the first element of this iterable collection. | |**Throws** - |- `NoSuchElementException`: + |- `NoSuchElementException`: if the iterable collection is empty. |""".stripMargin.hover, root = workspace.resolve(Directories.readonly), ) diff --git a/tests/unit/src/test/scala/tests/JavadocSuite.scala b/tests/unit/src/test/scala/tests/JavadocSuite.scala index e6f32d9f22a..f28682f3301 100644 --- a/tests/unit/src/test/scala/tests/JavadocSuite.scala +++ b/tests/unit/src/test/scala/tests/JavadocSuite.scala @@ -171,7 +171,7 @@ class JavadocSuite extends BaseSuite { |**Returns:** the image at the specified URL | |**Throws** - |- `IOException`: + |- `IOException`: when stuff hapend | |**See** |- [Image](Image)""".stripMargin, @@ -211,8 +211,8 @@ class JavadocSuite extends BaseSuite { |**Returns:** the image at the specified URL | |**Throws** - |- `IOException`: - |- `IllegalArgumentException`: + |- `IOException`: when stuff hapend + |- `IllegalArgumentException`: when other stuff hapend | |**See** |- [Image](Image)