From 0bf1d0f5491a62c56393a06cdfb4168778d9829e Mon Sep 17 00:00:00 2001 From: Kamil Doległo <9080183+kamildoleglo@users.noreply.github.com> Date: Mon, 5 Jul 2021 14:10:23 +0200 Subject: Flatten multi-module structure (#1980) * Add support for multimodule package lists * Merge package-lists in multi-module generation * Remove double-wrapping of modules in multi-module generation * Handle empty modules in package lists --- .../main/kotlin/resolvers/shared/PackageList.kt | 43 ++++++++++++++++++---- 1 file changed, 35 insertions(+), 8 deletions(-) (limited to 'plugins/base/src/main/kotlin/resolvers/shared') diff --git a/plugins/base/src/main/kotlin/resolvers/shared/PackageList.kt b/plugins/base/src/main/kotlin/resolvers/shared/PackageList.kt index a06365eb..469904bd 100644 --- a/plugins/base/src/main/kotlin/resolvers/shared/PackageList.kt +++ b/plugins/base/src/main/kotlin/resolvers/shared/PackageList.kt @@ -1,20 +1,33 @@ package org.jetbrains.dokka.base.resolvers.shared -import org.jetbrains.dokka.base.renderers.PackageListService import java.net.URL +typealias Module = String + data class PackageList( val linkFormat: RecognizedLinkFormat, - val packages: Set, + val modules: Map>, val locations: Map, val url: URL ) { + val packages: Set + get() = modules.values.flatten().toSet() + + fun moduleFor(packageName: String) = modules.asSequence() + .filter { it.value.contains(packageName) } + .firstOrNull()?.key + companion object { + const val PACKAGE_LIST_NAME = "package-list" + const val MODULE_DELIMITER = "module:" + const val DOKKA_PARAM_PREFIX = "\$dokka" + const val SINGLE_MODULE_NAME = "" + fun load(url: URL, jdkVersion: Int, offlineMode: Boolean = false): PackageList? { if (offlineMode && url.protocol.toLowerCase() != "file") return null - val packageListStream = kotlin.runCatching { url.readContent() }.onFailure { + val packageListStream = runCatching { url.readContent() }.onFailure { println("Failed to download package-list from $url, this might suggest that remote resource is not available," + " module is empty or dokka output got corrupted") return null @@ -22,22 +35,36 @@ data class PackageList( val (params, packages) = packageListStream .bufferedReader() - .useLines { lines -> lines.partition { it.startsWith(PackageListService.DOKKA_PARAM_PREFIX) } } + .useLines { lines -> lines.partition { it.startsWith(DOKKA_PARAM_PREFIX) } } val paramsMap = splitParams(params) val format = linkFormat(paramsMap["format"]?.singleOrNull(), jdkVersion) val locations = splitLocations(paramsMap["location"].orEmpty()).filterKeys(String::isNotEmpty) - return PackageList(format, packages.filter(String::isNotBlank).toSet(), locations, url) + val modulesMap = splitPackages(packages) + return PackageList(format, modulesMap, locations, url) } private fun splitParams(params: List) = params.asSequence() - .map { it.removePrefix("${PackageListService.DOKKA_PARAM_PREFIX}.").split(":", limit = 2) } + .map { it.removePrefix("$DOKKA_PARAM_PREFIX.").split(":", limit = 2) } .groupBy({ (key, _) -> key }, { (_, value) -> value }) private fun splitLocations(locations: List) = locations.map { it.split("\u001f", limit = 2) } - .map { (key, value) -> key to value } - .toMap() + .associate { (key, value) -> key to value } + + private fun splitPackages(packages: List): Map> = + packages.fold(("" to mutableMapOf>())) { (lastModule, acc), el -> + val currentModule : String + when { + el.startsWith(MODULE_DELIMITER) -> currentModule = el.substringAfter(MODULE_DELIMITER) + el.isNotBlank() -> { + currentModule = lastModule + acc[currentModule] = acc.getOrDefault(lastModule, emptySet()) + el + } + else -> currentModule = lastModule + } + currentModule to acc + }.second private fun linkFormat(formatName: String?, jdkVersion: Int) = formatName?.let { RecognizedLinkFormat.fromString(it) } -- cgit