Merge pull request #552 from JetBrains/rr/yole/kdoc-generate

structured rendering of doc comments in quick documentation dialog
This commit is contained in:
Dmitry Jemerov
2015-01-21 23:32:10 +01:00
12 changed files with 244 additions and 119 deletions
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.idea;
import com.google.common.base.Predicate;
import com.intellij.lang.documentation.AbstractDocumentationProvider;
import com.intellij.lang.java.JavaDocumentationProvider;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiWhiteSpace;
import com.intellij.psi.util.PsiTreeUtil;
@@ -93,7 +92,7 @@ public class JetQuickDocumentationProvider extends AbstractDocumentationProvider
KDocTag comment = KdocPackage.findKDoc(declarationDescriptor);
if (comment != null) {
renderedDecl = renderedDecl + "<br/>" + kDocToHtml(comment);
renderedDecl = renderedDecl + "<br/>" + org.jetbrains.kotlin.idea.kdoc.KdocPackage.renderKDoc(comment);
}
return renderedDecl;
@@ -111,14 +110,4 @@ public class JetQuickDocumentationProvider extends AbstractDocumentationProvider
return null;
}
private static String kDocToHtml(@NotNull KDocTag comment) {
// TODO: Parse and show markdown comments as html
String content = comment.getContentWithTags();
String htmlContent = StringUtil.replace(content, "\n", "<br/>")
.replaceAll("(@param)\\s+(\\w+)", "@param - <i>$2</i>")
.replaceAll("(@\\w+)", "<b>$1</b>");
return "<p>" + htmlContent + "</p>";
}
}
@@ -0,0 +1,66 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.kdoc
import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag
import com.intellij.openapi.util.text.StringUtil
import org.jetbrains.kotlin.kdoc.psi.impl.KDocSection
fun renderKDoc(docComment: KDocTag): String {
val content = docComment.getContent()
val result = StringBuilder("<p>")
result.append(markdownToHtml(content))
if (docComment is KDocSection) {
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)
}
result.append("</p>")
return result.toString()
}
private fun renderTagList(tags: List<KDocTag>, title: String, to: StringBuilder) {
if (tags.isEmpty()) {
return
}
to.append("<dl><dt><b>${title}:</b></dt>")
tags.forEach {
to.append("<dd><code>${it.getSubjectName()}</code> - ${markdownToHtml(it.getContent().trimLeading())}</dd>")
}
to.append("</dl>")
}
private fun renderTag(tag: KDocTag?, title: String, to: StringBuilder) {
if (tag != null) {
to.append("<dl><dt><b>${title}:</b></dt>")
to.append("<dd>${markdownToHtml(tag.getContent())}</dd>")
to.append("</dl>")
}
}
fun markdownToHtml(markdown: String): String {
// TODO Integrate a real Markdown parser
return StringUtil.replace(markdown, "\n", "<br/>");
}
@@ -7,9 +7,9 @@ package test
* Test function
*
* @param first - Some
* @param second - Other
* @param first Some
* @param second Other
*/
fun <caret>testFun(first: String, second: Int) = 12
// INFO: <b>internal</b> <b>fun</b> testFun(first: String, second: Int): Int<br/><p>Test function<br/><br/><br/><b>@param</b> - <i>first</i> - Some<br/><b>@param</b> - <i>second</i> - Other<br/></p>
// INFO: <b>internal</b> <b>fun</b> testFun(first: String, second: Int): Int<br/><p>Test function<br/><br/><br/><dl><dt><b>Parameters:</b></dt><dd><code>first</code> - Some</dd><dd><code>second</code> - Other</dd></dl></p>
@@ -1,8 +1,8 @@
/**
Some documentation
@param a - Some int
* @param b: String
* @param a Some int
* @param b String
*/
fun testMethod(a: Int, b: String) {
@@ -12,4 +12,4 @@ fun test() {
<caret>testMethod(1, "value")
}
// INFO: <b>internal</b> <b>fun</b> testMethod(a: Int, b: String): Unit<br/><p>Some documentation<br/><br/><b>@param</b> - <i>a</i> - Some int<br/><b>@param</b> - <i>b</i>: String<br/></p>
// INFO: <b>internal</b> <b>fun</b> testMethod(a: Int, b: String): Unit<br/><p>Some documentation<br/><br/><dl><dt><b>Parameters:</b></dt><dd><code>a</code> - Some int</dd><dd><code>b</code> - String</dd></dl></p>
@@ -0,0 +1,15 @@
/**
Some documentation
* @param[a] Some int
* @param[b] String
*/
fun testMethod(a: Int, b: String) {
}
fun test() {
<caret>testMethod(1, "value")
}
// INFO: <b>internal</b> <b>fun</b> testMethod(a: Int, b: String): Unit<br/><p>Some documentation<br/><br/><dl><dt><b>Parameters:</b></dt><dd><code>a</code> - Some int</dd><dd><code>b</code> - String</dd></dl></p>
@@ -0,0 +1,17 @@
/**
Some documentation
* @param a Some int
* @param b String
* @return Return value
* @throws IllegalArgumentException if the weather is bad
*/
fun testMethod(a: Int, b: String) {
}
fun test() {
<caret>testMethod(1, "value")
}
// INFO: <b>internal</b> <b>fun</b> testMethod(a: Int, b: String): Unit<br/><p>Some documentation<br/><br/><dl><dt><b>Parameters:</b></dt><dd><code>a</code> - Some int</dd><dd><code>b</code> - String</dd></dl><dl><dt><b>Returns:</b></dt><dd> value</dd></dl><dl><dt><b>Throws:</b></dt><dd><code>IllegalArgumentException</code> - if the weather is bad</dd></dl></p>
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.idea.editor.quickDoc;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.InnerTestClasses;
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
import org.jetbrains.kotlin.test.JetTestUtils;
import org.jetbrains.kotlin.test.TestMetadata;
@@ -107,6 +108,18 @@ public class JetQuickDocProviderTestGenerated extends AbstractJetQuickDocProvide
doTest(fileName);
}
@TestMetadata("OnMethodUsageWithBracketsInParam.kt")
public void testOnMethodUsageWithBracketsInParam() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/editor/quickDoc/OnMethodUsageWithBracketsInParam.kt");
doTest(fileName);
}
@TestMetadata("OnMethodUsageWithReturnAndThrows.kt")
public void testOnMethodUsageWithReturnAndThrows() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/editor/quickDoc/OnMethodUsageWithReturnAndThrows.kt");
doTest(fileName);
}
@TestMetadata("TopLevelMethodFromJava.java")
public void testTopLevelMethodFromJava() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/editor/quickDoc/TopLevelMethodFromJava.java");