aboutsummaryrefslogtreecommitdiff
path: root/core/src
diff options
context:
space:
mode:
authorSimon Ogorodnik <Simon.Ogorodnik@jetbrains.com>2018-04-13 19:47:07 +0300
committerSimon Ogorodnik <Simon.Ogorodnik@jetbrains.com>2018-07-13 18:32:24 +0300
commit8883839b8796589a1fa02b3dca5d1aae172b5c56 (patch)
tree6884c200a7cdc7f1b43fa35e8b158bad32a31ea5 /core/src
parent3e8448bf5d3f00cfaa7d4d6b4fbbf678aebc37b7 (diff)
downloaddokka-8883839b8796589a1fa02b3dca5d1aae172b5c56.tar.gz
dokka-8883839b8796589a1fa02b3dca5d1aae172b5c56.tar.bz2
dokka-8883839b8796589a1fa02b3dca5d1aae172b5c56.zip
[backport] Fix problems in as-java java-layout-html mode
Extract common part of LanguageServices & other improvements Original: 853262e
Diffstat (limited to 'core/src')
-rw-r--r--core/src/main/kotlin/Java/JavadocParser.kt43
-rw-r--r--core/src/main/kotlin/Kotlin/DeclarationLinkResolver.kt2
-rw-r--r--core/src/main/kotlin/Kotlin/KotlinLanguageService.kt164
-rw-r--r--core/src/main/kotlin/Languages/CommonLanguageService.kt65
-rw-r--r--core/src/main/kotlin/Languages/NewJavaLanguageService.kt190
-rw-r--r--core/src/main/kotlin/Model/DocumentationNode.kt2
-rw-r--r--core/src/main/kotlin/Model/DocumentationReference.kt2
7 files changed, 353 insertions, 115 deletions
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<PsiElement> {
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 = "<a docref=\"$linkSignature\">${labelText.htmlEscape()}</a>"
if (tag.name == "link") "<code>$link</code>" 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()
diff --git a/core/src/main/kotlin/Kotlin/DeclarationLinkResolver.kt b/core/src/main/kotlin/Kotlin/DeclarationLinkResolver.kt
index ffef399d..ec474900 100644
--- a/core/src/main/kotlin/Kotlin/DeclarationLinkResolver.kt
+++ b/core/src/main/kotlin/Kotlin/DeclarationLinkResolver.kt
@@ -41,7 +41,7 @@ class DeclarationLinkResolver
val target = refGraph.lookup(signature)
if (target == null) {
- logger.warn("Can't find node by signature $signature, referenced at $referencedAt")
+ logger.warn("Can't find node by signature `$signature`, referenced at $referencedAt")
}
target
})
diff --git a/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt b/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt
index aa185de7..69a97848 100644
--- a/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt
+++ b/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt
@@ -5,8 +5,9 @@ import org.jetbrains.dokka.LanguageService.RenderMode
/**
* Implements [LanguageService] and provides rendering of symbols in Kotlin language
*/
-class KotlinLanguageService : LanguageService {
- private val fullOnlyModifiers = setOf("public", "protected", "private", "inline", "noinline", "crossinline", "reified")
+class KotlinLanguageService : CommonLanguageService() {
+ private val fullOnlyModifiers =
+ setOf("public", "protected", "private", "inline", "noinline", "crossinline", "reified")
override fun render(node: DocumentationNode, renderMode: RenderMode): ContentNode {
return content {
@@ -22,7 +23,7 @@ class KotlinLanguageService : LanguageService {
NodeKind.Type,
NodeKind.UpperBound -> renderType(node, renderMode)
- NodeKind.Modifier -> renderModifier(node)
+ NodeKind.Modifier -> renderModifier(this, node)
NodeKind.Constructor,
NodeKind.Function,
NodeKind.CompanionObjectFunction -> renderFunction(node, renderMode)
@@ -33,12 +34,6 @@ class KotlinLanguageService : LanguageService {
}
}
- override fun renderName(node: DocumentationNode): String {
- return when (node.kind) {
- NodeKind.Constructor -> node.owner!!.name
- else -> node.name
- }
- }
override fun summarizeSignatures(nodes: List<DocumentationNode>): ContentNode? {
if (nodes.size < 2) return null
@@ -47,9 +42,17 @@ class KotlinLanguageService : LanguageService {
return content {
val typeParameter = functionWithTypeParameter.details(NodeKind.TypeParameter).first()
if (functionWithTypeParameter.kind == NodeKind.Function) {
- renderFunction(functionWithTypeParameter, RenderMode.SUMMARY, SummarizingMapper(receiverKind, typeParameter.name))
+ renderFunction(
+ functionWithTypeParameter,
+ RenderMode.SUMMARY,
+ SummarizingMapper(receiverKind, typeParameter.name)
+ )
} else {
- renderProperty(functionWithTypeParameter, RenderMode.SUMMARY, SummarizingMapper(receiverKind, typeParameter.name))
+ renderProperty(
+ functionWithTypeParameter,
+ RenderMode.SUMMARY,
+ SummarizingMapper(receiverKind, typeParameter.name)
+ )
}
}
}
@@ -70,26 +73,27 @@ class KotlinLanguageService : LanguageService {
companion object {
private val arrayClasses = setOf(
- "kotlin.Array",
- "kotlin.BooleanArray",
- "kotlin.ByteArray",
- "kotlin.CharArray",
- "kotlin.ShortArray",
- "kotlin.IntArray",
- "kotlin.LongArray",
- "kotlin.FloatArray",
- "kotlin.DoubleArray"
+ "kotlin.Array",
+ "kotlin.BooleanArray",
+ "kotlin.ByteArray",
+ "kotlin.CharArray",
+ "kotlin.ShortArray",
+ "kotlin.IntArray",
+ "kotlin.LongArray",
+ "kotlin.FloatArray",
+ "kotlin.DoubleArray"
)
private val arrayOrListClasses = setOf("kotlin.List") + arrayClasses
private val iterableClasses = setOf(
- "kotlin.Collection",
- "kotlin.Sequence",
- "kotlin.Iterable",
- "kotlin.Map",
- "kotlin.String",
- "kotlin.CharSequence") + arrayOrListClasses
+ "kotlin.Collection",
+ "kotlin.Sequence",
+ "kotlin.Iterable",
+ "kotlin.Map",
+ "kotlin.String",
+ "kotlin.CharSequence"
+ ) + arrayOrListClasses
}
private enum class ReceiverKind(val receiverName: String, val classes: Collection<String>) {
@@ -109,46 +113,14 @@ class KotlinLanguageService : LanguageService {
}
}
- private fun ContentBlock.renderPackage(node: DocumentationNode) {
- keyword("package")
- text(" ")
- identifier(node.name)
- }
-
- private fun <T> ContentBlock.renderList(nodes: List<T>, separator: String = ", ",
- noWrap: Boolean = false, renderItem: (T) -> Unit) {
- if (nodes.none())
- return
- renderItem(nodes.first())
- nodes.drop(1).forEach {
- if (noWrap) {
- symbol(separator.removeSuffix(" "))
- nbsp()
- } else {
- symbol(separator)
- }
- renderItem(it)
- }
- }
-
- private fun ContentBlock.renderLinked(node: DocumentationNode, body: ContentBlock.(DocumentationNode) -> Unit) {
- val to = node.links.firstOrNull()
- if (to == null)
- body(node)
- else
- link(to) {
- body(node)
- }
- }
-
private fun ContentBlock.renderFunctionalTypeParameterName(node: DocumentationNode, renderMode: RenderMode) {
node.references(RefKind.HiddenAnnotation).map { it.to }
- .find { it.name == "ParameterName" }?.let {
- val parameterNameValue = it.detail(NodeKind.Parameter).detail(NodeKind.Value)
- identifier(parameterNameValue.name.removeSurrounding("\""), IdentifierKind.ParameterName)
- symbol(":")
- nbsp()
- }
+ .find { it.name == "ParameterName" }?.let {
+ val parameterNameValue = it.detail(NodeKind.Parameter).detail(NodeKind.Value)
+ identifier(parameterNameValue.name.removeSurrounding("\""), IdentifierKind.ParameterName)
+ symbol(":")
+ nbsp()
+ }
}
private fun ContentBlock.renderFunctionalType(node: DocumentationNode, renderMode: RenderMode) {
@@ -198,7 +170,7 @@ class KotlinLanguageService : LanguageService {
renderAnnotationsForNode(node)
}
renderModifiersForNode(node, renderMode, true)
- renderLinked(node) { identifier(it.name, IdentifierKind.TypeName) }
+ renderLinked(this, node) { identifier(it.name, IdentifierKind.TypeName) }
val typeArguments = node.details(NodeKind.Type)
if (typeArguments.isNotEmpty()) {
symbol("<")
@@ -213,17 +185,16 @@ class KotlinLanguageService : LanguageService {
}
}
- private fun ContentBlock.renderModifier(node: DocumentationNode, nowrap: Boolean = false) {
+ override fun renderModifier(
+ block: ContentBlock,
+ node: DocumentationNode,
+ nowrap: Boolean
+ ) {
when (node.name) {
"final", "public", "var" -> {
}
else -> {
- keyword(node.name)
- if (nowrap) {
- nbsp()
- } else {
- text(" ")
- }
+ super.renderModifier(block, node, nowrap)
}
}
}
@@ -275,9 +246,12 @@ class KotlinLanguageService : LanguageService {
}
private fun ContentBlock.renderExtraTypeParameterConstraints(node: DocumentationNode, renderMode: RenderMode) {
- val parametersWithMultipleConstraints = node.details(NodeKind.TypeParameter).filter { it.details(NodeKind.UpperBound).size > 1 }
+ val parametersWithMultipleConstraints =
+ node.details(NodeKind.TypeParameter).filter { it.details(NodeKind.UpperBound).size > 1 }
val parametersWithConstraints = parametersWithMultipleConstraints
- .flatMap { parameter -> parameter.details(NodeKind.UpperBound).map { constraint -> parameter to constraint } }
+ .flatMap { parameter ->
+ parameter.details(NodeKind.UpperBound).map { constraint -> parameter to constraint }
+ }
if (parametersWithMultipleConstraints.isNotEmpty()) {
keyword(" where ")
renderList(parametersWithConstraints) {
@@ -303,9 +277,11 @@ class KotlinLanguageService : LanguageService {
}
}
- private fun ContentBlock.renderModifiersForNode(node: DocumentationNode,
- renderMode: RenderMode,
- nowrap: Boolean = false) {
+ private fun ContentBlock.renderModifiersForNode(
+ node: DocumentationNode,
+ renderMode: RenderMode,
+ nowrap: Boolean = false
+ ) {
val modifiers = node.details(NodeKind.Modifier)
for (it in modifiers) {
if (node.kind == org.jetbrains.dokka.NodeKind.Interface && it.name == "abstract")
@@ -313,7 +289,7 @@ class KotlinLanguageService : LanguageService {
if (renderMode == RenderMode.SUMMARY && it.name in fullOnlyModifiers) {
continue
}
- renderModifier(it, nowrap)
+ renderModifier(this, it, nowrap)
}
}
@@ -366,9 +342,11 @@ class KotlinLanguageService : LanguageService {
}
}
- private fun ContentBlock.renderFunction(node: DocumentationNode,
- renderMode: RenderMode,
- signatureMapper: SignatureMapper? = null) {
+ private fun ContentBlock.renderFunction(
+ node: DocumentationNode,
+ renderMode: RenderMode,
+ signatureMapper: SignatureMapper? = null
+ ) {
if (renderMode == RenderMode.FULL) {
renderAnnotationsForNode(node)
}
@@ -408,7 +386,11 @@ class KotlinLanguageService : LanguageService {
renderExtraTypeParameterConstraints(node, renderMode)
}
- private fun ContentBlock.renderReceiver(node: DocumentationNode, renderMode: RenderMode, signatureMapper: SignatureMapper?) {
+ private fun ContentBlock.renderReceiver(
+ node: DocumentationNode,
+ renderMode: RenderMode,
+ signatureMapper: SignatureMapper?
+ ) {
val receiver = node.details(NodeKind.Receiver).singleOrNull()
if (receiver != null) {
if (signatureMapper != null) {
@@ -434,11 +416,13 @@ class KotlinLanguageService : LanguageService {
}
fun DocumentationNode.isUnitReturnType(): Boolean =
- detail(NodeKind.Type).hiddenLinks.firstOrNull()?.qualifiedName() == "kotlin.Unit"
+ detail(NodeKind.Type).hiddenLinks.firstOrNull()?.qualifiedName() == "kotlin.Unit"
- private fun ContentBlock.renderProperty(node: DocumentationNode,
- renderMode: RenderMode,
- signatureMapper: SignatureMapper? = null) {
+ private fun ContentBlock.renderProperty(
+ node: DocumentationNode,
+ renderMode: RenderMode,
+ signatureMapper: SignatureMapper? = null
+ ) {
if (renderMode == RenderMode.FULL) {
renderAnnotationsForNode(node)
}
@@ -462,7 +446,7 @@ class KotlinLanguageService : LanguageService {
}
fun DocumentationNode.getPropertyKeyword() =
- if (details(NodeKind.Modifier).any { it.name == "var" }) "var" else "val"
+ if (details(NodeKind.Modifier).any { it.name == "var" }) "var" else "val"
fun ContentBlock.identifierOrDeprecated(node: DocumentationNode) {
if (node.deprecation != null) {
@@ -476,6 +460,6 @@ class KotlinLanguageService : LanguageService {
}
fun DocumentationNode.qualifiedNameFromType() =
- details.firstOrNull { it.kind == NodeKind.QualifiedName }?.name
- ?: (links.firstOrNull() ?: hiddenLinks.firstOrNull())?.qualifiedName()
- ?: name
+ details.firstOrNull { it.kind == NodeKind.QualifiedName }?.name
+ ?: (links.firstOrNull() ?: hiddenLinks.firstOrNull())?.qualifiedName()
+ ?: name
diff --git a/core/src/main/kotlin/Languages/CommonLanguageService.kt b/core/src/main/kotlin/Languages/CommonLanguageService.kt
new file mode 100644
index 00000000..f155192d
--- /dev/null
+++ b/core/src/main/kotlin/Languages/CommonLanguageService.kt
@@ -0,0 +1,65 @@
+package org.jetbrains.dokka
+
+
+abstract class CommonLanguageService : LanguageService {
+
+ protected fun ContentBlock.renderPackage(node: DocumentationNode) {
+ keyword("package")
+ nbsp()
+ identifier(node.name)
+ }
+
+ override fun renderName(node: DocumentationNode): String {
+ return when (node.kind) {
+ NodeKind.Constructor -> node.owner!!.name
+ else -> node.name
+ }
+ }
+
+ open fun renderModifier(
+ block: ContentBlock,
+ node: DocumentationNode,
+ nowrap: Boolean = false
+ ) = with(block) {
+ keyword(node.name)
+ if (nowrap) {
+ nbsp()
+ } else {
+ text(" ")
+ }
+ }
+
+ protected fun renderLinked(
+ block: ContentBlock,
+ node: DocumentationNode,
+ body: ContentBlock.(DocumentationNode) -> Unit
+ ) = with(block) {
+ val to = node.links.firstOrNull()
+ if (to == null)
+ body(node)
+ else
+ link(to) {
+ this.body(node)
+ }
+ }
+
+ protected fun <T> ContentBlock.renderList(
+ nodes: List<T>, separator: String = ", ",
+ noWrap: Boolean = false, renderItem: (T) -> Unit
+ ) {
+ if (nodes.none())
+ return
+ renderItem(nodes.first())
+ nodes.drop(1).forEach {
+ if (noWrap) {
+ symbol(separator.removeSuffix(" "))
+ nbsp()
+ } else {
+ symbol(separator)
+ }
+ renderItem(it)
+ }
+ }
+
+
+} \ No newline at end of file
diff --git a/core/src/main/kotlin/Languages/NewJavaLanguageService.kt b/core/src/main/kotlin/Languages/NewJavaLanguageService.kt
new file mode 100644
index 00000000..22ad62b2
--- /dev/null
+++ b/core/src/main/kotlin/Languages/NewJavaLanguageService.kt
@@ -0,0 +1,190 @@
+package org.jetbrains.dokka
+
+/**
+ * Implements [LanguageService] and provides rendering of symbols in Java language
+ */
+class NewJavaLanguageService : CommonLanguageService() {
+ override fun render(node: DocumentationNode, renderMode: LanguageService.RenderMode): ContentNode {
+ return content {
+ (when (node.kind) {
+ NodeKind.Package -> renderPackage(node)
+ in NodeKind.classLike -> renderClass(node)
+
+ NodeKind.Modifier -> renderModifier(this, node)
+ NodeKind.TypeParameter -> renderTypeParameter(node)
+ NodeKind.Type,
+ NodeKind.UpperBound -> renderType(node)
+
+ NodeKind.Constructor,
+ NodeKind.Function -> renderFunction(node)
+ NodeKind.Property -> renderProperty(node)
+ else -> "${node.kind}: ${node.name}"
+ })
+ }
+ }
+
+ override fun summarizeSignatures(nodes: List<DocumentationNode>): ContentNode? = null
+
+
+ override fun renderModifier(block: ContentBlock, node: DocumentationNode, nowrap: Boolean) {
+ when (node.name) {
+ "open", "internal" -> {
+ }
+ else -> super.renderModifier(block, node, nowrap)
+ }
+ }
+
+ fun getArrayElementType(node: DocumentationNode): DocumentationNode? = when (node.qualifiedName()) {
+ "kotlin.Array" ->
+ node.details(NodeKind.Type).singleOrNull()?.let { et -> getArrayElementType(et) ?: et }
+ ?: DocumentationNode("Object", node.content, NodeKind.ExternalClass)
+
+ "kotlin.IntArray", "kotlin.LongArray", "kotlin.ShortArray", "kotlin.ByteArray",
+ "kotlin.CharArray", "kotlin.DoubleArray", "kotlin.FloatArray", "kotlin.BooleanArray" ->
+ DocumentationNode(node.name.removeSuffix("Array").toLowerCase(), node.content, NodeKind.Type)
+
+ else -> null
+ }
+
+ fun getArrayDimension(node: DocumentationNode): Int = when (node.qualifiedName()) {
+ "kotlin.Array" ->
+ 1 + (node.details(NodeKind.Type).singleOrNull()?.let { getArrayDimension(it) } ?: 0)
+
+ "kotlin.IntArray", "kotlin.LongArray", "kotlin.ShortArray", "kotlin.ByteArray",
+ "kotlin.CharArray", "kotlin.DoubleArray", "kotlin.FloatArray", "kotlin.BooleanArray" ->
+ 1
+ else -> 0
+ }
+
+ fun ContentBlock.renderType(node: DocumentationNode) {
+ when (node.name) {
+ "Unit" -> identifier("void")
+ "Int" -> identifier("int")
+ "Long" -> identifier("long")
+ "Double" -> identifier("double")
+ "Float" -> identifier("float")
+ "Char" -> identifier("char")
+ "Boolean" -> identifier("bool")
+ // TODO: render arrays
+ else -> renderLinked(this, node) {
+ identifier(node.name)
+ }
+ }
+ }
+
+ private fun ContentBlock.renderTypeParameter(node: DocumentationNode) {
+ val constraints = node.details(NodeKind.UpperBound)
+ if (constraints.none())
+ identifier(node.name)
+ else {
+ identifier(node.name)
+ text(" ")
+ keyword("extends")
+ text(" ")
+ constraints.forEach { renderType(node) }
+ }
+ }
+
+ private fun ContentBlock.renderParameter(node: DocumentationNode) {
+ renderType(node.detail(NodeKind.Type))
+ text(" ")
+ identifier(node.name)
+ }
+
+ private fun ContentBlock.renderTypeParametersForNode(node: DocumentationNode) {
+ val typeParameters = node.details(NodeKind.TypeParameter)
+ if (typeParameters.any()) {
+ symbol("<")
+ renderList(typeParameters, noWrap = true) {
+ renderTypeParameter(it)
+ }
+ symbol(">")
+ text(" ")
+ }
+ }
+
+// private fun renderModifiersForNode(node: DocumentationNode): String {
+// val modifiers = node.details(NodeKind.Modifier).map { renderModifier(it) }.filter { it != "" }
+// if (modifiers.none())
+// return ""
+// return modifiers.joinToString(" ", postfix = " ")
+// }
+
+ private fun ContentBlock.renderClassKind(node: DocumentationNode) {
+ when (node.kind) {
+ NodeKind.Interface -> {
+ keyword("interface")
+ }
+ NodeKind.EnumItem -> {
+ keyword("enum value")
+ }
+ NodeKind.Enum -> {
+ keyword("enum")
+ }
+ NodeKind.Class, NodeKind.Exception, NodeKind.Object -> {
+ keyword("class")
+ }
+ else -> throw IllegalArgumentException("Node $node is not a class-like object")
+ }
+ text(" ")
+ }
+
+ private fun ContentBlock.renderClass(node: DocumentationNode) {
+ renderClassKind(node)
+
+ identifier(node.name)
+ renderTypeParametersForNode(node)
+ }
+
+ private fun ContentBlock.renderParameters(nodes: List<DocumentationNode>) {
+ renderList(nodes) {
+ renderParameter(it)
+ }
+ }
+
+ private fun ContentBlock.renderFunction(node: DocumentationNode) {
+ when (node.kind) {
+ NodeKind.Constructor -> identifier(node.owner?.name ?: "")
+ NodeKind.Function -> {
+ renderTypeParametersForNode(node)
+ renderType(node.detail(NodeKind.Type))
+ text(" ")
+ identifier(node.name)
+
+ }
+ else -> throw IllegalArgumentException("Node $node is not a function-like object")
+ }
+
+ val receiver = node.details(NodeKind.Receiver).singleOrNull()
+ symbol("(")
+ if (receiver != null)
+ renderParameters(listOf(receiver) + node.details(NodeKind.Parameter))
+ else
+ renderParameters(node.details(NodeKind.Parameter))
+
+ symbol(")")
+ }
+
+ private fun ContentBlock.renderProperty(node: DocumentationNode) {
+
+ when (node.kind) {
+ NodeKind.Property -> {
+ keyword("val")
+ text(" ")
+ }
+ else -> throw IllegalArgumentException("Node $node is not a property")
+ }
+ renderTypeParametersForNode(node)
+ val receiver = node.details(NodeKind.Receiver).singleOrNull()
+ if (receiver != null) {
+ renderType(receiver.detail(NodeKind.Type))
+ symbol(".")
+ }
+
+ identifier(node.name)
+ symbol(":")
+ text(" ")
+ renderType(node.detail(NodeKind.Type))
+
+ }
+} \ No newline at end of file
diff --git a/core/src/main/kotlin/Model/DocumentationNode.kt b/core/src/main/kotlin/Model/DocumentationNode.kt
index 85ecdf87..84501d2b 100644
--- a/core/src/main/kotlin/Model/DocumentationNode.kt
+++ b/core/src/main/kotlin/Model/DocumentationNode.kt
@@ -63,7 +63,7 @@ enum class NodeKind {
companion object {
val classLike = setOf(Class, Interface, Enum, AnnotationClass, Exception, Object, TypeAlias)
- val memberLike = setOf(Function, Property, Constructor, CompanionObjectFunction, CompanionObjectProperty, EnumItem)
+ val memberLike = setOf(Function, Property, Field, Constructor, CompanionObjectFunction, CompanionObjectProperty, EnumItem)
}
}
diff --git a/core/src/main/kotlin/Model/DocumentationReference.kt b/core/src/main/kotlin/Model/DocumentationReference.kt
index b0f011be..89ec1b3e 100644
--- a/core/src/main/kotlin/Model/DocumentationReference.kt
+++ b/core/src/main/kotlin/Model/DocumentationReference.kt
@@ -62,7 +62,7 @@ class NodeReferenceGraph() {
fun lookupOrWarn(signature: String, logger: DokkaLogger): DocumentationNode? {
val result = nodeMap[signature]
if (result == null) {
- logger.warn("Can't find node by signature $signature")
+ logger.warn("Can't find node by signature `$signature`")
}
return result
}