diff options
author | Simon Ogorodnik <Simon.Ogorodnik@jetbrains.com> | 2019-03-18 22:05:22 +0300 |
---|---|---|
committer | Simon Ogorodnik <Simon.Ogorodnik@jetbrains.com> | 2019-03-18 22:05:22 +0300 |
commit | fd2f36301e95f8d100e1c2b942f1590144d8c6c2 (patch) | |
tree | dcbf109f14de5301848c29e9721c8e0af6881b3e /core/src/main/kotlin/Kotlin/KotlinLanguageService.kt | |
parent | f2359e05347708e625d5a6b339010cda2adc30de (diff) | |
parent | 4b22ebab09ce3b934443d063df6b905e5347c390 (diff) | |
download | dokka-fd2f36301e95f8d100e1c2b942f1590144d8c6c2.tar.gz dokka-fd2f36301e95f8d100e1c2b942f1590144d8c6c2.tar.bz2 dokka-fd2f36301e95f8d100e1c2b942f1590144d8c6c2.zip |
Merge branch 'dev'
Diffstat (limited to 'core/src/main/kotlin/Kotlin/KotlinLanguageService.kt')
-rw-r--r-- | core/src/main/kotlin/Kotlin/KotlinLanguageService.kt | 217 |
1 files changed, 106 insertions, 111 deletions
diff --git a/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt b/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt index f33c8c96..5f43c22e 100644 --- a/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt +++ b/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt @@ -5,8 +5,13 @@ 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() { + override fun showModifierInSummary(node: DocumentationNode): Boolean { + return node.name !in fullOnlyModifiers + } + + private val fullOnlyModifiers = + setOf("public", "protected", "private", "internal", "inline", "noinline", "crossinline", "reified") override fun render(node: DocumentationNode, renderMode: RenderMode): ContentNode { return content { @@ -17,11 +22,12 @@ class KotlinLanguageService : LanguageService { NodeKind.EnumItem, NodeKind.ExternalClass -> if (renderMode == RenderMode.FULL) identifier(node.name) + NodeKind.Parameter -> renderParameter(node, renderMode) NodeKind.TypeParameter -> renderTypeParameter(node, renderMode) NodeKind.Type, NodeKind.UpperBound -> renderType(node, renderMode) - NodeKind.Modifier -> renderModifier(node) + NodeKind.Modifier -> renderModifier(this, node, renderMode) NodeKind.Constructor, NodeKind.Function, NodeKind.CompanionObjectFunction -> renderFunction(node, renderMode) @@ -32,12 +38,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 @@ -46,10 +46,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)) - } - else { - renderProperty(functionWithTypeParameter, RenderMode.SUMMARY, SummarizingMapper(receiverKind, typeParameter.name)) + renderFunction( + functionWithTypeParameter, + RenderMode.SUMMARY, + SummarizingMapper(receiverKind, typeParameter.name) + ) + } else { + renderProperty( + functionWithTypeParameter, + RenderMode.SUMMARY, + SummarizingMapper(receiverKind, typeParameter.name) + ) } } } @@ -70,26 +77,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>) { @@ -102,53 +110,21 @@ class KotlinLanguageService : LanguageService { fun renderReceiver(receiver: DocumentationNode, to: ContentBlock) } - private class SummarizingMapper(val kind: ReceiverKind, val typeParameterName: String): SignatureMapper { + private class SummarizingMapper(val kind: ReceiverKind, val typeParameterName: String) : SignatureMapper { override fun renderReceiver(receiver: DocumentationNode, to: ContentBlock) { to.append(ContentIdentifier(kind.receiverName, IdentifierKind.SummarizedTypeName)) to.text("<$typeParameterName>") } } - 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) { @@ -190,15 +166,27 @@ class KotlinLanguageService : LanguageService { keyword("dynamic") return } + + val nullabilityModifier = node.detailOrNull(NodeKind.NullabilityModifier) + if (node.isFunctionalType()) { - renderFunctionalType(node, renderMode) + if (nullabilityModifier != null) { + symbol("(") + renderFunctionalType(node, renderMode) + symbol(")") + symbol(nullabilityModifier.name) + } else { + renderFunctionalType(node, renderMode) + } return } if (renderMode == RenderMode.FULL) { renderAnnotationsForNode(node) } renderModifiersForNode(node, renderMode, true) - renderLinked(node) { identifier(it.name, IdentifierKind.TypeName) } + renderLinked(this, node) { + identifier(it.typeDeclarationClass?.classNodeNameWithOuterClass() ?: it.name, IdentifierKind.TypeName) + } val typeArguments = node.details(NodeKind.Type) if (typeArguments.isNotEmpty()) { symbol("<") @@ -207,22 +195,24 @@ class KotlinLanguageService : LanguageService { } symbol(">") } - val nullabilityModifier = node.details(NodeKind.NullabilityModifier).singleOrNull() - if (nullabilityModifier != null) { + + nullabilityModifier ?.apply { symbol(nullabilityModifier.name) } } - private fun ContentBlock.renderModifier(node: DocumentationNode, nowrap: Boolean = false) { + override fun renderModifier( + block: ContentBlock, + node: DocumentationNode, + renderMode: RenderMode, + nowrap: Boolean + ) { when (node.name) { - "final", "public", "var" -> {} + "final", "public", "var" -> { + } else -> { - keyword(node.name) - if (nowrap) { - nbsp() - } - else { - text(" ") + if (showModifierInSummary(node) || renderMode == RenderMode.FULL) { + super.renderModifier(block, node, renderMode, nowrap) } } } @@ -238,11 +228,12 @@ class KotlinLanguageService : LanguageService { nbsp() symbol(":") nbsp() - renderList(constraints, noWrap=true) { + renderList(constraints, noWrap = true) { renderType(it, renderMode) } } } + private fun ContentBlock.renderParameter(node: DocumentationNode, renderMode: RenderMode) { if (renderMode == RenderMode.FULL) { renderAnnotationsForNode(node) @@ -274,9 +265,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) { @@ -290,7 +284,7 @@ class KotlinLanguageService : LanguageService { } private fun ContentBlock.renderSupertypesForNode(node: DocumentationNode, renderMode: RenderMode) { - val supertypes = node.details(NodeKind.Supertype) + val supertypes = node.details(NodeKind.Supertype).filterNot { it.qualifiedNameFromType() in ignoredSupertypes } if (supertypes.any()) { nbsp() symbol(":") @@ -302,20 +296,6 @@ class KotlinLanguageService : LanguageService { } } - 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") - continue - if (renderMode == RenderMode.SUMMARY && it.name in fullOnlyModifiers) { - continue - } - renderModifier(it, nowrap) - } - } - private fun ContentBlock.renderAnnotationsForNode(node: DocumentationNode) { node.annotations.forEach { renderAnnotation(it) @@ -365,9 +345,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) } @@ -385,7 +367,7 @@ class KotlinLanguageService : LanguageService { renderReceiver(node, renderMode, signatureMapper) - if (node.kind != org.jetbrains.dokka.NodeKind.Constructor) + if (node.kind != NodeKind.Constructor) identifierOrDeprecated(node) symbol("(") @@ -401,14 +383,17 @@ class KotlinLanguageService : LanguageService { symbol(")") symbol(": ") renderType(node.detail(NodeKind.Type), renderMode) - } - else { + } else { symbol(")") } 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) { @@ -428,17 +413,19 @@ class KotlinLanguageService : LanguageService { } } - private fun needReturnType(node: DocumentationNode) = when(node.kind) { + private fun needReturnType(node: DocumentationNode) = when (node.kind) { NodeKind.Constructor -> false else -> !node.isUnitReturnType() } 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 +449,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) { @@ -475,4 +462,12 @@ class KotlinLanguageService : LanguageService { } } -fun DocumentationNode.qualifiedNameFromType() = (links.firstOrNull() ?: hiddenLinks.firstOrNull())?.qualifiedName() ?: name +fun DocumentationNode.qualifiedNameFromType(): String { + return details.firstOrNull { it.kind == NodeKind.QualifiedName }?.name + ?: (links.firstOrNull() ?: hiddenLinks.firstOrNull())?.qualifiedName() + ?: name +} + + +val DocumentationNode.typeDeclarationClass + get() = (links.firstOrNull { it.kind in NodeKind.classLike } ?: externalType) |