diff --git a/idea/src/org/jetbrains/kotlin/idea/KotlinQuickDocumentationProvider.kt b/idea/src/org/jetbrains/kotlin/idea/KotlinQuickDocumentationProvider.kt index 150138d2e44..1f94ab01fd2 100644 --- a/idea/src/org/jetbrains/kotlin/idea/KotlinQuickDocumentationProvider.kt +++ b/idea/src/org/jetbrains/kotlin/idea/KotlinQuickDocumentationProvider.kt @@ -311,9 +311,7 @@ class KotlinQuickDocumentationProvider : AbstractDocumentationProvider() { var renderedHtml: String - //if (!quickNavigation) { renderedHtml = "${DocumentationMarkup.DEFINITION_START}$declaration${DocumentationMarkup.DEFINITION_END}" - //} val deprecationProvider = ktElement.getResolutionFacade().frontendService() renderedHtml += renderDeprecationInfo(declarationDescriptor, deprecationProvider) @@ -322,13 +320,7 @@ class KotlinQuickDocumentationProvider : AbstractDocumentationProvider() { val comment = declarationDescriptor.findKDoc { DescriptorToSourceUtilsIde.getAnyDeclaration(ktElement.project, it) } if (comment != null) { val renderedComment = KDocRenderer.renderKDoc(comment) - renderedHtml += "${DocumentationMarkup.CONTENT_START}$renderedComment${DocumentationMarkup.CONTENT_END}" -// if (renderedComment.startsWith("

")) { -// renderedHtml += renderedComment -// } -// else { -// renderedHtml = "$renderedHtml
$renderedComment" -// } + renderedHtml += "${DocumentationMarkup.CONTENT_START}$renderedComment" } else { if (declarationDescriptor is CallableDescriptor) { // If we couldn't find KDoc, try to find javadoc in one of super's val psi = declarationDescriptor.findPsi() as? KtFunction diff --git a/idea/src/org/jetbrains/kotlin/idea/kdoc/KDocRenderer.kt b/idea/src/org/jetbrains/kotlin/idea/kdoc/KDocRenderer.kt index 8f91da47253..5905f45395a 100644 --- a/idea/src/org/jetbrains/kotlin/idea/kdoc/KDocRenderer.kt +++ b/idea/src/org/jetbrains/kotlin/idea/kdoc/KDocRenderer.kt @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.idea.kdoc import com.intellij.codeInsight.documentation.DocumentationManagerUtil +import com.intellij.lang.documentation.DocumentationMarkup.* import com.intellij.psi.PsiElement import org.intellij.markdown.IElementType import org.intellij.markdown.MarkdownElementTypes @@ -36,30 +37,35 @@ import org.jetbrains.kotlin.psi.psiUtil.getChildrenOfType object KDocRenderer { fun renderKDoc(docComment: KDocTag): String { - val content = docComment.getContent() - val result = StringBuilder() - result.append(markdownToHtml(content, allowSingleParagraph = true)) - if (docComment is KDocSection) { - result.append("\n") - renderTag(docComment.findTagByName("receiver"), "Receiver", result) - val paramTags = docComment.findTagsByName("param").filter { it.getSubjectName() != null } - renderTagList(paramTags, "Parameters", result) - - renderTag(docComment.findTagByName("return"), "Returns", result) - - val throwsTags = (docComment.findTagsByName("exception").union(docComment.findTagsByName("throws"))) - .filter { it.getSubjectName() != null } - renderTagList(throwsTags, "Throws", result) - - renderTag(docComment.findTagByName("author"), "Author", result) - renderTag(docComment.findTagByName("since"), "Since", result) - - renderSeeAlso(docComment, result) - - val sampleTags = docComment.findTagsByName("sample").filter { it.getSubjectLink() != null } - renderSamplesList(sampleTags, result) + return if (docComment is KDocSection) { + renderKDocSection(docComment) + } else { + markdownToHtml(docComment.getContent(), allowSingleParagraph = true) } - return result.toString() + } + + fun renderKDocSection(section: KDocSection): String = buildString { + append(markdownToHtml(section.getContent(), allowSingleParagraph = true)) + append(CONTENT_END) + append(SECTIONS_START) + renderTag(section.findTagByName("receiver"), "Receiver", this) + val paramTags = section.findTagsByName("param").filter { it.getSubjectName() != null } + renderTagList(paramTags, "Parameters", this) + + renderTag(section.findTagByName("return"), "Returns", this) + + val throwsTags = (section.findTagsByName("exception").union(section.findTagsByName("throws"))) + .filter { it.getSubjectName() != null } + renderTagList(throwsTags, "Throws", this) + + renderTag(section.findTagByName("author"), "Author", this) + renderTag(section.findTagByName("since"), "Since", this) + + renderSeeAlso(section, this) + + val sampleTags = section.findTagsByName("sample").filter { it.getSubjectLink() != null } + renderSamplesList(sampleTags, this) + append(SECTIONS_END) } private fun KDocLink.createHyperlink(to: StringBuilder) { @@ -89,25 +95,27 @@ object KDocRenderer { return lines.joinToString("\n") { it.drop(minIndent) } } + private fun StringBuilder.renderSection(title: String, content: StringBuilder.() -> Unit) { + append(SECTION_HEADER_START, title, SECTION_SEPARATOR) + content() + append(SECTION_END) + } private fun renderSamplesList(sampleTags: List, to: StringBuilder) { if (sampleTags.isEmpty()) return - to.apply { - wrapTag("dl") { - append("

Samples:
") - sampleTags.forEach { - wrapTag("dd") { - it.getSubjectLink()?.let { subjectLink -> - subjectLink.createHyperlink(to) - val target = subjectLink.getTargetElement() - wrapTag("pre") { - wrapTag("code") { - if (target == null) - to.append("// Unresolved") - else { - to.append(trimCommonIndent(target.extractExampleText())) - } - } + + to.renderSection("Samples") { + sampleTags.forEach { + it.getSubjectLink()?.let { subjectLink -> + append("

") + subjectLink.createHyperlink(to) + val target = subjectLink.getTargetElement() + wrapTag("pre") { + wrapTag("code") { + if (target == null) + to.append("// Unresolved") + else { + to.append(trimCommonIndent(target.extractExampleText())) } } } @@ -119,40 +127,39 @@ object KDocRenderer { private fun renderSeeAlso(docComment: KDocSection, to: StringBuilder) { val seeTags = docComment.findTagsByName("see") if (seeTags.isEmpty()) return - to.append("

") - to.append("
").append("See Also:").append("") - to.append("
") - seeTags.forEachIndexed { index, tag -> - val subjectName = tag.getSubjectName() - if (subjectName != null) { - DocumentationManagerUtil.createHyperlink(to, subjectName, subjectName, false) - } - else { - to.append(tag.getContent()) - } - if (index < seeTags.size - 1) { - to.append(", ") + + to.renderSection("See Also") { + seeTags.forEachIndexed { index, tag -> + val subjectName = tag.getSubjectName() + if (subjectName != null) { + DocumentationManagerUtil.createHyperlink(this, subjectName, subjectName, false) + } + else { + append(tag.getContent()) + } + if (index < seeTags.size - 1) { + append(", ") + } } } - to.append("
") } private fun renderTagList(tags: List, title: String, to: StringBuilder) { if (tags.isEmpty()) { return } - to.append("
$title:
") - tags.forEach { - to.append("
${it.getSubjectName()} - ${markdownToHtml(it.getContent().trimStart())}
") + to.renderSection(title) { + tags.forEach { + append("

${it.getSubjectName()} - ${markdownToHtml(it.getContent().trimStart())}") + } } - to.append("

\n") } private fun renderTag(tag: KDocTag?, title: String, to: StringBuilder) { if (tag != null) { - to.append("
$title:
") - to.append("
${markdownToHtml(tag.getContent())}
") - to.append("
\n") + to.renderSection(title) { + markdownToHtml(tag.getContent()) + } } }