diff options
author | Simon Ogorodnik <Simon.Ogorodnik@jetbrains.com> | 2017-05-03 13:45:30 +0300 |
---|---|---|
committer | Simon Ogorodnik <Simon.Ogorodnik@jetbrains.com> | 2017-05-11 19:52:40 +0300 |
commit | a86c859eba6154524f3b42461aad6b45f26e3650 (patch) | |
tree | 6772882331daf29c8d19e4a3ed77ef938d45b1ac /core/src/main/kotlin/Formats | |
parent | 022a6a6bc9a1d61f190715dec56c3bef31887388 (diff) | |
download | dokka-a86c859eba6154524f3b42461aad6b45f26e3650.tar.gz dokka-a86c859eba6154524f3b42461aad6b45f26e3650.tar.bz2 dokka-a86c859eba6154524f3b42461aad6b45f26e3650.zip |
Support linking of external documentation
Introduce PackageListService
#KT-16309 fixed
Diffstat (limited to 'core/src/main/kotlin/Formats')
5 files changed, 77 insertions, 7 deletions
diff --git a/core/src/main/kotlin/Formats/FormatDescriptor.kt b/core/src/main/kotlin/Formats/FormatDescriptor.kt index 7cc50acb..fc925f40 100644 --- a/core/src/main/kotlin/Formats/FormatDescriptor.kt +++ b/core/src/main/kotlin/Formats/FormatDescriptor.kt @@ -11,4 +11,5 @@ interface FormatDescriptor { val packageDocumentationBuilderClass: KClass<out PackageDocumentationBuilder> val javaDocumentationBuilderClass: KClass<out JavaDocumentationBuilder> val sampleProcessingService: KClass<out SampleProcessingService> + val packageListServiceClass: KClass<out PackageListService>? } diff --git a/core/src/main/kotlin/Formats/FormatService.kt b/core/src/main/kotlin/Formats/FormatService.kt index e281f2fc..63f25008 100644 --- a/core/src/main/kotlin/Formats/FormatService.kt +++ b/core/src/main/kotlin/Formats/FormatService.kt @@ -11,6 +11,10 @@ interface FormatService { /** Returns extension for output files */ val extension: String + /** extension which will be used for internal and external linking */ + val linkExtension: String + get() = extension + fun createOutputBuilder(to: StringBuilder, location: Location): FormattedOutputBuilder fun enumerateSupportFiles(callback: (resource: String, targetPath: String) -> Unit) { diff --git a/core/src/main/kotlin/Formats/PackageListService.kt b/core/src/main/kotlin/Formats/PackageListService.kt new file mode 100644 index 00000000..360dbb46 --- /dev/null +++ b/core/src/main/kotlin/Formats/PackageListService.kt @@ -0,0 +1,63 @@ +package org.jetbrains.dokka + +import com.google.inject.Inject + + +interface PackageListService { + fun formatPackageList(module: DocumentationModule): String +} + +class DefaultPackageListService @Inject constructor(locationService: FileLocationService, + val formatService: FormatService) : PackageListService { + + val locationService: FileLocationService = locationService.withExtension(formatService.linkExtension) + + override fun formatPackageList(module: DocumentationModule): String { + val packages = mutableSetOf<String>() + val nonStandardLocations = mutableMapOf<String, String>() + + fun visit(node: DocumentationNode, relocated: Boolean = false) { + val nodeKind = node.kind + + when (nodeKind) { + NodeKind.Package -> { + packages.add(node.qualifiedName()) + node.members.forEach { visit(it) } + } + NodeKind.Signature -> { + if (relocated) + nonStandardLocations[node.name] = locationService.relativePathToLocation(module, node.owner!!) + } + NodeKind.ExternalClass -> { + node.members.forEach { visit(it, relocated = true) } + } + NodeKind.GroupNode -> { + //only children of top-level GN records interesting for us, since link to top-level ones should point to GN + node.members.forEach { it.members.forEach { visit(it, relocated = true) } } + //record signature of GN as signature of type alias and class merged to GN, so link to it should point to GN + node.detailOrNull(NodeKind.Signature)?.let { visit(it, relocated = true) } + } + else -> { + if (nodeKind in NodeKind.classLike || nodeKind in NodeKind.memberLike) { + node.details(NodeKind.Signature).forEach { visit(it, relocated) } + node.members.forEach { visit(it, relocated) } + } + } + } + } + + module.members.forEach { visit(it) } + + return buildString { + appendln("\$dokka.linkExtension:${formatService.linkExtension}") + + nonStandardLocations.map { (signature, location) -> "\$dokka.location:$signature\u001f$location" } + .joinTo(this, separator = "\n", postfix = "\n") + + packages.joinTo(this, separator = "\n", postfix = "\n") + } + + } + +} + diff --git a/core/src/main/kotlin/Formats/StandardFormats.kt b/core/src/main/kotlin/Formats/StandardFormats.kt index c67386af..fad65ff1 100644 --- a/core/src/main/kotlin/Formats/StandardFormats.kt +++ b/core/src/main/kotlin/Formats/StandardFormats.kt @@ -13,6 +13,7 @@ abstract class KotlinFormatDescriptorBase : FormatDescriptor { override val generatorServiceClass = FileGenerator::class override val outlineServiceClass: KClass<out OutlineFormatService>? = null override val sampleProcessingService: KClass<out SampleProcessingService> = DefaultSampleProcessingService::class + override val packageListServiceClass: KClass<out PackageListService>? = DefaultPackageListService::class } class HtmlFormatDescriptor : KotlinFormatDescriptorBase() { @@ -27,6 +28,7 @@ class HtmlAsJavaFormatDescriptor : FormatDescriptor { override val packageDocumentationBuilderClass = KotlinAsJavaDocumentationBuilder::class override val javaDocumentationBuilderClass = JavaPsiDocumentationBuilder::class override val sampleProcessingService: KClass<out SampleProcessingService> = DefaultSampleProcessingService::class + override val packageListServiceClass: KClass<out PackageListService>? = DefaultPackageListService::class } class KotlinWebsiteFormatDescriptor : KotlinFormatDescriptorBase() { diff --git a/core/src/main/kotlin/Formats/StructuredFormatService.kt b/core/src/main/kotlin/Formats/StructuredFormatService.kt index b29cf492..a8b000b7 100644 --- a/core/src/main/kotlin/Formats/StructuredFormatService.kt +++ b/core/src/main/kotlin/Formats/StructuredFormatService.kt @@ -290,16 +290,16 @@ abstract class StructuredOutputBuilder(val to: StringBuilder, for ((name, items) in breakdownByName) { if (!noHeader) appendHeader { appendText(name) } - appendDocumentation(items) + appendDocumentation(items, singleNode != null) } } } - private fun appendDocumentation(overloads: Iterable<DocumentationNode>) { + private fun appendDocumentation(overloads: Iterable<DocumentationNode>, isSingleNode: Boolean) { val breakdownBySummary = overloads.groupByTo(LinkedHashMap()) { node -> node.content } if (breakdownBySummary.size == 1) { - formatOverloadGroup(breakdownBySummary.values.single()) + formatOverloadGroup(breakdownBySummary.values.single(), isSingleNode) } else { for ((_, items) in breakdownBySummary) { @@ -311,12 +311,13 @@ abstract class StructuredOutputBuilder(val to: StringBuilder, } } - private fun formatOverloadGroup(items: List<DocumentationNode>) { + private fun formatOverloadGroup(items: List<DocumentationNode>, isSingleNode: Boolean = false) { for ((index, item) in items.withIndex()) { if (index > 0) appendLine() val rendered = languageService.render(item) item.detailOrNull(NodeKind.Signature)?.let { - appendAnchor(it.name) + if (item.kind !in NodeKind.classLike || !isSingleNode) + appendAnchor(it.name) } appendAsSignature(rendered) { appendCode { appendContent(rendered) } @@ -439,7 +440,6 @@ abstract class StructuredOutputBuilder(val to: StringBuilder, inner class GroupNodePageBuilder(val node: DocumentationNode) : PageBuilder(listOf(node)) { override fun build() { - val breakdownByLocation = node.path.filterNot { it.name.isEmpty() }.map { link(node, it) } appendBreadcrumbs(breakdownByLocation) @@ -658,6 +658,6 @@ abstract class StructuredOutputBuilder(val to: StringBuilder, abstract class StructuredFormatService(locationService: LocationService, val languageService: LanguageService, override val extension: String, - linkExtension: String = extension) : FormatService { + override final val linkExtension: String = extension) : FormatService { val locationService: LocationService = locationService.withExtension(linkExtension) } |