diff --git a/mtags/src/main/scala/scala/meta/internal/metals/ScaladocIndexer.scala b/mtags/src/main/scala/scala/meta/internal/metals/ScaladocIndexer.scala index fb2f9703a92..98d75602634 100644 --- a/mtags/src/main/scala/scala/meta/internal/metals/ScaladocIndexer.scala +++ b/mtags/src/main/scala/scala/meta/internal/metals/ScaladocIndexer.scala @@ -44,7 +44,7 @@ class ScaladocIndexer( // Register `@define` macros to use for expanding in later docstrings. defines ++= ScaladocParser.extractDefines(docstring) val comment = ScaladocParser.parseComment(docstring, defines) - val markdown = MarkdownGenerator.toMarkdown(comment) + val markdown = MarkdownGenerator.toMarkdown(comment, docstring) def param(name: String, default: String): SymbolDocumentation = { val paramDoc = comment.valueParams .get(name) 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 6f0ffadfdad..80170414f46 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 @@ -27,7 +27,7 @@ object MarkdownGenerator { docstring: String, defines: collection.Map[String, String] ): String = { - toMarkdown(ScaladocParser.parseComment(docstring, defines)) + toMarkdown(ScaladocParser.parseComment(docstring, defines), docstring) } def toMarkdown(b: Body): String = { @@ -36,7 +36,23 @@ object MarkdownGenerator { .mkString } - def toMarkdown(c: Comment): String = { + 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 + } + } + Seq( toMarkdown(c.body), if (c.constructor.nonEmpty) @@ -62,7 +78,7 @@ object MarkdownGenerator { else "", if (c.typeParams.nonEmpty) "\n**Type Parameters**\n" + - c.typeParams + sortInSection("tparam", c.typeParams.toSeq) .map(tuple => s"- `${tuple._1}`: " + blocksToMarkdown(tuple._2.blocks) ) @@ -70,7 +86,7 @@ object MarkdownGenerator { else "", if (c.valueParams.nonEmpty) - "\n**Parameters**\n" + c.valueParams + "\n**Parameters**\n" + sortInSection("param", c.valueParams.toSeq) .map(tuple => s"- `${tuple._1}`: " + blocksToMarkdown(tuple._2.blocks) ) @@ -83,7 +99,7 @@ object MarkdownGenerator { .mkString("\n") else "", if (c.throws.nonEmpty) - "\n**Throws**\n" + c.throws + "\n**Throws**\n" + sortInSection("throws", c.throws.toSeq) .map(tuple => s"- `${tuple._1}`: " + tuple._2.summary .map(inlineToMarkdown) diff --git a/tests/unit/src/test/scala/tests/JavadocSuite.scala b/tests/unit/src/test/scala/tests/JavadocSuite.scala index e160ee01e1a..e6f32d9f22a 100644 --- a/tests/unit/src/test/scala/tests/JavadocSuite.scala +++ b/tests/unit/src/test/scala/tests/JavadocSuite.scala @@ -165,8 +165,8 @@ class JavadocSuite extends BaseSuite { |[#javadoc](#javadoc) | |**Parameters** - |- `name`: the location of the image, relative to the url argument |- `url`: an absolute URL giving the base location of the image + |- `name`: the location of the image, relative to the url argument | |**Returns:** the image at the specified URL | @@ -177,6 +177,48 @@ class JavadocSuite extends BaseSuite { |- [Image](Image)""".stripMargin, ) + check( + "method2", + s"""/** + | * Description of the method + | + | {@linkplain #javadoc} + | + | * + | * @param param1 description of param1 + | * @param param2 description of param2 + | * @param param3 description of param3 + | * @tparam T1 description of T1 + | * @tparam T2 description of T2 + | * @return the image at the specified URL + | * @throws IOException when stuff hapend + | * @throws IllegalArgumentException when other stuff hapend + | * @see Image + | */""".stripMargin, + """|Description of the method + | + |[#javadoc](#javadoc) + | + |**Type Parameters** + |- `T1`: description of T1 + |- `T2`: description of T2 + | + |**Parameters** + |- `param1`: description of param1 + |- `param2`: description of param2 + |- `param3`: description of param3 + | + |**Returns:** the image at the specified URL + | + |**Throws** + |- `IOException`: + |- `IllegalArgumentException`: + | + |**See** + |- [Image](Image) + |""".stripMargin, + ) + check( "complex", """/**