From a60d8ba79fd823260582b558f9f61229b12f4f6e Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 24 Feb 2015 16:24:00 +0100 Subject: understand @deprecated tag in javadoc --- src/Formats/StructuredFormatService.kt | 7 ++-- src/Java/JavaDocumentationBuilder.kt | 66 +++++++++++++++++++++++----------- test/data/format/javaDeprecated.html | 14 ++++++++ test/data/format/javaDeprecated.java | 7 ++++ test/data/format/javaLinkTag.html | 2 +- test/src/format/HtmlFormatTest.kt | 6 ++++ 6 files changed, 78 insertions(+), 24 deletions(-) create mode 100644 test/data/format/javaDeprecated.html create mode 100644 test/data/format/javaDeprecated.java diff --git a/src/Formats/StructuredFormatService.kt b/src/Formats/StructuredFormatService.kt index d2e2436b..efddd578 100644 --- a/src/Formats/StructuredFormatService.kt +++ b/src/Formats/StructuredFormatService.kt @@ -98,7 +98,7 @@ public abstract class StructuredFormatService(locationService: LocationService, to.append(formatCode(formatText(location, languageService.render(it)))) it.appendSourceLink(to) it.appendOverrides(to) - it.appendDeprecation(to) + it.appendDeprecation(location, to) } // All items have exactly the same documentation, so we can use any item to render it val item = items.first() @@ -149,13 +149,16 @@ public abstract class StructuredFormatService(locationService: LocationService, } } - private fun DocumentationNode.appendDeprecation(to: StringBuilder) { + private fun DocumentationNode.appendDeprecation(location: Location, to: StringBuilder) { if (deprecation != null) { val deprecationParameter = deprecation!!.details(DocumentationNode.Kind.Parameter).firstOrNull() val deprecationValue = deprecationParameter?.details(DocumentationNode.Kind.Value)?.firstOrNull() if (deprecationValue != null) { to.append(formatStrong("Deprecated: ")) appendLine(to, formatText(deprecationValue.name.trim("\""))) + } else if (deprecation?.content != Content.Empty) { + to.append(formatStrong("Deprecated: ")) + to.append(formatText(location, deprecation!!.content)) } else { appendLine(to, formatStrong("Deprecated")) } diff --git a/src/Java/JavaDocumentationBuilder.kt b/src/Java/JavaDocumentationBuilder.kt index 5d54e214..ba766e3f 100644 --- a/src/Java/JavaDocumentationBuilder.kt +++ b/src/Java/JavaDocumentationBuilder.kt @@ -16,33 +16,46 @@ public class JavaDocumentationBuilder(private val options: DocumentationOptions, packageNode.appendChildren(file.getClasses()) { build() } } - fun parseDocumentation(docComment: PsiDocComment?): Content { - if (docComment == null) return Content.Empty + data class JavadocParseResult(val content: Content, val deprecatedContent: Content?) + + fun parseDocumentation(docComment: PsiDocComment?): JavadocParseResult { + if (docComment == null) return JavadocParseResult(Content.Empty, null) val result = Content() + var deprecatedContent: Content? = null val para = ContentParagraph() result.append(para) - docComment.getDescriptionElements().dropWhile { it.getText().trim().isEmpty() }.forEach { - if (it is PsiInlineDocTag) { - para.append(convertInlineDocTag(it)) - } else { - val text = if (para.isEmpty()) it.getText().trimLeading() else it.getText() - para.append(ContentText(text)) - } - } + para.convertJavadocElements(docComment.getDescriptionElements().dropWhile { it.getText().trim().isEmpty() }) docComment.getTags().forEach { tag -> - if (tag.getName() == "see") { - result.convertSeeTag(tag) - } else { - val subjectName = tag.getSubjectName() - val section = result.addSection(javadocSectionDisplayName(tag.getName()), subjectName) - tag.getDataElements().forEach { - if (it !is PsiDocTagValue || tag.getSubjectName() == null) { - section.append(ContentText(it.getText())) + when(tag.getName()) { + "see" -> result.convertSeeTag(tag) + "deprecated" -> { + deprecatedContent = Content() + deprecatedContent!!.convertJavadocElements(tag.getDataElements().toArrayList()) + } + else -> { + val subjectName = tag.getSubjectName() + val section = result.addSection(javadocSectionDisplayName(tag.getName()), subjectName) + + tag.getDataElements().forEach { + if (it !is PsiDocTagValue || tag.getSubjectName() == null) { + section.append(ContentText(it.getText())) + } } } } } - return result + return JavadocParseResult(result, deprecatedContent) + } + + private fun ContentBlock.convertJavadocElements(elements: Iterable) { + elements.forEach { + if (it is PsiInlineDocTag) { + append(convertInlineDocTag(it)) + } else { + val text = if (isEmpty()) it.getText().trimLeading() else it.getText() + append(ContentText(text)) + } + } } private fun Content.convertSeeTag(tag: PsiDocTag) { @@ -58,7 +71,14 @@ public class JavaDocumentationBuilder(private val options: DocumentationOptions, } private fun convertInlineDocTag(tag: PsiInlineDocTag) = when (tag.getName()) { - "link", "linkplain" -> resolveLink(tag.getValueElement()) ?: ContentText(tag.getText()) + "link", "linkplain" -> { + val link = resolveLink(tag.getValueElement()) + if (link != null) { + link.append(ContentText(tag.getValueElement()!!.getText())) + link + } + else ContentText(tag.getValueElement()!!.getText()) + } else -> ContentText(tag.getText()) } @@ -116,7 +136,7 @@ public class JavaDocumentationBuilder(private val options: DocumentationOptions, fun DocumentationNode(element: PsiNamedElement, kind: Kind, name: String = element.getName() ?: ""): DocumentationNode { - val docComment = if (element is PsiDocCommentOwner) parseDocumentation(element.getDocComment()) else Content.Empty + val (docComment, deprecatedContent) = parseDocumentation((element as? PsiDocCommentOwner)?.getDocComment()) val node = DocumentationNode(name, docComment, kind) if (element is PsiModifierListOwner) { node.appendModifiers(element) @@ -129,6 +149,10 @@ public class JavaDocumentationBuilder(private val options: DocumentationOptions, } } } + if (deprecatedContent != null) { + val deprecationNode = DocumentationNode("", deprecatedContent, Kind.Modifier) + node.append(deprecationNode, DocumentationReference.Kind.Deprecation) + } return node } diff --git a/test/data/format/javaDeprecated.html b/test/data/format/javaDeprecated.html new file mode 100644 index 00000000..aaeed534 --- /dev/null +++ b/test/data/format/javaDeprecated.html @@ -0,0 +1,14 @@ + + +test / test.Foo.foo + + +test / test / Foo / foo
+
+

foo

+public open fun foo(): Unit
+Deprecated: use#bar instead

+
+
+ + diff --git a/test/data/format/javaDeprecated.java b/test/data/format/javaDeprecated.java new file mode 100644 index 00000000..4216f205 --- /dev/null +++ b/test/data/format/javaDeprecated.java @@ -0,0 +1,7 @@ +package test; + +class Foo { + /** @deprecated use {@link #bar} instead */ + public void foo() {} + public void bar() {} +} diff --git a/test/data/format/javaLinkTag.html b/test/data/format/javaLinkTag.html index 65d33283..b5f03ef3 100644 --- a/test/data/format/javaLinkTag.html +++ b/test/data/format/javaLinkTag.html @@ -7,7 +7,7 @@

Foo

open class Foo : Any
-

Call to do the job. +

Call #bar() to do the job.



diff --git a/test/src/format/HtmlFormatTest.kt b/test/src/format/HtmlFormatTest.kt index feeab186..85badf8e 100644 --- a/test/src/format/HtmlFormatTest.kt +++ b/test/src/format/HtmlFormatTest.kt @@ -111,4 +111,10 @@ public class HtmlFormatTest { htmlService.appendNodes(tempLocation, output, model.members.single().members) } } + + Test fun javaDeprecated() { + verifyOutput("test/data/format/javaDeprecated.java", ".html") { model, output -> + htmlService.appendNodes(tempLocation, output, model.members.single().members.single { it.name == "Foo" }.members.filter { it.name == "foo" }) + } + } } -- cgit