From 8883839b8796589a1fa02b3dca5d1aae172b5c56 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Fri, 13 Apr 2018 19:47:07 +0300 Subject: [backport] Fix problems in as-java java-layout-html mode Extract common part of LanguageServices & other improvements Original: 853262e --- core/src/main/kotlin/Java/JavadocParser.kt | 43 +++++++++++++++--------------- 1 file changed, 21 insertions(+), 22 deletions(-) (limited to 'core/src/main/kotlin/Java') diff --git a/core/src/main/kotlin/Java/JavadocParser.kt b/core/src/main/kotlin/Java/JavadocParser.kt index c25f5813..db61a00a 100644 --- a/core/src/main/kotlin/Java/JavadocParser.kt +++ b/core/src/main/kotlin/Java/JavadocParser.kt @@ -20,8 +20,10 @@ interface JavaDocumentationParser { fun parseDocumentation(element: PsiNamedElement): JavadocParseResult } -class JavadocParser(private val refGraph: NodeReferenceGraph, - private val logger: DokkaLogger) : JavaDocumentationParser { +class JavadocParser( + private val refGraph: NodeReferenceGraph, + private val logger: DokkaLogger +) : JavaDocumentationParser { override fun parseDocumentation(element: PsiNamedElement): JavadocParseResult { val docComment = (element as? PsiDocCommentOwner)?.docComment if (docComment == null) return JavadocParseResult.Empty @@ -31,7 +33,7 @@ class JavadocParser(private val refGraph: NodeReferenceGraph, result.append(para) para.convertJavadocElements(docComment.descriptionElements.dropWhile { it.text.trim().isEmpty() }) docComment.tags.forEach { tag -> - when(tag.name) { + when (tag.name) { "see" -> result.convertSeeTag(tag) "deprecated" -> { deprecatedContent = Content() @@ -50,9 +52,9 @@ class JavadocParser(private val refGraph: NodeReferenceGraph, private fun PsiDocTag.contentElements(): Iterable { val tagValueElements = children - .dropWhile { it.node?.elementType == JavaDocTokenType.DOC_TAG_NAME } - .dropWhile { it is PsiWhiteSpace } - .filterNot { it.node?.elementType == JavaDocTokenType.DOC_COMMENT_LEADING_ASTERISKS } + .dropWhile { it.node?.elementType == JavaDocTokenType.DOC_TAG_NAME } + .dropWhile { it is PsiWhiteSpace } + .filterNot { it.node?.elementType == JavaDocTokenType.DOC_COMMENT_LEADING_ASTERISKS } return if (getSubjectName() != null) tagValueElements.dropWhile { it is PsiDocTagValue } else tagValueElements } @@ -83,7 +85,7 @@ class JavadocParser(private val refGraph: NodeReferenceGraph, } } - private fun createBlock(element: Element): ContentBlock = when(element.tagName()) { + private fun createBlock(element: Element): ContentBlock = when (element.tagName()) { "p" -> ContentParagraph() "b", "strong" -> ContentStrong() "i", "em" -> ContentEmphasis() @@ -99,28 +101,26 @@ class JavadocParser(private val refGraph: NodeReferenceGraph, } private fun createLink(element: Element): ContentBlock { - val docref = element.attr("docref") - if (docref != null) { - return ContentNodeLazyLink(docref, { -> refGraph.lookupOrWarn(docref, logger)}) + if (element.hasAttr("docref")) { + val docref = element.attr("docref") + return ContentNodeLazyLink(docref, { -> refGraph.lookupOrWarn(docref, logger) }) } - val href = element.attr("href") - if (href != null) { - return ContentExternalLink(href) + return if (element.hasAttr("href")) { + val href = element.attr("href") + ContentExternalLink(href) } else { - return ContentBlock() + ContentBlock() } } private fun MutableContent.convertSeeTag(tag: PsiDocTag) { - val linkElement = tag.linkElement() - if (linkElement == null) { - return - } + val linkElement = tag.linkElement() ?: return val seeSection = findSectionByTag(ContentTags.SeeAlso) ?: addSection(ContentTags.SeeAlso, null) val linkSignature = resolveLink(linkElement) val text = ContentText(linkElement.text) if (linkSignature != null) { - val linkNode = ContentNodeLazyLink(tag.valueElement!!.text, { -> refGraph.lookupOrWarn(linkSignature, logger)}) + val linkNode = + ContentNodeLazyLink(tag.valueElement!!.text, { -> refGraph.lookupOrWarn(linkSignature, logger) }) linkNode.append(text) seeSection.append(linkNode) } else { @@ -136,8 +136,7 @@ class JavadocParser(private val refGraph: NodeReferenceGraph, val labelText = tag.dataElements.firstOrNull { it is PsiDocToken }?.text ?: valueElement!!.text val link = "${labelText.htmlEscape()}" if (tag.name == "link") "$link" else link - } - else if (valueElement != null) { + } else if (valueElement != null) { valueElement.text } else { "" @@ -153,7 +152,7 @@ class JavadocParser(private val refGraph: NodeReferenceGraph, } private fun PsiDocTag.linkElement(): PsiElement? = - valueElement ?: dataElements.firstOrNull { it !is PsiWhiteSpace } + valueElement ?: dataElements.firstOrNull { it !is PsiWhiteSpace } private fun resolveLink(valueElement: PsiElement?): String? { val target = valueElement?.reference?.resolve() -- cgit From a3f16fd75c200020465f79563ca58b2833236865 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Tue, 24 Apr 2018 20:35:42 +0300 Subject: [backport] Stabilize signatures to fix linking from Java to Kotlin Basically there is 2 ways to get signature, from PSI and from descriptors, and there should be only one way in one session Original: adc09f2 --- core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt | 6 +++--- core/src/main/kotlin/Java/JavadocParser.kt | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'core/src/main/kotlin/Java') diff --git a/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt b/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt index cf2b0514..646096e5 100644 --- a/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt +++ b/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt @@ -45,10 +45,10 @@ class JavaPsiDocumentationBuilder : JavaDocumentationBuilder { private val refGraph: NodeReferenceGraph private val docParser: JavaDocumentationParser - @Inject constructor(options: DocumentationOptions, refGraph: NodeReferenceGraph, logger: DokkaLogger) { + @Inject constructor(options: DocumentationOptions, refGraph: NodeReferenceGraph, logger: DokkaLogger, signatureProvider: ElementSignatureProvider) { this.options = options this.refGraph = refGraph - this.docParser = JavadocParser(refGraph, logger) + this.docParser = JavadocParser(refGraph, logger, signatureProvider) } constructor(options: DocumentationOptions, refGraph: NodeReferenceGraph, docParser: JavaDocumentationParser) { @@ -61,7 +61,7 @@ class JavaPsiDocumentationBuilder : JavaDocumentationBuilder { if (skipFile(file) || file.classes.all { skipElement(it) }) { return } - val packageNode = module.findOrCreatePackageNode(file.packageName, emptyMap(), refGraph) + val packageNode = findOrCreatePackageNode(module, file.packageName, emptyMap(), refGraph) appendClasses(packageNode, file.classes) } diff --git a/core/src/main/kotlin/Java/JavadocParser.kt b/core/src/main/kotlin/Java/JavadocParser.kt index db61a00a..365ae298 100644 --- a/core/src/main/kotlin/Java/JavadocParser.kt +++ b/core/src/main/kotlin/Java/JavadocParser.kt @@ -22,7 +22,8 @@ interface JavaDocumentationParser { class JavadocParser( private val refGraph: NodeReferenceGraph, - private val logger: DokkaLogger + private val logger: DokkaLogger, + private val signatureProvider: ElementSignatureProvider ) : JavaDocumentationParser { override fun parseDocumentation(element: PsiNamedElement): JavadocParseResult { val docComment = (element as? PsiDocCommentOwner)?.docComment @@ -157,7 +158,7 @@ class JavadocParser( private fun resolveLink(valueElement: PsiElement?): String? { val target = valueElement?.reference?.resolve() if (target != null) { - return getSignature(target) + return signatureProvider.signature(target) } return null } -- cgit From 57a6bb55ddafbde4eab7c1c4344fff3ad3f0fe1f Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Fri, 27 Apr 2018 18:05:35 +0300 Subject: [backport] KT-24042: Fix structure of content paragraphs in Javadoc parser Original: edc0581 --- core/src/main/kotlin/Java/JavadocParser.kt | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) (limited to 'core/src/main/kotlin/Java') diff --git a/core/src/main/kotlin/Java/JavadocParser.kt b/core/src/main/kotlin/Java/JavadocParser.kt index 365ae298..08ae5354 100644 --- a/core/src/main/kotlin/Java/JavadocParser.kt +++ b/core/src/main/kotlin/Java/JavadocParser.kt @@ -30,9 +30,18 @@ class JavadocParser( if (docComment == null) return JavadocParseResult.Empty val result = MutableContent() var deprecatedContent: Content? = null - val para = ContentParagraph() - result.append(para) - para.convertJavadocElements(docComment.descriptionElements.dropWhile { it.text.trim().isEmpty() }) + val firstParagraph = ContentParagraph() + firstParagraph.convertJavadocElements(docComment.descriptionElements.dropWhile { it.text.trim().isEmpty() }) + val paragraphs = firstParagraph.children.dropWhile { it !is ContentParagraph } + firstParagraph.children.removeAll(paragraphs) + if (!firstParagraph.isEmpty()) { + result.append(firstParagraph) + } + paragraphs.forEach { + result.append(it) + } + val attrs = mutableListOf() + var since: DocumentationNode? = null docComment.tags.forEach { tag -> when (tag.name) { "see" -> result.convertSeeTag(tag) @@ -70,20 +79,24 @@ class JavadocParser( } val doc = Jsoup.parse(htmlBuilder.toString().trim()) doc.body().childNodes().forEach { - convertHtmlNode(it) + convertHtmlNode(it)?.let { append(it) } } } - private fun ContentBlock.convertHtmlNode(node: Node) { + private fun convertHtmlNode(node: Node): ContentNode? { if (node is TextNode) { - append(ContentText(node.text())) + return ContentText(node.text()) } else if (node is Element) { val childBlock = createBlock(node) node.childNodes().forEach { - childBlock.convertHtmlNode(it) + val child = convertHtmlNode(it) + if (child != null) { + childBlock.append(child) + } } - append(childBlock) + return (childBlock) } + return null } private fun createBlock(element: Element): ContentBlock = when (element.tagName()) { -- cgit From 6cfaf04a6a0a34299d3a39803322b2eea2afbaac Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Fri, 27 Apr 2018 19:42:25 +0300 Subject: [backport] KT-24149: Fix resolution of links in Javadoc Original: edc0581 --- core/src/main/kotlin/Java/JavadocParser.kt | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'core/src/main/kotlin/Java') diff --git a/core/src/main/kotlin/Java/JavadocParser.kt b/core/src/main/kotlin/Java/JavadocParser.kt index 08ae5354..0869081b 100644 --- a/core/src/main/kotlin/Java/JavadocParser.kt +++ b/core/src/main/kotlin/Java/JavadocParser.kt @@ -1,10 +1,12 @@ package org.jetbrains.dokka import com.intellij.psi.* +import com.intellij.psi.impl.source.tree.JavaDocElementType import com.intellij.psi.javadoc.PsiDocTag import com.intellij.psi.javadoc.PsiDocTagValue import com.intellij.psi.javadoc.PsiDocToken import com.intellij.psi.javadoc.PsiInlineDocTag +import com.intellij.psi.util.PsiTreeUtil import org.jsoup.Jsoup import org.jsoup.nodes.Element import org.jsoup.nodes.Node @@ -130,11 +132,11 @@ class JavadocParser( private fun MutableContent.convertSeeTag(tag: PsiDocTag) { val linkElement = tag.linkElement() ?: return val seeSection = findSectionByTag(ContentTags.SeeAlso) ?: addSection(ContentTags.SeeAlso, null) - val linkSignature = resolveLink(linkElement) + val linkSignature = resolveLink(tag.referenceElement()) val text = ContentText(linkElement.text) if (linkSignature != null) { val linkNode = - ContentNodeLazyLink(tag.valueElement!!.text, { -> refGraph.lookupOrWarn(linkSignature, logger) }) + ContentNodeLazyLink((tag.valueElement ?: linkElement).text, { -> refGraph.lookupOrWarn(linkSignature, logger) }) linkNode.append(text) seeSection.append(linkNode) } else { @@ -144,7 +146,7 @@ class JavadocParser( private fun convertInlineDocTag(tag: PsiInlineDocTag) = when (tag.name) { "link", "linkplain" -> { - val valueElement = tag.linkElement() + val valueElement = tag.referenceElement() val linkSignature = resolveLink(valueElement) if (linkSignature != null) { val labelText = tag.dataElements.firstOrNull { it is PsiDocToken }?.text ?: valueElement!!.text @@ -165,6 +167,15 @@ class JavadocParser( else -> tag.text } + private fun PsiDocTag.referenceElement(): PsiElement? = + linkElement()?.let { + if (it.node.elementType == JavaDocElementType.DOC_REFERENCE_HOLDER) { + PsiTreeUtil.findChildOfType(it, PsiJavaCodeReferenceElement::class.java) + } else { + it + } + } + private fun PsiDocTag.linkElement(): PsiElement? = valueElement ?: dataElements.firstOrNull { it !is PsiWhiteSpace } -- cgit From 432868e8732085a0b160466ddbe8262b793b4f95 Mon Sep 17 00:00:00 2001 From: Sean McQuillan Date: Thu, 26 Apr 2018 18:03:04 -0700 Subject: [backport] Support for {@inheritDoc} including grand inheritance and skip levels. Original: f100b73 --- core/src/main/kotlin/Java/JavadocParser.kt | 127 +++++++++++++++++++++++++---- 1 file changed, 113 insertions(+), 14 deletions(-) (limited to 'core/src/main/kotlin/Java') diff --git a/core/src/main/kotlin/Java/JavadocParser.kt b/core/src/main/kotlin/Java/JavadocParser.kt index 0869081b..f88f557d 100644 --- a/core/src/main/kotlin/Java/JavadocParser.kt +++ b/core/src/main/kotlin/Java/JavadocParser.kt @@ -2,11 +2,10 @@ package org.jetbrains.dokka import com.intellij.psi.* import com.intellij.psi.impl.source.tree.JavaDocElementType -import com.intellij.psi.javadoc.PsiDocTag -import com.intellij.psi.javadoc.PsiDocTagValue -import com.intellij.psi.javadoc.PsiDocToken -import com.intellij.psi.javadoc.PsiInlineDocTag +import com.intellij.psi.javadoc.* import com.intellij.psi.util.PsiTreeUtil +import com.intellij.util.IncorrectOperationException +import com.intellij.util.containers.isNullOrEmpty import org.jsoup.Jsoup import org.jsoup.nodes.Element import org.jsoup.nodes.Node @@ -33,7 +32,7 @@ class JavadocParser( val result = MutableContent() var deprecatedContent: Content? = null val firstParagraph = ContentParagraph() - firstParagraph.convertJavadocElements(docComment.descriptionElements.dropWhile { it.text.trim().isEmpty() }) + firstParagraph.convertJavadocElements(docComment.descriptionElements.dropWhile { it.text.trim().isEmpty() }, element) val paragraphs = firstParagraph.children.dropWhile { it !is ContentParagraph } firstParagraph.children.removeAll(paragraphs) if (!firstParagraph.isEmpty()) { @@ -49,13 +48,13 @@ class JavadocParser( "see" -> result.convertSeeTag(tag) "deprecated" -> { deprecatedContent = Content() - deprecatedContent!!.convertJavadocElements(tag.contentElements()) + deprecatedContent!!.convertJavadocElements(tag.contentElements(), element) } else -> { val subjectName = tag.getSubjectName() val section = result.addSection(javadocSectionDisplayName(tag.name), subjectName) - section.convertJavadocElements(tag.contentElements()) + section.convertJavadocElements(tag.contentElements(), element) } } } @@ -70,19 +69,23 @@ class JavadocParser( return if (getSubjectName() != null) tagValueElements.dropWhile { it is PsiDocTagValue } else tagValueElements } - private fun ContentBlock.convertJavadocElements(elements: Iterable) { + private fun ContentBlock.convertJavadocElements(elements: Iterable, element: PsiNamedElement) { + val doc = Jsoup.parse(expandAllForElements(elements, element)) + doc.body().childNodes().forEach { + convertHtmlNode(it)?.let { append(it) } + } + } + + private fun expandAllForElements(elements: Iterable, element: PsiNamedElement): String { val htmlBuilder = StringBuilder() elements.forEach { if (it is PsiInlineDocTag) { - htmlBuilder.append(convertInlineDocTag(it)) + htmlBuilder.append(convertInlineDocTag(it, element)) } else { htmlBuilder.append(it.text) } } - val doc = Jsoup.parse(htmlBuilder.toString().trim()) - doc.body().childNodes().forEach { - convertHtmlNode(it)?.let { append(it) } - } + return htmlBuilder.toString().trim() } private fun convertHtmlNode(node: Node): ContentNode? { @@ -144,7 +147,7 @@ class JavadocParser( } } - private fun convertInlineDocTag(tag: PsiInlineDocTag) = when (tag.name) { + private fun convertInlineDocTag(tag: PsiInlineDocTag, element: PsiNamedElement) = when (tag.name) { "link", "linkplain" -> { val valueElement = tag.referenceElement() val linkSignature = resolveLink(valueElement) @@ -164,6 +167,18 @@ class JavadocParser( val escaped = text.toString().trimStart().htmlEscape() if (tag.name == "code") "$escaped" else escaped } + "inheritDoc" -> { + val result = (element as? PsiMethod)?.let { + // @{inheritDoc} is only allowed on functions + val parent = tag.parent + when (parent) { + is PsiDocComment -> element.findSuperDocCommentOrWarn() + is PsiDocTag -> element.findSuperDocTagOrWarn(parent) + else -> null + } + } + result ?: tag.text + } else -> tag.text } @@ -193,4 +208,88 @@ class JavadocParser( } return null } + + private fun PsiMethod.findSuperDocCommentOrWarn(): String { + val method = findFirstSuperMethodWithDocumentation(this) + if (method != null) { + val descriptionElements = method.docComment?.descriptionElements?.dropWhile { + it.text.trim().isEmpty() + } ?: return "" + + return expandAllForElements(descriptionElements, method) + } + logger.warn("No docs found on supertype with {@inheritDoc} method ${this.name} in ${this.containingFile.name}:${this.lineNumber()}") + return "" + } + + + private fun PsiMethod.findSuperDocTagOrWarn(elementToExpand: PsiDocTag): String { + val result = findFirstSuperMethodWithDocumentationforTag(elementToExpand, this) + + if (result != null) { + val (method, tag) = result + + val contentElements = tag.contentElements().dropWhile { it.text.trim().isEmpty() } + + val expandedString = expandAllForElements(contentElements, method) + + return expandedString + } + logger.warn("No docs found on supertype for @${elementToExpand.name} ${elementToExpand.getSubjectName()} with {@inheritDoc} method ${this.name} in ${this.containingFile.name}:${this.lineNumber()}") + return "" + } + + private fun findFirstSuperMethodWithDocumentation(current: PsiMethod): PsiMethod? { + val superMethods = current.findSuperMethods() + for (method in superMethods) { + val docs = method.docComment?.descriptionElements?.dropWhile { it.text.trim().isEmpty() } + if (!docs.isNullOrEmpty()) { + return method + } + } + for (method in superMethods) { + val result = findFirstSuperMethodWithDocumentation(method) + if (result != null) { + return result + } + } + + return null + } + + private fun findFirstSuperMethodWithDocumentationforTag(elementToExpand: PsiDocTag, current: PsiMethod): Pair? { + val superMethods = current.findSuperMethods() + val mappedFilteredTags = superMethods.map { + it to it.docComment?.tags?.filter { it.name == elementToExpand.name } + } + + for ((method, tags) in mappedFilteredTags) { + tags ?: continue + for (tag in tags) { + val (tagSubject, elementSubject) = when (tag.name) { + "throws" -> { + // match class names only for throws, ignore possibly fully qualified path + // TODO: Always match exactly here + tag.getSubjectName()?.split(".")?.last() to elementToExpand.getSubjectName()?.split(".")?.last() + } + else -> { + tag.getSubjectName() to elementToExpand.getSubjectName() + } + } + + if (tagSubject == elementSubject) { + return method to tag + } + } + } + + for (method in superMethods) { + val result = findFirstSuperMethodWithDocumentationforTag(elementToExpand, method) + if (result != null) { + return result + } + } + return null + } + } -- cgit From a16ae6c02e1ec7270fb161c63908b5b3831bce8e Mon Sep 17 00:00:00 2001 From: Sean McQuillan Date: Thu, 26 Apr 2018 18:03:04 -0700 Subject: [backport] Support for {@inheritDoc} including grand inheritance and skip levels. Original: 0eda743 --- core/src/main/kotlin/Java/JavadocParser.kt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'core/src/main/kotlin/Java') diff --git a/core/src/main/kotlin/Java/JavadocParser.kt b/core/src/main/kotlin/Java/JavadocParser.kt index f88f557d..554cd2d3 100644 --- a/core/src/main/kotlin/Java/JavadocParser.kt +++ b/core/src/main/kotlin/Java/JavadocParser.kt @@ -1,6 +1,8 @@ package org.jetbrains.dokka import com.intellij.psi.* +import com.intellij.psi.impl.source.javadoc.CorePsiDocTagValueImpl +import com.intellij.psi.javadoc.* import com.intellij.psi.impl.source.tree.JavaDocElementType import com.intellij.psi.javadoc.* import com.intellij.psi.util.PsiTreeUtil @@ -41,14 +43,13 @@ class JavadocParser( paragraphs.forEach { result.append(it) } - val attrs = mutableListOf() - var since: DocumentationNode? = null docComment.tags.forEach { tag -> when (tag.name) { "see" -> result.convertSeeTag(tag) "deprecated" -> { - deprecatedContent = Content() - deprecatedContent!!.convertJavadocElements(tag.contentElements(), element) + deprecatedContent = Content().apply { + convertJavadocElements(tag.contentElements(), element) + } } else -> { val subjectName = tag.getSubjectName() -- cgit From 74b228108445a8a9024b6892f6562d77c658fc64 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Thu, 3 May 2018 18:20:33 +0300 Subject: [backport] KT-24152: Support implicit sections inheritance Original: 5636fac --- core/src/main/kotlin/Java/JavadocParser.kt | 40 +++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) (limited to 'core/src/main/kotlin/Java') diff --git a/core/src/main/kotlin/Java/JavadocParser.kt b/core/src/main/kotlin/Java/JavadocParser.kt index 554cd2d3..41b77aed 100644 --- a/core/src/main/kotlin/Java/JavadocParser.kt +++ b/core/src/main/kotlin/Java/JavadocParser.kt @@ -2,12 +2,12 @@ package org.jetbrains.dokka import com.intellij.psi.* import com.intellij.psi.impl.source.javadoc.CorePsiDocTagValueImpl -import com.intellij.psi.javadoc.* import com.intellij.psi.impl.source.tree.JavaDocElementType import com.intellij.psi.javadoc.* import com.intellij.psi.util.PsiTreeUtil import com.intellij.util.IncorrectOperationException import com.intellij.util.containers.isNullOrEmpty +import org.jetbrains.kotlin.utils.keysToMap import org.jsoup.Jsoup import org.jsoup.nodes.Element import org.jsoup.nodes.Node @@ -43,6 +43,17 @@ class JavadocParser( paragraphs.forEach { result.append(it) } + + if (element is PsiMethod) { + val tagsByName = element.searchInheritedTags() + for ((tagName, tags) in tagsByName) { + for ((tag, context) in tags) { + val section = result.addSection(javadocSectionDisplayName(tagName), tag.getSubjectName()) + section.convertJavadocElements(tag.contentElements(), context) + } + } + } + docComment.tags.forEach { tag -> when (tag.name) { "see" -> result.convertSeeTag(tag) @@ -51,6 +62,7 @@ class JavadocParser( convertJavadocElements(tag.contentElements(), element) } } + in tagsToInherit -> {} else -> { val subjectName = tag.getSubjectName() val section = result.addSection(javadocSectionDisplayName(tag.name), subjectName) @@ -62,6 +74,32 @@ class JavadocParser( return JavadocParseResult(result, deprecatedContent) } + private val tagsToInherit = setOf("param", "return", "throws") + + private data class TagWithContext(val tag: PsiDocTag, val context: PsiNamedElement) + + private fun PsiMethod.searchInheritedTags(): Map> { + + val output = tagsToInherit.keysToMap { mutableMapOf() } + + fun recursiveSearch(methods: Array) { + for (method in methods) { + recursiveSearch(method.findSuperMethods()) + } + for (method in methods) { + for (tag in method.docComment?.tags.orEmpty()) { + if (tag.name in tagsToInherit) { + output[tag.name]!![tag.getSubjectName()] = TagWithContext(tag, method) + } + } + } + } + + recursiveSearch(arrayOf(this)) + return output.mapValues { it.value.values } + } + + private fun PsiDocTag.contentElements(): Iterable { val tagValueElements = children .dropWhile { it.node?.elementType == JavaDocTokenType.DOC_TAG_NAME } -- cgit From a50de81d3d0ce88d2fd8e91a55b203ba49e66eb1 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Fri, 4 May 2018 00:32:40 +0300 Subject: [backport] KT-24028: Add type info to param and return section in javadoc Original: a603157 --- core/src/main/kotlin/Java/JavadocParser.kt | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'core/src/main/kotlin/Java') diff --git a/core/src/main/kotlin/Java/JavadocParser.kt b/core/src/main/kotlin/Java/JavadocParser.kt index 41b77aed..5e23e357 100644 --- a/core/src/main/kotlin/Java/JavadocParser.kt +++ b/core/src/main/kotlin/Java/JavadocParser.kt @@ -28,6 +28,18 @@ class JavadocParser( private val logger: DokkaLogger, private val signatureProvider: ElementSignatureProvider ) : JavaDocumentationParser { + + private fun ContentSection.appendTypeElement(signature: String, selector: (DocumentationNode) -> DocumentationNode?) { + append(LazyContentBlock { + val node = refGraph.lookupOrWarn(signature, logger)?.let(selector) + if (node != null) { + it.append(NodeRenderContent(node, LanguageService.RenderMode.SUMMARY)) + it.symbol(":") + it.text(" ") + } + }) + } + override fun parseDocumentation(element: PsiNamedElement): JavadocParseResult { val docComment = (element as? PsiDocCommentOwner)?.docComment if (docComment == null) return JavadocParseResult.Empty @@ -49,6 +61,17 @@ class JavadocParser( for ((tagName, tags) in tagsByName) { for ((tag, context) in tags) { val section = result.addSection(javadocSectionDisplayName(tagName), tag.getSubjectName()) + val signature = signatureProvider.signature(element) + when (tagName) { + "param" -> { + section.appendTypeElement(signature) { + it.details.find { it.kind == NodeKind.Parameter }?.detailOrNull(NodeKind.Type) + } + } + "return" -> { + section.appendTypeElement(signature) { it.detailOrNull(NodeKind.Type) } + } + } section.convertJavadocElements(tag.contentElements(), context) } } -- cgit From b00dabc4c53a71f745c29a135541b02f8dd7d266 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Fri, 4 May 2018 21:35:02 +0300 Subject: [backport] KT-24271: Support external link resolution in JavadocParser Original: ace3914 --- .../kotlin/Java/JavaPsiDocumentationBuilder.kt | 10 ++++- core/src/main/kotlin/Java/JavadocParser.kt | 51 ++++++++++++++++------ 2 files changed, 46 insertions(+), 15 deletions(-) (limited to 'core/src/main/kotlin/Java') diff --git a/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt b/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt index 646096e5..8b30a6b4 100644 --- a/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt +++ b/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt @@ -45,10 +45,16 @@ class JavaPsiDocumentationBuilder : JavaDocumentationBuilder { private val refGraph: NodeReferenceGraph private val docParser: JavaDocumentationParser - @Inject constructor(options: DocumentationOptions, refGraph: NodeReferenceGraph, logger: DokkaLogger, signatureProvider: ElementSignatureProvider) { + @Inject constructor( + options: DocumentationOptions, + refGraph: NodeReferenceGraph, + logger: DokkaLogger, + signatureProvider: ElementSignatureProvider, + externalDocumentationLinkResolver: ExternalDocumentationLinkResolver + ) { this.options = options this.refGraph = refGraph - this.docParser = JavadocParser(refGraph, logger, signatureProvider) + this.docParser = JavadocParser(refGraph, logger, signatureProvider, externalDocumentationLinkResolver) } constructor(options: DocumentationOptions, refGraph: NodeReferenceGraph, docParser: JavaDocumentationParser) { diff --git a/core/src/main/kotlin/Java/JavadocParser.kt b/core/src/main/kotlin/Java/JavadocParser.kt index 5e23e357..e1b15cb2 100644 --- a/core/src/main/kotlin/Java/JavadocParser.kt +++ b/core/src/main/kotlin/Java/JavadocParser.kt @@ -26,7 +26,8 @@ interface JavaDocumentationParser { class JavadocParser( private val refGraph: NodeReferenceGraph, private val logger: DokkaLogger, - private val signatureProvider: ElementSignatureProvider + private val signatureProvider: ElementSignatureProvider, + private val externalDocumentationLinkResolver: ExternalDocumentationLinkResolver ) : JavaDocumentationParser { private fun ContentSection.appendTypeElement(signature: String, selector: (DocumentationNode) -> DocumentationNode?) { @@ -197,25 +198,41 @@ class JavadocParser( private fun MutableContent.convertSeeTag(tag: PsiDocTag) { val linkElement = tag.linkElement() ?: return val seeSection = findSectionByTag(ContentTags.SeeAlso) ?: addSection(ContentTags.SeeAlso, null) - val linkSignature = resolveLink(tag.referenceElement()) + + val valueElement = tag.referenceElement() + val externalLink = resolveExternalLink(valueElement) val text = ContentText(linkElement.text) - if (linkSignature != null) { - val linkNode = - ContentNodeLazyLink((tag.valueElement ?: linkElement).text, { -> refGraph.lookupOrWarn(linkSignature, logger) }) - linkNode.append(text) - seeSection.append(linkNode) - } else { - seeSection.append(text) + + val linkSignature by lazy { resolveInternalLink(valueElement) } + val node = when { + externalLink != null -> { + val linkNode = ContentExternalLink(externalLink) + linkNode.append(text) + linkNode + } + linkSignature != null -> { + val linkNode = + ContentNodeLazyLink( + (tag.valueElement ?: linkElement).text, + { -> refGraph.lookupOrWarn(linkSignature, logger) } + ) + linkNode.append(text) + linkNode + } + else -> text } + seeSection.append(node) } private fun convertInlineDocTag(tag: PsiInlineDocTag, element: PsiNamedElement) = when (tag.name) { "link", "linkplain" -> { val valueElement = tag.referenceElement() - val linkSignature = resolveLink(valueElement) - if (linkSignature != null) { + val externalLink = resolveExternalLink(valueElement) + val linkSignature by lazy { resolveInternalLink(valueElement) } + if (externalLink != null || linkSignature != null) { val labelText = tag.dataElements.firstOrNull { it is PsiDocToken }?.text ?: valueElement!!.text - val link = "${labelText.htmlEscape()}" + val linkTarget = if (externalLink != null) "href=\"$externalLink\"" else "docref=\"$linkSignature\"" + val link = "${labelText.htmlEscape()}" if (tag.name == "link") "$link" else link } else if (valueElement != null) { valueElement.text @@ -256,7 +273,15 @@ class JavadocParser( private fun PsiDocTag.linkElement(): PsiElement? = valueElement ?: dataElements.firstOrNull { it !is PsiWhiteSpace } - private fun resolveLink(valueElement: PsiElement?): String? { + private fun resolveExternalLink(valueElement: PsiElement?): String? { + val target = valueElement?.reference?.resolve() + if (target != null) { + return externalDocumentationLinkResolver.buildExternalDocumentationLink(target) + } + return null + } + + private fun resolveInternalLink(valueElement: PsiElement?): String? { val target = valueElement?.reference?.resolve() if (target != null) { return signatureProvider.signature(target) -- cgit From 44ad68386658dde985207ea0aedb19c96d9b3f93 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Mon, 7 May 2018 16:37:12 +0300 Subject: [backport] KT-24277: Persist inpage anchors (aka bookmarks) from Javadoc Original: 4fddba5 --- core/src/main/kotlin/Java/JavadocParser.kt | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'core/src/main/kotlin/Java') diff --git a/core/src/main/kotlin/Java/JavadocParser.kt b/core/src/main/kotlin/Java/JavadocParser.kt index e1b15cb2..8cd274e7 100644 --- a/core/src/main/kotlin/Java/JavadocParser.kt +++ b/core/src/main/kotlin/Java/JavadocParser.kt @@ -183,15 +183,19 @@ class JavadocParser( } private fun createLink(element: Element): ContentBlock { - if (element.hasAttr("docref")) { - val docref = element.attr("docref") - return ContentNodeLazyLink(docref, { -> refGraph.lookupOrWarn(docref, logger) }) - } - return if (element.hasAttr("href")) { - val href = element.attr("href") - ContentExternalLink(href) - } else { - ContentBlock() + return when { + element.hasAttr("docref") -> { + val docref = element.attr("docref") + ContentNodeLazyLink(docref, { -> refGraph.lookupOrWarn(docref, logger) }) + } + element.hasAttr("href") -> { + val href = element.attr("href") + ContentExternalLink(href) + } + element.hasAttr("name") -> { + ContentBookmark(element.attr("name")) + } + else -> ContentBlock() } } -- cgit From 4301503416ed45783a81250295adf4b5a86c4280 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Mon, 7 May 2018 17:28:22 +0300 Subject: [backport] KT-24299: Fix local links resolved in incorrect context Original: fababd4 --- core/src/main/kotlin/Java/JavadocParser.kt | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'core/src/main/kotlin/Java') diff --git a/core/src/main/kotlin/Java/JavadocParser.kt b/core/src/main/kotlin/Java/JavadocParser.kt index 8cd274e7..9f9ea017 100644 --- a/core/src/main/kotlin/Java/JavadocParser.kt +++ b/core/src/main/kotlin/Java/JavadocParser.kt @@ -12,6 +12,7 @@ import org.jsoup.Jsoup import org.jsoup.nodes.Element import org.jsoup.nodes.Node import org.jsoup.nodes.TextNode +import java.net.URI data class JavadocParseResult(val content: Content, val deprecatedContent: Content?) { companion object { @@ -190,7 +191,18 @@ class JavadocParser( } element.hasAttr("href") -> { val href = element.attr("href") - ContentExternalLink(href) + + val uri = try { + URI(href) + } catch (_: Exception) { + null + } + + if (uri?.isAbsolute == false) { + ContentLocalLink(href) + } else { + ContentExternalLink(href) + } } element.hasAttr("name") -> { ContentBookmark(element.attr("name")) -- cgit From 9715d6300d6e0082a3e900c7e5cff873b8c294f2 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Sat, 26 May 2018 00:12:38 +0300 Subject: Provide signature for packages --- core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt | 1 + 1 file changed, 1 insertion(+) (limited to 'core/src/main/kotlin/Java') diff --git a/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt b/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt index 8b30a6b4..6d5825e9 100644 --- a/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt +++ b/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.psi.KtModifierListOwner import java.io.File fun getSignature(element: PsiElement?) = when(element) { + is PsiPackage -> element.qualifiedName is PsiClass -> element.qualifiedName is PsiField -> element.containingClass!!.qualifiedName + "$" + element.name is PsiMethod -> -- cgit From 633fda36403e8c5483054737d285dd01b5c190bb Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Sat, 26 May 2018 00:15:47 +0300 Subject: KT-24025: Support constants in as java mode #KT-24025 fixed --- .../main/kotlin/Java/JavaPsiDocumentationBuilder.kt | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'core/src/main/kotlin/Java') diff --git a/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt b/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt index 6d5825e9..9eabc227 100644 --- a/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt +++ b/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt @@ -1,7 +1,9 @@ package org.jetbrains.dokka import com.google.inject.Inject +import com.intellij.openapi.util.text.StringUtil import com.intellij.psi.* +import com.intellij.psi.impl.JavaConstantExpressionEvaluator import com.intellij.psi.util.InheritanceUtil import com.intellij.psi.util.PsiTreeUtil import org.jetbrains.kotlin.asJava.elements.KtLightDeclaration @@ -207,11 +209,28 @@ class JavaPsiDocumentationBuilder : JavaDocumentationBuilder { fun PsiField.build(): DocumentationNode { val node = nodeForElement(this, nodeKind()) node.appendType(type) - node.appendModifiers(this) + + node.appendConstantValueIfAny(this) register(this, node) return node } + private fun DocumentationNode.appendConstantValueIfAny(field: PsiField) { + val modifierList = field.modifierList ?: return + val initializer = field.initializer ?: return + if (field.type is PsiPrimitiveType && + modifierList.hasExplicitModifier(PsiModifier.FINAL) && + modifierList.hasExplicitModifier(PsiModifier.STATIC)) { + val value = JavaConstantExpressionEvaluator.computeConstantExpression(initializer, false) + val text = when(value) { + is String -> + "\"" + StringUtil.escapeStringCharacters(value) + "\"" + else -> value.toString() + } + append(DocumentationNode(text, Content.Empty, NodeKind.Value), RefKind.Detail) + } + } + private fun PsiField.nodeKind(): NodeKind = when { this is PsiEnumConstant -> NodeKind.EnumItem else -> NodeKind.Field -- cgit From 0485472951134685c434d148b6fe5b6393217023 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Sat, 9 Jun 2018 23:51:43 +0300 Subject: KT-24032: Fix parameter rendering in asJava mode #KT-24032 fixed --- core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'core/src/main/kotlin/Java') diff --git a/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt b/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt index 9eabc227..332afffb 100644 --- a/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt +++ b/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt @@ -148,11 +148,13 @@ class JavaPsiDocumentationBuilder : JavaDocumentationBuilder { hasSuppressDocTag(element) || skipElementBySuppressedFiles(element) - private fun skipElementByVisibility(element: Any): Boolean = element is PsiModifierListOwner && - !(options.effectivePackageOptions((element.containingFile as? PsiJavaFile)?.packageName ?: "").includeNonPublic) && - (element.hasModifierProperty(PsiModifier.PRIVATE) || - element.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) || - element.isInternal()) + private fun skipElementByVisibility(element: Any): Boolean = + element is PsiModifierListOwner && + element !is PsiParameter && + !(options.effectivePackageOptions((element.containingFile as? PsiJavaFile)?.packageName ?: "").includeNonPublic) && + (element.hasModifierProperty(PsiModifier.PRIVATE) || + element.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) || + element.isInternal()) private fun skipElementBySuppressedFiles(element: Any): Boolean = element is PsiElement && File(element.containingFile.virtualFile.path).absoluteFile in options.suppressedFiles -- cgit From 7ef0cf32835d6d652e408a2115d58c37749320c5 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Mon, 29 Oct 2018 17:12:47 +0300 Subject: Cleanup support for NodeRenderContent --- core/src/main/kotlin/Java/JavadocParser.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'core/src/main/kotlin/Java') diff --git a/core/src/main/kotlin/Java/JavadocParser.kt b/core/src/main/kotlin/Java/JavadocParser.kt index 9f9ea017..1144763b 100644 --- a/core/src/main/kotlin/Java/JavadocParser.kt +++ b/core/src/main/kotlin/Java/JavadocParser.kt @@ -33,12 +33,12 @@ class JavadocParser( private fun ContentSection.appendTypeElement(signature: String, selector: (DocumentationNode) -> DocumentationNode?) { append(LazyContentBlock { - val node = refGraph.lookupOrWarn(signature, logger)?.let(selector) - if (node != null) { - it.append(NodeRenderContent(node, LanguageService.RenderMode.SUMMARY)) - it.symbol(":") - it.text(" ") - } + val node = refGraph.lookupOrWarn(signature, logger)?.let(selector) ?: return@LazyContentBlock emptyList() + listOf(ContentBlock().apply { + append(NodeRenderContent(node, LanguageService.RenderMode.SUMMARY)) + symbol(":") + text(" ") + }) }) } -- cgit From 8afbc009483636adbc8562b0707439b595d59242 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Mon, 29 Oct 2018 17:13:42 +0300 Subject: Refactor code of javadoc paragraphs converting --- core/src/main/kotlin/Java/JavadocParser.kt | 39 ++++++++++++++++-------------- 1 file changed, 21 insertions(+), 18 deletions(-) (limited to 'core/src/main/kotlin/Java') diff --git a/core/src/main/kotlin/Java/JavadocParser.kt b/core/src/main/kotlin/Java/JavadocParser.kt index 1144763b..d6e46c50 100644 --- a/core/src/main/kotlin/Java/JavadocParser.kt +++ b/core/src/main/kotlin/Java/JavadocParser.kt @@ -1,11 +1,9 @@ package org.jetbrains.dokka import com.intellij.psi.* -import com.intellij.psi.impl.source.javadoc.CorePsiDocTagValueImpl import com.intellij.psi.impl.source.tree.JavaDocElementType import com.intellij.psi.javadoc.* import com.intellij.psi.util.PsiTreeUtil -import com.intellij.util.IncorrectOperationException import com.intellij.util.containers.isNullOrEmpty import org.jetbrains.kotlin.utils.keysToMap import org.jsoup.Jsoup @@ -43,20 +41,19 @@ class JavadocParser( } override fun parseDocumentation(element: PsiNamedElement): JavadocParseResult { - val docComment = (element as? PsiDocCommentOwner)?.docComment - if (docComment == null) return JavadocParseResult.Empty + val docComment = (element as? PsiDocCommentOwner)?.docComment ?: return JavadocParseResult.Empty val result = MutableContent() var deprecatedContent: Content? = null + + val nodes = convertJavadocElements(docComment.descriptionElements.dropWhile { it.text.trim().isEmpty() }, element) + val firstParagraphContents = nodes.takeWhile { it !is ContentParagraph } val firstParagraph = ContentParagraph() - firstParagraph.convertJavadocElements(docComment.descriptionElements.dropWhile { it.text.trim().isEmpty() }, element) - val paragraphs = firstParagraph.children.dropWhile { it !is ContentParagraph } - firstParagraph.children.removeAll(paragraphs) - if (!firstParagraph.isEmpty()) { + if (firstParagraphContents.isNotEmpty()) { + firstParagraphContents.forEach { firstParagraph.append(it) } result.append(firstParagraph) } - paragraphs.forEach { - result.append(it) - } + + result.appendAll(nodes.drop(firstParagraphContents.size)) if (element is PsiMethod) { val tagsByName = element.searchInheritedTags() @@ -67,14 +64,16 @@ class JavadocParser( when (tagName) { "param" -> { section.appendTypeElement(signature) { - it.details.find { it.kind == NodeKind.Parameter }?.detailOrNull(NodeKind.Type) + it.details + .find { node -> node.kind == NodeKind.Parameter && node.name == tag.getSubjectName() } + ?.detailOrNull(NodeKind.Type) } } "return" -> { section.appendTypeElement(signature) { it.detailOrNull(NodeKind.Type) } } } - section.convertJavadocElements(tag.contentElements(), context) + section.appendAll(convertJavadocElements(tag.contentElements(), context)) } } } @@ -84,7 +83,7 @@ class JavadocParser( "see" -> result.convertSeeTag(tag) "deprecated" -> { deprecatedContent = Content().apply { - convertJavadocElements(tag.contentElements(), element) + appendAll(convertJavadocElements(tag.contentElements(), element)) } } in tagsToInherit -> {} @@ -92,7 +91,7 @@ class JavadocParser( val subjectName = tag.getSubjectName() val section = result.addSection(javadocSectionDisplayName(tag.name), subjectName) - section.convertJavadocElements(tag.contentElements(), element) + section.appendAll(convertJavadocElements(tag.contentElements(), element)) } } } @@ -133,13 +132,17 @@ class JavadocParser( return if (getSubjectName() != null) tagValueElements.dropWhile { it is PsiDocTagValue } else tagValueElements } - private fun ContentBlock.convertJavadocElements(elements: Iterable, element: PsiNamedElement) { + private fun convertJavadocElements(elements: Iterable, element: PsiNamedElement): List { val doc = Jsoup.parse(expandAllForElements(elements, element)) - doc.body().childNodes().forEach { - convertHtmlNode(it)?.let { append(it) } + return doc.body().childNodes().mapNotNull { + convertHtmlNode(it) } } + private fun ContentBlock.appendAll(nodes: List) { + nodes.forEach { append(it) } + } + private fun expandAllForElements(elements: Iterable, element: PsiNamedElement): String { val htmlBuilder = StringBuilder() elements.forEach { -- cgit From b0310f8f3e242ffc64c56e8fd95710b25b37dfff Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Fri, 23 Nov 2018 19:50:49 +0300 Subject: Fix constant values for Java --- core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'core/src/main/kotlin/Java') diff --git a/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt b/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt index 332afffb..f0b3a56b 100644 --- a/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt +++ b/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt @@ -220,11 +220,11 @@ class JavaPsiDocumentationBuilder : JavaDocumentationBuilder { private fun DocumentationNode.appendConstantValueIfAny(field: PsiField) { val modifierList = field.modifierList ?: return val initializer = field.initializer ?: return - if (field.type is PsiPrimitiveType && - modifierList.hasExplicitModifier(PsiModifier.FINAL) && + if (modifierList.hasExplicitModifier(PsiModifier.FINAL) && modifierList.hasExplicitModifier(PsiModifier.STATIC)) { val value = JavaConstantExpressionEvaluator.computeConstantExpression(initializer, false) val text = when(value) { + null -> return // No value found is String -> "\"" + StringUtil.escapeStringCharacters(value) + "\"" else -> value.toString() -- cgit From a2104d1e24a452cbfd2a76c204fc58475aa70057 Mon Sep 17 00:00:00 2001 From: Błażej Kardyś Date: Tue, 5 Feb 2019 16:05:15 +0100 Subject: Fix @deprecated visibility in JavaDoc (#420) #343 Fixed --- core/src/main/kotlin/Java/JavadocParser.kt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'core/src/main/kotlin/Java') diff --git a/core/src/main/kotlin/Java/JavadocParser.kt b/core/src/main/kotlin/Java/JavadocParser.kt index d6e46c50..39a4568a 100644 --- a/core/src/main/kotlin/Java/JavadocParser.kt +++ b/core/src/main/kotlin/Java/JavadocParser.kt @@ -83,7 +83,7 @@ class JavadocParser( "see" -> result.convertSeeTag(tag) "deprecated" -> { deprecatedContent = Content().apply { - appendAll(convertJavadocElements(tag.contentElements(), element)) + appendAll(convertJavadocElements(tag.contentElementsOrFirstChild(), element)) } } in tagsToInherit -> {} @@ -122,9 +122,10 @@ class JavadocParser( recursiveSearch(arrayOf(this)) return output.mapValues { it.value.values } } + private fun PsiDocTag.contentElementsOrFirstChild(): Collection = contentElements() + .takeIf { it.isNotEmpty() } ?: children.take(1) - - private fun PsiDocTag.contentElements(): Iterable { + private fun PsiDocTag.contentElements(): Collection { val tagValueElements = children .dropWhile { it.node?.elementType == JavaDocTokenType.DOC_TAG_NAME } .dropWhile { it is PsiWhiteSpace } -- cgit From ff25593e8af941c624f3bee8bc031ae53c3700d5 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Mon, 25 Feb 2019 19:45:09 +0300 Subject: Fix problem on consumer side, improve test (#420) --- core/src/main/kotlin/Java/JavadocParser.kt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'core/src/main/kotlin/Java') diff --git a/core/src/main/kotlin/Java/JavadocParser.kt b/core/src/main/kotlin/Java/JavadocParser.kt index 39a4568a..d6e46c50 100644 --- a/core/src/main/kotlin/Java/JavadocParser.kt +++ b/core/src/main/kotlin/Java/JavadocParser.kt @@ -83,7 +83,7 @@ class JavadocParser( "see" -> result.convertSeeTag(tag) "deprecated" -> { deprecatedContent = Content().apply { - appendAll(convertJavadocElements(tag.contentElementsOrFirstChild(), element)) + appendAll(convertJavadocElements(tag.contentElements(), element)) } } in tagsToInherit -> {} @@ -122,10 +122,9 @@ class JavadocParser( recursiveSearch(arrayOf(this)) return output.mapValues { it.value.values } } - private fun PsiDocTag.contentElementsOrFirstChild(): Collection = contentElements() - .takeIf { it.isNotEmpty() } ?: children.take(1) - private fun PsiDocTag.contentElements(): Collection { + + private fun PsiDocTag.contentElements(): Iterable { val tagValueElements = children .dropWhile { it.node?.elementType == JavaDocTokenType.DOC_TAG_NAME } .dropWhile { it is PsiWhiteSpace } -- cgit From f4aeac0a974837a18d0c18d42bd5980dffa043fb Mon Sep 17 00:00:00 2001 From: Dominik Schürmann Date: Mon, 21 Jan 2019 01:16:09 +0100 Subject: Preserve newlines in javadoc code blocks --- core/src/main/kotlin/Java/JavadocParser.kt | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'core/src/main/kotlin/Java') diff --git a/core/src/main/kotlin/Java/JavadocParser.kt b/core/src/main/kotlin/Java/JavadocParser.kt index d6e46c50..3411b5c7 100644 --- a/core/src/main/kotlin/Java/JavadocParser.kt +++ b/core/src/main/kotlin/Java/JavadocParser.kt @@ -160,13 +160,17 @@ class JavadocParser( return ContentText(node.text()) } else if (node is Element) { val childBlock = createBlock(node) - node.childNodes().forEach { - val child = convertHtmlNode(it) - if (child != null) { - childBlock.append(child) + if (childBlock is ContentBlockCode) { + childBlock.append(ContentText(node.text())) + } else { + node.childNodes().forEach { + val child = convertHtmlNode(it) + if (child != null) { + childBlock.append(child) + } } + return (childBlock) } - return (childBlock) } return null } -- cgit From 3fc4102597437dbf217c96b70000cac5fb9b591b Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Mon, 25 Feb 2019 21:34:14 +0300 Subject: Rework logic to avoid loosing tags inside pre --- core/src/main/kotlin/Java/JavadocParser.kt | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) (limited to 'core/src/main/kotlin/Java') diff --git a/core/src/main/kotlin/Java/JavadocParser.kt b/core/src/main/kotlin/Java/JavadocParser.kt index 3411b5c7..70af73f9 100644 --- a/core/src/main/kotlin/Java/JavadocParser.kt +++ b/core/src/main/kotlin/Java/JavadocParser.kt @@ -155,32 +155,30 @@ class JavadocParser( return htmlBuilder.toString().trim() } - private fun convertHtmlNode(node: Node): ContentNode? { + private fun convertHtmlNode(node: Node, insidePre: Boolean = false): ContentNode? { if (node is TextNode) { - return ContentText(node.text()) + val text = if (insidePre) node.wholeText else node.text() + return ContentText(text) } else if (node is Element) { - val childBlock = createBlock(node) - if (childBlock is ContentBlockCode) { - childBlock.append(ContentText(node.text())) - } else { - node.childNodes().forEach { - val child = convertHtmlNode(it) - if (child != null) { - childBlock.append(child) - } + val childBlock = createBlock(node, insidePre) + + node.childNodes().forEach { + val child = convertHtmlNode(it, insidePre || childBlock is ContentBlockCode) + if (child != null) { + childBlock.append(child) } - return (childBlock) } + return childBlock } return null } - private fun createBlock(element: Element): ContentBlock = when (element.tagName()) { + private fun createBlock(element: Element, insidePre: Boolean): ContentBlock = when (element.tagName()) { "p" -> ContentParagraph() "b", "strong" -> ContentStrong() "i", "em" -> ContentEmphasis() "s", "del" -> ContentStrikethrough() - "code" -> ContentCode() + "code" -> if (insidePre) ContentBlock() else ContentCode() "pre" -> ContentBlockCode() "ul" -> ContentUnorderedList() "ol" -> ContentOrderedList() -- cgit From 61b126692bb2ede06911ae1c493e8417f0bbe49d Mon Sep 17 00:00:00 2001 From: Kamil Doległo Date: Mon, 11 Mar 2019 17:11:50 +0100 Subject: Allow linking arguments with methods, change link label (#431) * Add PsiParameter to link arguments with methods, change link label --- core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'core/src/main/kotlin/Java') diff --git a/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt b/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt index f0b3a56b..1ef601d3 100644 --- a/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt +++ b/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt @@ -20,11 +20,19 @@ fun getSignature(element: PsiElement?) = when(element) { is PsiClass -> element.qualifiedName is PsiField -> element.containingClass!!.qualifiedName + "$" + element.name is PsiMethod -> - element.containingClass!!.qualifiedName + "$" + element.name + "(" + - element.parameterList.parameters.map { it.type.typeSignature() }.joinToString(",") + ")" + methodSignature(element) + is PsiParameter -> { + val method = (element.parent.parent as PsiMethod) + methodSignature(method) + } else -> null } +private fun methodSignature(method: PsiMethod): String { + return method.containingClass!!.qualifiedName + "$" + method.name + "(" + + method.parameterList.parameters.map { it.type.typeSignature() }.joinToString(",") + ")" +} + private fun PsiType.typeSignature(): String = when(this) { is PsiArrayType -> "Array((${componentType.typeSignature()}))" is PsiPrimitiveType -> "kotlin." + canonicalText.capitalize() -- cgit From 52b303d4251d54ddf9f09330f902621689a50f5d Mon Sep 17 00:00:00 2001 From: Krystian Ujma Date: Mon, 11 Mar 2019 17:12:44 +0100 Subject: Fix not null annotation java-as-html bug (#442) --- core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'core/src/main/kotlin/Java') diff --git a/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt b/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt index 1ef601d3..e26fa13e 100644 --- a/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt +++ b/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt @@ -311,7 +311,7 @@ class JavaPsiDocumentationBuilder : JavaDocumentationBuilder { } fun PsiAnnotation.build(): DocumentationNode { - val node = DocumentationNode(nameReferenceElement?.text ?: "", Content.Empty, NodeKind.Annotation) + val node = DocumentationNode(qualifiedName?.substringAfterLast(".") ?: "", Content.Empty, NodeKind.Annotation) parameterList.attributes.forEach { val parameter = DocumentationNode(it.name ?: "value", Content.Empty, NodeKind.Parameter) val value = it.value -- cgit From 69eefa767ccf692297cbdb9dc44240a4fa67aa3c Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Wed, 13 Mar 2019 16:30:07 +0300 Subject: Fix nullability annotations in javadoc #446 fixed --- .../kotlin/Java/JavaPsiDocumentationBuilder.kt | 27 +++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'core/src/main/kotlin/Java') diff --git a/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt b/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt index e26fa13e..f1f170d7 100644 --- a/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt +++ b/core/src/main/kotlin/Java/JavaPsiDocumentationBuilder.kt @@ -6,6 +6,7 @@ import com.intellij.psi.* import com.intellij.psi.impl.JavaConstantExpressionEvaluator import com.intellij.psi.util.InheritanceUtil import com.intellij.psi.util.PsiTreeUtil +import org.jetbrains.kotlin.asJava.elements.KtLightAbstractAnnotation import org.jetbrains.kotlin.asJava.element