diff options
author | Dmitry Jemerov <yole@jetbrains.com> | 2015-10-27 17:12:31 +0100 |
---|---|---|
committer | Dmitry Jemerov <yole@jetbrains.com> | 2015-10-29 11:57:20 +0100 |
commit | 3faa3f2d1c7ca33ad8d98bc6c562e4fe6977225f (patch) | |
tree | ab52ce7c62c485f892e12c05e0c619c44f410cf6 /src/Kotlin | |
parent | 44498ab2912d1156ad9d6549353251c9220af888 (diff) | |
download | dokka-3faa3f2d1c7ca33ad8d98bc6c562e4fe6977225f.tar.gz dokka-3faa3f2d1c7ca33ad8d98bc6c562e4fe6977225f.tar.bz2 dokka-3faa3f2d1c7ca33ad8d98bc6c562e4fe6977225f.zip |
summarize signatures for overloaded stdlib functions
Diffstat (limited to 'src/Kotlin')
-rw-r--r-- | src/Kotlin/DocumentationBuilder.kt | 9 | ||||
-rw-r--r-- | src/Kotlin/KotlinLanguageService.kt | 80 |
2 files changed, 83 insertions, 6 deletions
diff --git a/src/Kotlin/DocumentationBuilder.kt b/src/Kotlin/DocumentationBuilder.kt index a9ac8551..b30d59d7 100644 --- a/src/Kotlin/DocumentationBuilder.kt +++ b/src/Kotlin/DocumentationBuilder.kt @@ -229,8 +229,8 @@ class DocumentationBuilder(val resolutionFacade: ResolutionFacade, } } - fun link(node: DocumentationNode, descriptor: DeclarationDescriptor) { - refGraph.link(node, descriptor.signature(), DocumentationReference.Kind.Link) + fun link(node: DocumentationNode, descriptor: DeclarationDescriptor, kind: DocumentationReference.Kind) { + refGraph.link(node, descriptor.signature(), kind) } fun link(fromDescriptor: DeclarationDescriptor?, toDescriptor: DeclarationDescriptor?, kind: DocumentationReference.Kind) { @@ -328,8 +328,9 @@ class DocumentationBuilder(val resolutionFacade: ResolutionFacade, if (jetType.isMarkedNullable) { node.appendTextNode("?", Kind.NullabilityModifier) } - if (classifierDescriptor != null && !classifierDescriptor.isBoringBuiltinClass()) { - link(node, classifierDescriptor) + if (classifierDescriptor != null) { + link(node, classifierDescriptor, + if (classifierDescriptor.isBoringBuiltinClass()) DocumentationReference.Kind.HiddenLink else DocumentationReference.Kind.Link) } append(node, DocumentationReference.Kind.Detail) diff --git a/src/Kotlin/KotlinLanguageService.kt b/src/Kotlin/KotlinLanguageService.kt index 12a0bcda..1e7050ef 100644 --- a/src/Kotlin/KotlinLanguageService.kt +++ b/src/Kotlin/KotlinLanguageService.kt @@ -43,6 +43,74 @@ class KotlinLanguageService : LanguageService { } } + override fun summarizeSignatures(nodes: List<DocumentationNode>): ContentNode? { + if (nodes.size < 2) return null + val receiverKind = nodes.getReceiverKind() ?: return null + val functionWithTypeParameter = nodes.firstOrNull { it.details(DocumentationNode.Kind.TypeParameter).any() } ?: return null + return content { + val typeParameter = functionWithTypeParameter.details(DocumentationNode.Kind.TypeParameter).first() + renderFunction(functionWithTypeParameter, RenderMode.SUMMARY, SummarizingMapper(receiverKind, typeParameter.name)) + } + } + + private fun List<DocumentationNode>.getReceiverKind(): ReceiverKind? { + val qNames = map { it.getReceiverQName() }.filterNotNull() + if (qNames.size != size) + return null + + return ReceiverKind.values.firstOrNull { kind -> qNames.all { it in kind.classes } } + } + + private fun DocumentationNode.getReceiverQName(): String? { + if (kind != DocumentationNode.Kind.Function) return null + val receiver = details(DocumentationNode.Kind.Receiver).singleOrNull() ?: return null + val receiverType = receiver.detail(DocumentationNode.Kind.Type) + return (receiverType.links.firstOrNull() ?: receiverType.hiddenLinks.firstOrNull())?.qualifiedName() + } + + companion object { + private val arrayClasses = setOf( + "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 + } + + private enum class ReceiverKind(val receiverName: String, val classes: Collection<String>) { + ARRAY("any_array", arrayClasses), + ARRAY_OR_LIST("any_array_or_list", arrayOrListClasses), + ITERABLE("any_iterable", iterableClasses), + } + + interface SignatureMapper { + fun renderReceiver(receiver: DocumentationNode, to: ContentBlock) + } + + private class SummarizingMapper(val kind: ReceiverKind, val typeParameterName: String): SignatureMapper { + override fun renderReceiver(receiver: DocumentationNode, to: ContentBlock) { + val newReceiver = ContentEmphasis() + newReceiver.append(ContentIdentifier(kind.receiverName, IdentifierKind.SummarizedTypeName)) + to.append(newReceiver) + to.text("<$typeParameterName>") + } + } + private fun ContentBlock.renderPackage(node: DocumentationNode) { keyword("package") text(" ") @@ -238,7 +306,9 @@ class KotlinLanguageService : LanguageService { renderSupertypesForNode(node) } - private fun ContentBlock.renderFunction(node: DocumentationNode, renderMode: RenderMode) { + private fun ContentBlock.renderFunction(node: DocumentationNode, + renderMode: RenderMode, + signatureMapper: SignatureMapper? = null) { if (renderMode == RenderMode.FULL) { renderAnnotationsForNode(node) } @@ -253,9 +323,15 @@ class KotlinLanguageService : LanguageService { if (node.details(DocumentationNode.Kind.TypeParameter).any()) { text(" ") } + val receiver = node.details(DocumentationNode.Kind.Receiver).singleOrNull() if (receiver != null) { - renderType(receiver.detail(DocumentationNode.Kind.Type)) + if (signatureMapper != null) { + signatureMapper.renderReceiver(receiver, this) + } + else { + renderType(receiver.detail(DocumentationNode.Kind.Type)) + } symbol(".") } |