diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/j2k/IdeaDocCommentConverter.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/j2k/IdeaDocCommentConverter.kt index 13c734deb71..72d457e2f41 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/j2k/IdeaDocCommentConverter.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/j2k/IdeaDocCommentConverter.kt @@ -18,10 +18,7 @@ package org.jetbrains.kotlin.idea.j2k import com.intellij.ide.highlighter.HtmlFileType import com.intellij.openapi.util.text.StringUtil -import com.intellij.psi.PsiElement -import com.intellij.psi.PsiFileFactory -import com.intellij.psi.PsiWhiteSpace -import com.intellij.psi.XmlRecursiveElementVisitor +import com.intellij.psi.* import com.intellij.psi.html.HtmlTag import com.intellij.psi.javadoc.PsiDocComment import com.intellij.psi.javadoc.PsiDocTag @@ -44,7 +41,10 @@ object IdeaDocCommentConverter : DocCommentConverter { when (tag.name) { "deprecated" -> continue@tagsLoop "see" -> append("@see ${convertJavadocLink(tag.content())}\n") - else -> appendJavadocElements(tag.children).append("\n") + else -> { + appendJavadocElements(tag.children) + if (!endsWithNewline()) append("\n") + } } } } @@ -67,12 +67,30 @@ object IdeaDocCommentConverter : DocCommentConverter { append(convertInlineDocTag(it)) } else { - append(it.text) + if (it.node?.elementType != JavaDocTokenType.DOC_COMMENT_LEADING_ASTERISKS) { + append(it.text) + } } } return this } + /** + * Returns true if the builder ends with a new-line optionally followed by some spaces + */ + private fun StringBuilder.endsWithNewline(): Boolean { + for (i in length-1 downTo 0) { + val c = get(i) + if (c.isWhitespace()) { + if (c == '\n' || c == '\r') return true + } else { + return false + } + } + return false + } + + private fun convertInlineDocTag(tag: PsiInlineDocTag) = when (tag.name) { "code", "literal" -> { val text = tag.dataElements.joinToString("") { it.text } @@ -131,8 +149,18 @@ object IdeaDocCommentConverter : DocCommentConverter { if (whitespaceIsPartOfText) { appendPendingText() - markdownBuilder.append(space.text) - if (space.textContains('\n')) { + val lines = space.text.lines() + if (lines.size == 1) { + markdownBuilder.append(space.text) + } else { + //several lines of spaces: + //drop first line - it contains trailing spaces before the first new-line; + //do not add star for the last line, it is handled by appendPendingText() + //and it is not needed in the end of the comment + lines.drop(1).dropLast(1).forEach { + markdownBuilder.append("\n * ") + } + markdownBuilder.append("\n") afterLineBreak = true } } @@ -170,6 +198,7 @@ object IdeaDocCommentConverter : DocCommentConverter { super.visitXmlTag(tag) + //appendPendingText() markdownBuilder.append(closingMarkdown) currentListType = oldListType } diff --git a/j2k/testData/fileOrElement/comments/comments2.java b/j2k/testData/fileOrElement/comments/comments2.java index 84cf7c5baf2..342906cb629 100644 --- a/j2k/testData/fileOrElement/comments/comments2.java +++ b/j2k/testData/fileOrElement/comments/comments2.java @@ -15,5 +15,17 @@ class A { protected/*it's protected*/ void foo(char c) { } + /** + * Method description. + * Multi-line method description. + * + * + * @param param1 param1 description + * @param param2 param2 description + * + * @param param3 param3 description + */ + public void foo(String param1, String param2, String param3) {} + public/*it's public*/ static/*and static*/ final/*and final*/ int C = 1; } \ No newline at end of file diff --git a/j2k/testData/fileOrElement/comments/comments2.kt b/j2k/testData/fileOrElement/comments/comments2.kt index 17a0573612d..fb3cca64e4a 100644 --- a/j2k/testData/fileOrElement/comments/comments2.kt +++ b/j2k/testData/fileOrElement/comments/comments2.kt @@ -18,6 +18,18 @@ internal class A { protected /*it's protected*/ fun foo(c: Char) {} + /** + * Method description. + * Multi-line method description. + * + * + * @param param1 param1 description + * @param param2 param2 description + * + * @param param3 param3 description + */ + fun foo(param1: String, param2: String, param3: String) {} + companion object { /*it's public*//*and static*//*and final*/ val C = 1