Skip to content

Commit

Permalink
Fix multiline links in javadoc
Browse files Browse the repository at this point in the history
  • Loading branch information
BarkingBad committed Oct 1, 2020
1 parent dafa895 commit ac9fe0e
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 12 deletions.
28 changes: 16 additions & 12 deletions plugins/base/src/main/kotlin/translators/psi/JavadocParser.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import com.intellij.psi.impl.source.javadoc.PsiDocParamRef
import com.intellij.psi.impl.source.tree.JavaDocElementType
import com.intellij.psi.impl.source.tree.LeafPsiElement
import com.intellij.psi.javadoc.*
import com.intellij.psi.tree.IElementType
import com.intellij.psi.tree.java.IJavaDocElementType
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.dokka.analysis.from
import org.jetbrains.dokka.links.DRI
Expand Down Expand Up @@ -40,7 +42,7 @@ class JavadocParser(
)
"throws" -> Throws(wrapTagIfNecessary(convertJavadocElements(tag.contentElements())), tag.text)
"return" -> Return(wrapTagIfNecessary(convertJavadocElements(tag.contentElements())))
"author" -> Author(wrapTagIfNecessary(convertJavadocElements(tag.contentElements())))
"author" -> Author(wrapTagIfNecessary(convertJavadocElements(tag.authorContentElements()))) // Workaround: PSI returns first word after @author tag as a `DOC_TAG_VALUE_ELEMENT`, then the rest as a `DOC_COMMENT_DATA`, so for `Name Surname` we get them parted
"see" -> getSeeTagElementContent(tag).let {
See(
wrapTagIfNecessary(it.first),
Expand Down Expand Up @@ -157,20 +159,19 @@ class JavadocParser(
}

private fun PsiElement.toDocumentationLinkString(
labelElement: PsiElement? = null
): String? =
reference?.resolve()?.let {
if (it !is PsiParameter) {
val dri = DRI.from(it)
driMap[dri.toString()] = dri
val label = labelElement ?: defaultLabel()
"""<a data-dri=$dri>${label.text}</a>"""
} else null
labelElement: List<PsiElement>? = null
): String =
(reference?.resolve()?.takeIf { it !is PsiParameter }?.let {
val dri = DRI.from(it)
driMap[dri.toString()] = dri
Pair(labelElement ?: listOf(defaultLabel()), dri.toString())
} ?: Pair(listOf(defaultLabel()), "UNRESOLVED_PSI_ELEMENT")).let { (label, dri) ->
"""<a data-dri=$dri>${label.joinToString(" ") { it.text }}</a>"""
}

private fun convertInlineDocTag(tag: PsiInlineDocTag) = when (tag.name) {
"link", "linkplain" -> {
tag.referenceElement()?.toDocumentationLinkString(tag.dataElements.firstIsInstanceOrNull<PsiDocToken>())
tag.referenceElement()?.toDocumentationLinkString(tag.dataElements.filterIsInstance<PsiDocToken>())
}
"code", "literal" -> {
"<code data-inline>${tag.text}</code>"
Expand All @@ -187,7 +188,7 @@ class JavadocParser(
A(children, params = mapOf("href" to element.attr("href")))
element.hasAttr("data-dri") && driMap.containsKey(element.attr("data-dri")) ->
DocumentationLink(driMap[element.attr("data-dri")]!!, children)
else -> Text(children = children)
else -> Text(body = children.filterIsInstance<Text>().joinToString { it.body })
}
}

Expand Down Expand Up @@ -226,6 +227,9 @@ class JavadocParser(
}

private fun PsiDocTag.contentElements(): List<PsiElement> =
dataElements.mapNotNull { it.takeIf { it is PsiDocToken && it.text.isNotBlank() } }

private fun PsiDocTag.authorContentElements(): List<PsiElement> =
dataElements.mapNotNull { it.takeIf { it.text.isNotBlank() } }

private fun convertJavadocElements(elements: Iterable<PsiElement>, asParagraph: Boolean = true): List<DocTag> = Parse()(elements, asParagraph)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package org.jetbrains.dokka.javadoc.location

import org.jetbrains.dokka.ExternalDocumentationLink
import org.jetbrains.dokka.model.doc.DocumentationLink
import org.jetbrains.dokka.model.doc.Text
import org.jetbrains.dokka.testApi.testRunner.AbstractCoreTest
import org.jetbrains.dokka.utilities.cast
import org.junit.jupiter.api.Test
import kotlin.test.assertEquals

class JavadocLinkingTest : AbstractCoreTest() {

@Test
fun `linebroken link`() {
fun externalLink(link: String) = ExternalDocumentationLink(link)

val config = dokkaConfiguration {
sourceSets {
sourceSet {
sourceRoots = listOf("jvmSrc/")
externalDocumentationLinks = listOf(
externalLink("https://docs.oracle.com/javase/8/docs/api/"),
externalLink("https://kotlinlang.org/api/latest/jvm/stdlib/")
)
analysisPlatform = "jvm"
}
}
}
testInline(
"""
|/jvmSrc/javadoc/test/SomeClass.kt
|
|package example
|
|class SomeClass {
| fun someFun(x: Int): Int = 1
|}
|/jvmSrc/javadoc/test/SomeJavaDocExample.java
|
|package example;
|
|/**
| * Here comes some comment
| *
| * {@link example.SomeClass#someFun(int) someName(ads,
| * dsa)}
| *
| * longer comment
| */
|public class SomeJavaDocExample {
| public void someFunc(int integer, Object object) {
| }
|}
""".trimIndent(),
config,
cleanupOutput = false
) {
documentablesMergingStage = {
it.packages.single().classlikes.single { it.name == "SomeJavaDocExample" }.documentation.values.single().children.single().children.single {
it is DocumentationLink
}.children.single().cast<Text>().body.run {
assertEquals("someName(ads, dsa)", this)
}
}
}
}

}

0 comments on commit ac9fe0e

Please sign in to comment.