aboutsummaryrefslogtreecommitdiff
path: root/plugins/javadoc/src
diff options
context:
space:
mode:
authoririna-turova <31963497+irina-turova@users.noreply.github.com>2023-05-31 16:16:10 +0500
committerGitHub <noreply@github.com>2023-05-31 13:16:10 +0200
commitf45750699d089e0101dcde5d38c7e08ec2f03708 (patch)
tree13a59ca4458374731e92766f70a1f2183a4ba368 /plugins/javadoc/src
parent0cad056d84bf1dbe285ca008be17ca5fbb224818 (diff)
downloaddokka-f45750699d089e0101dcde5d38c7e08ec2f03708.tar.gz
dokka-f45750699d089e0101dcde5d38c7e08ec2f03708.tar.bz2
dokka-f45750699d089e0101dcde5d38c7e08ec2f03708.zip
Add support for `@author`, `@since`, `@return` Javadoc tags (#2967)
Diffstat (limited to 'plugins/javadoc/src')
-rw-r--r--plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/JavadocPageCreator.kt32
-rw-r--r--plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/pages/JavadocPageNodes.kt13
-rw-r--r--plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/renderer/JavadocContentToTemplateMapTranslator.kt4
-rw-r--r--plugins/javadoc/src/main/resources/static_res/stylesheet.css10
-rw-r--r--plugins/javadoc/src/main/resources/views/class.korte38
-rw-r--r--plugins/javadoc/src/test/kotlin/org/jetbrains/dokka/javadoc/JavadocClasslikeTemplateMapTest.kt98
6 files changed, 185 insertions, 10 deletions
diff --git a/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/JavadocPageCreator.kt b/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/JavadocPageCreator.kt
index 80814103..616583c8 100644
--- a/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/JavadocPageCreator.kt
+++ b/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/JavadocPageCreator.kt
@@ -7,10 +7,7 @@ import org.jetbrains.dokka.base.transformers.pages.comments.DocTagToContentConve
import org.jetbrains.dokka.base.translators.documentables.firstSentenceBriefFromContentNodes
import org.jetbrains.dokka.javadoc.pages.*
import org.jetbrains.dokka.model.*
-import org.jetbrains.dokka.model.doc.Description
-import org.jetbrains.dokka.model.doc.Index
-import org.jetbrains.dokka.model.doc.Param
-import org.jetbrains.dokka.model.doc.TagWrapper
+import org.jetbrains.dokka.model.doc.*
import org.jetbrains.dokka.model.properties.PropertyContainer
import org.jetbrains.dokka.model.properties.WithExtraProperties
import org.jetbrains.dokka.pages.*
@@ -68,9 +65,11 @@ open class JavadocPageCreator(context: DokkaContext) {
it.name,
signatureForNode(it, jvm),
it.descriptionToContentNodes(jvm),
- PropertyContainer.withAll(it.indexesInDocumentation())
+ PropertyContainer.withAll(it.indexesInDocumentation()),
)
},
+ sinceTagContent = c.sinceToContentNodes(jvm),
+ authorTagContent = c.authorsToContentNodes(jvm),
documentables = listOf(c),
children = children,
extra = extra + c.indexesInDocumentation()
@@ -165,6 +164,8 @@ open class JavadocPageCreator(context: DokkaContext) {
)
}
},
+ returnTagContent = returnToContentNodes(jvm),
+ sinceTagContent = sinceToContentNodes(jvm),
extra = extra + indexesInDocumentation()
)
}
@@ -177,6 +178,9 @@ open class JavadocPageCreator(context: DokkaContext) {
private inline fun <reified T : TagWrapper> Documentable.findNodeInDocumentation(sourceSetData: DokkaSourceSet?): T? =
documentation[sourceSetData]?.firstChildOfTypeOrNull<T>()
+ private inline fun <reified T : TagWrapper> Documentable.findAllNodesInDocumentation(sourceSetData: DokkaSourceSet?): List<T> =
+ documentation[sourceSetData]?.childrenOfType<T>() ?: emptyList()
+
private fun Documentable.descriptionToContentNodes(sourceSet: DokkaSourceSet? = highestJvmSourceSet) =
contentNodesFromType<Description>(sourceSet)
@@ -192,6 +196,15 @@ open class JavadocPageCreator(context: DokkaContext) {
)
}.orEmpty()
+ private inline fun <reified T : TagWrapper> Documentable.allContentNodesFromType(sourceSet: DokkaSourceSet?) =
+ findAllNodesInDocumentation<T>(sourceSet).map {
+ DocTagToContentConverter().buildContent(
+ it.root,
+ DCI(setOf(dri), JavadocContentKind.OverviewSummary),
+ sourceSets.toSet()
+ )
+ }
+
fun List<ContentNode>.nodeForJvm(jvm: DokkaSourceSet): ContentNode =
firstOrNull { jvm.sourceSetID in it.sourceSets.sourceSetIDs }
?: throw IllegalStateException("No source set found for ${jvm.sourceSetID} ")
@@ -228,5 +241,14 @@ open class JavadocPageCreator(context: DokkaContext) {
}
)
}
+
+ private fun Documentable.authorsToContentNodes(sourceSet: DokkaSourceSet? = highestJvmSourceSet) =
+ allContentNodesFromType<Author>(sourceSet)
+
+ private fun Documentable.sinceToContentNodes(sourceSet: DokkaSourceSet? = highestJvmSourceSet) =
+ allContentNodesFromType<Since>(sourceSet)
+
+ private fun Documentable.returnToContentNodes(sourceSet: DokkaSourceSet? = highestJvmSourceSet) =
+ contentNodesFromType<Return>(sourceSet)
}
diff --git a/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/pages/JavadocPageNodes.kt b/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/pages/JavadocPageNodes.kt
index cafc6c3e..8210b30a 100644
--- a/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/pages/JavadocPageNodes.kt
+++ b/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/pages/JavadocPageNodes.kt
@@ -149,6 +149,7 @@ data class JavadocPropertyNode(
override val name: String,
val signature: JavadocSignatureContentNode,
override val brief: List<ContentNode>,
+
override val extra: PropertyContainer<DProperty> = PropertyContainer.empty()
) : AnchorableJavadocNode(name, dri), WithJavadocExtra<DProperty>, WithBrief
@@ -157,6 +158,10 @@ data class JavadocFunctionNode(
override val brief: List<ContentNode>,
val description: List<ContentNode>,
val parameters: List<JavadocParameterNode>,
+
+ val returnTagContent: List<ContentNode>,
+ val sinceTagContent: List<List<ContentNode>>,
+
override val name: String,
override val dri: DRI,
override val extra: PropertyContainer<DFunction> = PropertyContainer.empty()
@@ -182,6 +187,10 @@ class JavadocClasslikePageNode(
val classlikes: List<JavadocClasslikePageNode>,
val properties: List<JavadocPropertyNode>,
override val brief: List<ContentNode>,
+
+ val sinceTagContent: List<List<ContentNode>>,
+ val authorTagContent: List<List<ContentNode>>,
+
override val documentables: List<Documentable> = emptyList(),
override val children: List<PageNode> = emptyList(),
override val embeddedResources: List<String> = listOf(),
@@ -215,6 +224,8 @@ class JavadocClasslikePageNode(
classlikes,
properties,
brief,
+ sinceTagContent,
+ authorTagContent,
documentables,
children,
embeddedResources,
@@ -240,6 +251,8 @@ class JavadocClasslikePageNode(
classlikes,
properties,
brief,
+ sinceTagContent,
+ authorTagContent,
documentables,
children,
embeddedResources,
diff --git a/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/renderer/JavadocContentToTemplateMapTranslator.kt b/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/renderer/JavadocContentToTemplateMapTranslator.kt
index 45fa3f2e..6a590bc7 100644
--- a/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/renderer/JavadocContentToTemplateMapTranslator.kt
+++ b/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/renderer/JavadocContentToTemplateMapTranslator.kt
@@ -122,6 +122,8 @@ internal class JavadocContentToTemplateMapTranslator(
"description" to htmlForContentNodes(node.description,contextNode),
"parameters" to node.parameters.map { templateMapForParameterNode(it) },
"inlineParameters" to node.parameters.joinToString { renderInlineParameter(it) },
+ "returnTagContent" to htmlForContentNodes(node.returnTagContent, contextNode),
+ "sinceTagContent" to node.sinceTagContent.map { htmlForContentNodes(it, contextNode) },
"anchorLink" to node.getAnchor(),
"signature" to templateMapForSignatureNode(node.signature),
"name" to node.name
@@ -137,6 +139,8 @@ internal class JavadocContentToTemplateMapTranslator(
"properties" to node.properties.map { templateMapForPropertyNode(it) },
"classlikes" to node.classlikes.map { templateMapForNestedClasslikeNode(it) },
"implementedInterfaces" to templateMapForImplementedInterfaces(node).sorted(),
+ "sinceTagContent" to node.sinceTagContent.map { htmlForContentNodes(it, contextNode) },
+ "authorTagContent" to node.authorTagContent.map { htmlForContentNodes(it, contextNode) },
"kind" to node.kind,
"packageName" to node.packageName,
"name" to node.name
diff --git a/plugins/javadoc/src/main/resources/static_res/stylesheet.css b/plugins/javadoc/src/main/resources/static_res/stylesheet.css
index e46e2825..5d5bc20a 100644
--- a/plugins/javadoc/src/main/resources/static_res/stylesheet.css
+++ b/plugins/javadoc/src/main/resources/static_res/stylesheet.css
@@ -352,6 +352,12 @@ ul.blockList li.blockList h2 {
font-size:14px;
font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif;
}
+
+.contentContainer .description dl dt p, .contentContainer .details dl dt p, .serializedFormContainer dl dt p,
+.contentContainer .description dl dd p, .contentContainer .details dl dd p, .serializedFormContainer dl dd p {
+ margin:5px 0 10px 0px;
+}
+
.serializedFormContainer dl.nameValue dt {
margin-left:1px;
font-size:1.1em;
@@ -629,8 +635,8 @@ h1.hidden {
}
.deprecatedLabel, .descfrmTypeLabel, .implementationLabel, .memberNameLabel, .memberNameLink,
.moduleLabelInPackage, .moduleLabelInType, .overrideSpecifyLabel, .packageLabelInType,
-.packageHierarchyLabel, .paramLabel, .returnLabel, .seeLabel, .simpleTagLabel,
-.throwsLabel, .typeNameLabel, .typeNameLink, .searchTagLink {
+.packageHierarchyLabel, .authorLabel, .paramLabel, .returnLabel, .seeLabel, .simpleTagLabel,
+.throwsLabel, .sinceLabel, .typeNameLabel, .typeNameLink, .searchTagLink {
font-weight:bold;
}
.deprecationComment, .emphasizedPhrase, .interfaceName {
diff --git a/plugins/javadoc/src/main/resources/views/class.korte b/plugins/javadoc/src/main/resources/views/class.korte
index 84e302fb..54106dda 100644
--- a/plugins/javadoc/src/main/resources/views/class.korte
+++ b/plugins/javadoc/src/main/resources/views/class.korte
@@ -38,6 +38,24 @@
{% if signature.supertypes != null %}{{signature.supertypes|raw}}{% endif %}
</pre>
<div class="block">{{ classlikeDocumentation|raw }}</div>
+
+ <dl>
+
+ {% if sinceTagContent.size() != 0 %}
+ <dt><span class="sinceLabel">Since:</span></dt>
+ {% for since in sinceTagContent %}
+ <dd>{{ since|raw }}</dd>
+ {% endfor %}
+ {% endif %}
+
+ {% if authorTagContent.size() != 0 %}
+ <dt><span class="authorLabel">Author:</span></dt>
+ {% for author in authorTagContent %}
+ <dd>{{ author|raw }}</dd>
+ {% endfor %}
+ {% endif %}
+
+ </dl>
</li>
</ul>
</div>
@@ -271,17 +289,31 @@
<h4>{{ method.name }}</h4>
<pre class="methodSignature">{{ method.signature.annotations|raw }} {{ method.signature.modifiers|raw }} {{ method.signature.signatureWithoutModifiers|raw}}</pre>
<div class="block">{{ method.description|raw }}</div>
- {% if method.parameters.size != 0 && hasAnyDescription(method.parameters) %}
+
<dl>
+
+ {% if method.parameters.size != 0 && hasAnyDescription(method.parameters) %}
<dt><span class="paramLabel">Parameters:</span></dt>
{% for parameter in method.parameters %}
{% if parameter.description != "" %}
<dd><code>{{ parameter.name }}</code> - {{ parameter.description|raw }}</dd>
{% endif %}
{% endfor %}
- </dl>
{% endif %}
- <!-- TODO missing return annotation -->
+
+ {% if method.returnTagContent != "" %}
+ <dt><span class="returnLabel">Returns:</span></dt>
+ <dd>{{ method.returnTagContent|raw }}</dd>
+ {% endif %}
+
+ {% if method.sinceTagContent.size() != 0 %}
+ <dt><span class="sinceLabel">Since:</span></dt>
+ {% for since in method.sinceTagContent %}
+ <dd>{{ since|raw }}</dd>
+ {% endfor %}
+ {% endif %}
+
+ </dl>
</li>
</ul>
{% endfor %}
diff --git a/plugins/javadoc/src/test/kotlin/org/jetbrains/dokka/javadoc/JavadocClasslikeTemplateMapTest.kt b/plugins/javadoc/src/test/kotlin/org/jetbrains/dokka/javadoc/JavadocClasslikeTemplateMapTest.kt
index 65fbd30f..53167f71 100644
--- a/plugins/javadoc/src/test/kotlin/org/jetbrains/dokka/javadoc/JavadocClasslikeTemplateMapTest.kt
+++ b/plugins/javadoc/src/test/kotlin/org/jetbrains/dokka/javadoc/JavadocClasslikeTemplateMapTest.kt
@@ -342,6 +342,104 @@ internal class JavadocClasslikeTemplateMapTest : AbstractJavadocTemplateMapTest(
}
}
+ @Test
+ fun `@author @since @return method tags`(){
+ dualTestTemplateMapInline(
+ kotlin =
+ """
+ /src/source0.kt
+ package com.test.package0
+ class TestClass {
+ /**
+ * Testing @author @since @return method tags
+ * @since 1.2
+ * @since 08 april 2023
+ * @return parameter's value in lower case
+ */
+ fun testFunction(testParam: String?): String {
+ return testParam?.lowercase() ?: ""
+ }
+ }
+ """,
+ java =
+ """
+ /src/com/test/package0/TestClass.java
+ package com.test.package0;
+ public final class TestClass {
+ /**
+ * Testing @author @since @return method tags
+ * @since 1.2
+ * @since 08 april 2023
+ * @return parameter's value in lower case
+ */
+ public final String testFunction(String testParam) {
+ return testParam.toLowerCase();
+ }
+ }
+ """
+ ) {
+ val map = singlePageOfType<JavadocClasslikePageNode>().templateMap
+ assertEquals("TestClass", map["name"])
+
+ val methods = assertIsInstance<Map<String, Any?>>(map["methods"])
+ val testFunction = assertIsInstance<List<Map<String, Any?>>>(methods["own"]).single()
+ assertEquals("Testing @author @since @return method tags", testFunction["brief"])
+
+ assertEquals("testFunction", testFunction["name"])
+ assertEquals(listOf("<p>1.2</p>", "<p>08 april 2023</p>"), testFunction["sinceTagContent"])
+ assertEquals("<p>parameter's value in lower case</p>", testFunction["returnTagContent"])
+ }
+ }
+
+ @Test
+ fun `@author @since class tags`(){
+ dualTestTemplateMapInline(
+ kotlin =
+ """
+ /src/source0.kt
+ package com.test.package0
+ /**
+ * Testing @author @since class tags
+ * @author Test Author
+ * @author Test Author2
+ * @author Test Author3
+ * @since 1.2
+ * @since 08 april 2023
+ */
+ class TestClass {
+ fun testFunction(testParam: String?): String {
+ return testParam?.lowercase() ?: ""
+ }
+ }
+ """,
+ java =
+ """
+ /src/com/test/package0/TestClass.java
+ package com.test.package0;
+ /**
+ * Testing @author @since class tags
+ * @author Test Author
+ * @author Test Author2
+ * @author Test Author3
+ * @since 1.2
+ * @since 08 april 2023
+ */
+ public final class TestClass {
+ public final String testFunction(String testParam) {
+ return testParam.toLowerCase();
+ }
+ }
+ """
+ ) {
+ val map = singlePageOfType<JavadocClasslikePageNode>().templateMap
+
+ assertEquals("TestClass", map["name"])
+ assertEquals("<p>Testing @author @since class tags</p>", map["classlikeDocumentation"])
+ assertEquals(listOf("<p>Test Author</p>", "<p>Test Author2</p>", "<p>Test Author3</p>"), map["authorTagContent"])
+ assertEquals(listOf("<p>1.2</p>", "<p>08 april 2023</p>"), map["sinceTagContent"])
+ }
+ }
+
private fun assertParameterNode(node: Map<String, Any?>, expectedName: String, expectedType: String, expectedDescription: String){
assertEquals(expectedName, node["name"])
assertEquals(expectedType, node["type"])