aboutsummaryrefslogtreecommitdiff
path: root/plugins/base/src/main/kotlin/resolvers/local
diff options
context:
space:
mode:
authorIgnat Beresnev <ignat.beresnev@jetbrains.com>2023-11-10 11:46:54 +0100
committerGitHub <noreply@github.com>2023-11-10 11:46:54 +0100
commit8e5c63d035ef44a269b8c43430f43f5c8eebfb63 (patch)
tree1b915207b2b9f61951ddbf0ff2e687efd053d555 /plugins/base/src/main/kotlin/resolvers/local
parenta44efd4ba0c2e4ab921ff75e0f53fc9335aa79db (diff)
downloaddokka-8e5c63d035ef44a269b8c43430f43f5c8eebfb63.tar.gz
dokka-8e5c63d035ef44a269b8c43430f43f5c8eebfb63.tar.bz2
dokka-8e5c63d035ef44a269b8c43430f43f5c8eebfb63.zip
Restructure the project to utilize included builds (#3174)
* Refactor and simplify artifact publishing * Update Gradle to 8.4 * Refactor and simplify convention plugins and build scripts Fixes #3132 --------- Co-authored-by: Adam <897017+aSemy@users.noreply.github.com> Co-authored-by: Oleg Yukhnevich <whyoleg@gmail.com>
Diffstat (limited to 'plugins/base/src/main/kotlin/resolvers/local')
-rw-r--r--plugins/base/src/main/kotlin/resolvers/local/DefaultLocationProvider.kt82
-rw-r--r--plugins/base/src/main/kotlin/resolvers/local/DokkaBaseLocationProvider.kt27
-rw-r--r--plugins/base/src/main/kotlin/resolvers/local/DokkaLocationProvider.kt182
-rw-r--r--plugins/base/src/main/kotlin/resolvers/local/DokkaLocationProviderFactory.kt26
-rw-r--r--plugins/base/src/main/kotlin/resolvers/local/LocationProvider.kt47
-rw-r--r--plugins/base/src/main/kotlin/resolvers/local/LocationProviderFactory.kt11
6 files changed, 0 insertions, 375 deletions
diff --git a/plugins/base/src/main/kotlin/resolvers/local/DefaultLocationProvider.kt b/plugins/base/src/main/kotlin/resolvers/local/DefaultLocationProvider.kt
deleted file mode 100644
index 24d0f13e..00000000
--- a/plugins/base/src/main/kotlin/resolvers/local/DefaultLocationProvider.kt
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
- */
-
-package org.jetbrains.dokka.base.resolvers.local
-
-import org.jetbrains.dokka.base.DokkaBase
-import org.jetbrains.dokka.base.resolvers.external.DefaultExternalLocationProvider
-import org.jetbrains.dokka.base.resolvers.external.Dokka010ExternalLocationProvider
-import org.jetbrains.dokka.base.resolvers.external.ExternalLocationProvider
-import org.jetbrains.dokka.base.resolvers.external.ExternalLocationProviderFactory
-import org.jetbrains.dokka.base.resolvers.external.javadoc.AndroidExternalLocationProvider
-import org.jetbrains.dokka.base.resolvers.external.javadoc.JavadocExternalLocationProvider
-import org.jetbrains.dokka.base.resolvers.shared.ExternalDocumentation
-import org.jetbrains.dokka.base.resolvers.shared.PackageList
-import org.jetbrains.dokka.links.DRI
-import org.jetbrains.dokka.model.DisplaySourceSet
-import org.jetbrains.dokka.pages.RootPageNode
-import org.jetbrains.dokka.plugability.DokkaContext
-import org.jetbrains.dokka.plugability.plugin
-import org.jetbrains.dokka.plugability.query
-
-public abstract class DefaultLocationProvider(
- protected val pageGraphRoot: RootPageNode,
- protected val dokkaContext: DokkaContext
-) : LocationProvider {
- protected val externalLocationProviderFactories: List<ExternalLocationProviderFactory> =
- dokkaContext.plugin<DokkaBase>().query { externalLocationProviderFactory }
-
- protected val externalLocationProviders: Map<ExternalDocumentation, ExternalLocationProvider?> = dokkaContext
- .configuration
- .sourceSets
- .flatMap { sourceSet ->
- sourceSet.externalDocumentationLinks.map {
- PackageList.load(it.packageListUrl, sourceSet.jdkVersion, dokkaContext.configuration.offlineMode)
- ?.let { packageList -> ExternalDocumentation(it.url, packageList) }
- }
- }
- .filterNotNull().associateWith { extDocInfo ->
- externalLocationProviderFactories
- .mapNotNull { it.getExternalLocationProvider(extDocInfo) }
- .firstOrNull()
- ?: run { dokkaContext.logger.error("No ExternalLocationProvider for '${extDocInfo.packageList.url}' found"); null }
- }
-
- protected val packagesIndex: Map<String, ExternalLocationProvider?> =
- externalLocationProviders
- .flatMap { (extDocInfo, externalLocationProvider) ->
- extDocInfo.packageList.packages.map { packageName -> packageName to externalLocationProvider }
- }.groupBy { it.first }.mapValues { (_, lst) ->
- lst.map { it.second }
- .sortedWith(compareBy(nullsLast(ExternalLocationProviderOrdering)) { it })
- .firstOrNull()
- }
- .filterKeys(String::isNotBlank)
-
-
- protected val locationsIndex: Map<String, ExternalLocationProvider?> = externalLocationProviders
- .flatMap { (extDocInfo, externalLocationProvider) ->
- extDocInfo.packageList.locations.keys.map { relocatedDri -> relocatedDri to externalLocationProvider }
- }
- .toMap()
- .filterKeys(String::isNotBlank)
-
- protected open fun getExternalLocation(dri: DRI, sourceSets: Set<DisplaySourceSet>): String? =
- packagesIndex[dri.packageName]?.resolve(dri)
- ?: locationsIndex[dri.toString()]?.resolve(dri)
- ?: externalLocationProviders.values.mapNotNull { it?.resolve(dri) }.firstOrNull()
-
- private object ExternalLocationProviderOrdering : Comparator<ExternalLocationProvider> {
- private val desiredOrdering = listOf(
- DefaultExternalLocationProvider::class,
- Dokka010ExternalLocationProvider::class,
- AndroidExternalLocationProvider::class,
- JavadocExternalLocationProvider::class
- )
-
- override fun compare(o1: ExternalLocationProvider, o2: ExternalLocationProvider): Int =
- desiredOrdering.indexOf(o1::class).compareTo(desiredOrdering.indexOf(o2::class))
- }
-
-}
diff --git a/plugins/base/src/main/kotlin/resolvers/local/DokkaBaseLocationProvider.kt b/plugins/base/src/main/kotlin/resolvers/local/DokkaBaseLocationProvider.kt
deleted file mode 100644
index ca3786ad..00000000
--- a/plugins/base/src/main/kotlin/resolvers/local/DokkaBaseLocationProvider.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
- */
-
-package org.jetbrains.dokka.base.resolvers.local
-
-import org.jetbrains.dokka.base.renderers.shortenToUrl
-import org.jetbrains.dokka.model.DisplaySourceSet
-import org.jetbrains.dokka.pages.DCI
-import org.jetbrains.dokka.pages.RootPageNode
-import org.jetbrains.dokka.plugability.DokkaContext
-import org.jetbrains.dokka.utilities.urlEncoded
-
-public abstract class DokkaBaseLocationProvider(
- pageGraphRoot: RootPageNode,
- dokkaContext: DokkaContext
-) : DefaultLocationProvider(pageGraphRoot, dokkaContext) {
-
- /**
- * Anchors should be unique and should contain sourcesets, dri and contentKind.
- * The idea is to make them as short as possible and just use a hashCode from sourcesets in order to match the
- * 2040 characters limit
- */
- public open fun anchorForDCI(dci: DCI, sourceSets: Set<DisplaySourceSet>): String =
- (dci.dri.shortenToUrl().toString() + "/" + dci.kind + "/" + sourceSets.shortenToUrl()).urlEncoded()
-
-}
diff --git a/plugins/base/src/main/kotlin/resolvers/local/DokkaLocationProvider.kt b/plugins/base/src/main/kotlin/resolvers/local/DokkaLocationProvider.kt
deleted file mode 100644
index aedbfb88..00000000
--- a/plugins/base/src/main/kotlin/resolvers/local/DokkaLocationProvider.kt
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
- */
-
-package org.jetbrains.dokka.base.resolvers.local
-
-import org.jetbrains.dokka.base.renderers.sourceSets
-import org.jetbrains.dokka.base.resolvers.anchors.SymbolAnchorHint
-import org.jetbrains.dokka.links.DRI
-import org.jetbrains.dokka.links.PointingToDeclaration
-import org.jetbrains.dokka.model.*
-import org.jetbrains.dokka.pages.*
-import org.jetbrains.dokka.plugability.DokkaContext
-import java.util.*
-
-public open class DokkaLocationProvider(
- pageGraphRoot: RootPageNode,
- dokkaContext: DokkaContext,
- public val extension: String = ".html"
-) : DokkaBaseLocationProvider(pageGraphRoot, dokkaContext) {
- protected open val PAGE_WITH_CHILDREN_SUFFIX: String = "index"
-
- protected open val pathsIndex: Map<PageNode, List<String>> = IdentityHashMap<PageNode, List<String>>().apply {
- fun registerPath(page: PageNode, prefix: List<String>) {
- if (page is RootPageNode && page.forceTopLevelName) {
- put(page, prefix + PAGE_WITH_CHILDREN_SUFFIX)
- page.children.forEach { registerPath(it, prefix) }
- } else {
- val newPrefix = prefix + page.pathName
- put(page, if (page is ModulePageNode) prefix else newPrefix)
- page.children.forEach { registerPath(it, newPrefix) }
- }
-
- }
- put(pageGraphRoot, emptyList())
- pageGraphRoot.children.forEach { registerPath(it, emptyList()) }
- }
-
- protected val pagesIndex: Map<DRIWithSourceSets, ContentPage> =
- pageGraphRoot.withDescendants().filterIsInstance<ContentPage>()
- .flatMap { page ->
- page.dri.flatMap { dri ->
- page.sourceSets().ifEmpty { setOf(null) }
- .map { sourceSet -> DRIWithSourceSets(dri, setOfNotNull(sourceSet)) to page }
- .let {
- if (it.size > 1) {
- it + (DRIWithSourceSets(dri, page.sourceSets()) to page)
- } else {
- it
- }
- }
- }
- }
- .groupingBy { it.first }
- .aggregate { key, _, (_, page), first ->
- if (first) page else throw AssertionError("Multiple pages associated with key: ${key.dri}/${key.sourceSet}")
- }
-
- protected val anchorsIndex: Map<DRIWithSourceSets, PageWithKind> =
- pageGraphRoot.withDescendants().filterIsInstance<ContentPage>()
- .flatMap { page ->
- page.content.withDescendants()
- .filter { it.extra[SymbolAnchorHint] != null && it.dci.dri.any() }
- .flatMap { content ->
- content.dci.dri.map { dri ->
- (dri to content.sourceSets) to content.extra[SymbolAnchorHint]?.contentKind!!
- }
- }
- .distinct()
- .flatMap { (pair, kind) ->
- val (dri, sourceSets) = pair
- sourceSets.ifEmpty { setOf(null) }.map { sourceSet ->
- DRIWithSourceSets(dri, setOfNotNull(sourceSet)) to PageWithKind(page, kind)
- }
- }
- }.toMap()
-
- override fun resolve(node: PageNode, context: PageNode?, skipExtension: Boolean): String =
- pathTo(node, context) + if (!skipExtension) extension else ""
-
- override fun resolve(dri: DRI, sourceSets: Set<DisplaySourceSet>, context: PageNode?): String? =
- sourceSets.ifEmpty { setOf(null) }.mapNotNull { sourceSet ->
- val driWithSourceSets = DRIWithSourceSets(dri, setOfNotNull(sourceSet))
- getLocalLocation(driWithSourceSets, context)
- ?: getLocalLocation(driWithSourceSets.copy(dri = dri.copy(target = PointingToDeclaration)), context)
- // Not found in PageGraph, that means it's an external link
- ?: getExternalLocation(dri, sourceSets)
- ?: getExternalLocation(dri.copy(target = PointingToDeclaration), sourceSets)
- }.distinct().singleOrNull()
-
- private fun getLocalLocation(driWithSourceSets: DRIWithSourceSets, context: PageNode?): String? {
- val (dri, originalSourceSet) = driWithSourceSets
- val allSourceSets: List<Set<DisplaySourceSet>> =
- listOf(originalSourceSet) + originalSourceSet.let { oss ->
- val ossIds = oss.computeSourceSetIds()
- dokkaContext.configuration.sourceSets.filter { it.sourceSetID in ossIds }
- .flatMap { it.dependentSourceSets }
- .mapNotNull { ssid ->
- dokkaContext.configuration.sourceSets.find { it.sourceSetID == ssid }?.toDisplaySourceSet()
- }.map {
- setOf(it)
- }
- }
-
- return getLocalPageLink(dri, allSourceSets, context)
- ?: getLocalAnchor(dri, allSourceSets, context)
- }
-
- private fun getLocalPageLink(dri: DRI, allSourceSets: Iterable<Set<DisplaySourceSet>>, context: PageNode?) =
- allSourceSets.mapNotNull { displaySourceSet ->
- pagesIndex[DRIWithSourceSets(dri, displaySourceSet)]
- }.firstOrNull()?.let { page -> resolve(page, context) }
-
- private fun getLocalAnchor(dri: DRI, allSourceSets: Iterable<Set<DisplaySourceSet>>, context: PageNode?) =
- allSourceSets.mapNotNull { displaySourceSet ->
- anchorsIndex[DRIWithSourceSets(dri, displaySourceSet)]?.let { (page, kind) ->
- val dci = DCI(setOf(dri), kind)
- resolve(page, context) + "#" + anchorForDCI(dci, displaySourceSet)
- }
- }.firstOrNull()
-
- override fun pathToRoot(from: PageNode): String =
- pathTo(pageGraphRoot, from).removeSuffix(PAGE_WITH_CHILDREN_SUFFIX)
-
- override fun ancestors(node: PageNode): List<PageNode> =
- generateSequence(node) { it.parent() }.toList()
-
- protected open fun pathTo(node: PageNode, context: PageNode?): String {
- fun pathFor(page: PageNode) = pathsIndex[page] ?: throw AssertionError(
- "${page::class.simpleName}(${page.name}) does not belong to the current page graph so it is impossible to compute its path"
- )
-
- val nodePath = pathFor(node)
- val contextPath = context?.let { pathFor(it) }.orEmpty()
- val endedContextPath = if (context?.isIndexPage() == false)
- contextPath.toMutableList().also { it.removeLastOrNull() }
- else contextPath
-
- val commonPathElements = nodePath.asSequence().zip(endedContextPath.asSequence())
- .takeWhile { (a, b) -> a == b }.count()
-
- return (List(endedContextPath.size - commonPathElements) { ".." } + nodePath.drop(commonPathElements) +
- if (node.isIndexPage())
- listOf(PAGE_WITH_CHILDREN_SUFFIX)
- else
- emptyList()
- ).joinToString("/")
- }
-
- private fun PageNode.isIndexPage() = this is ClasslikePageNode || children.isNotEmpty()
-
- private fun PageNode.parent() = pageGraphRoot.parentMap[this]
-
- private val PageNode.pathName: String
- get() = if (this is PackagePageNode || this is RendererSpecificResourcePage) name else identifierToFilename(name)
-
- protected data class DRIWithSourceSets(val dri: DRI, val sourceSet: Set<DisplaySourceSet>)
-
- protected data class PageWithKind(val page: ContentPage, val kind: Kind)
-
- public companion object {
- public val reservedFilenames: Set<String> = setOf("index", "con", "aux", "lst", "prn", "nul", "eof", "inp", "out")
-
- //Taken from: https://stackoverflow.com/questions/1976007/what-characters-are-forbidden-in-windows-and-linux-directory-names
- internal val reservedCharacters = setOf('|', '>', '<', '*', ':', '"', '?', '%')
-
- public fun identifierToFilename(name: String): String {
- if (name.isEmpty()) return "--root--"
- return sanitizeFileName(name, reservedFilenames, reservedCharacters)
- }
- }
-}
-
-internal fun sanitizeFileName(name: String, reservedFileNames: Set<String>, reservedCharacters: Set<Char>): String {
- val lowercase = name.replace("[A-Z]".toRegex()) { matchResult -> "-" + matchResult.value.toLowerCase() }
- val withoutReservedFileNames = if (lowercase in reservedFileNames) "--$lowercase--" else lowercase
- return reservedCharacters.fold(withoutReservedFileNames) { acc, character ->
- if (character in acc) acc.replace(character.toString(), "[${character.toInt()}]")
- else acc
- }
-}
-
diff --git a/plugins/base/src/main/kotlin/resolvers/local/DokkaLocationProviderFactory.kt b/plugins/base/src/main/kotlin/resolvers/local/DokkaLocationProviderFactory.kt
deleted file mode 100644
index bd9fa1bb..00000000
--- a/plugins/base/src/main/kotlin/resolvers/local/DokkaLocationProviderFactory.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
- */
-
-package org.jetbrains.dokka.base.resolvers.local
-
-import org.jetbrains.dokka.pages.RootPageNode
-import org.jetbrains.dokka.plugability.DokkaContext
-import java.util.concurrent.ConcurrentHashMap
-
-public class DokkaLocationProviderFactory(
- private val context: DokkaContext
-) : LocationProviderFactory {
- private val cache = ConcurrentHashMap<CacheWrapper, LocationProvider>()
-
- override fun getLocationProvider(pageNode: RootPageNode): LocationProvider {
- return cache.computeIfAbsent(CacheWrapper(pageNode)) {
- DokkaLocationProvider(pageNode, context)
- }
- }
-
- private class CacheWrapper(val pageNode: RootPageNode) {
- override fun equals(other: Any?) = other is CacheWrapper && other.pageNode == this.pageNode
- override fun hashCode() = System.identityHashCode(pageNode)
- }
-}
diff --git a/plugins/base/src/main/kotlin/resolvers/local/LocationProvider.kt b/plugins/base/src/main/kotlin/resolvers/local/LocationProvider.kt
deleted file mode 100644
index dbcd5c76..00000000
--- a/plugins/base/src/main/kotlin/resolvers/local/LocationProvider.kt
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
- */
-
-package org.jetbrains.dokka.base.resolvers.local
-
-import org.jetbrains.dokka.DokkaException
-import org.jetbrains.dokka.base.resolvers.local.DokkaLocationProvider.Companion.identifierToFilename
-import org.jetbrains.dokka.links.DRI
-import org.jetbrains.dokka.model.DisplaySourceSet
-import org.jetbrains.dokka.pages.PageNode
-
-public interface LocationProvider {
- public fun resolve(dri: DRI, sourceSets: Set<DisplaySourceSet>, context: PageNode? = null): String?
- public fun resolve(node: PageNode, context: PageNode? = null, skipExtension: Boolean = false): String?
- public fun pathToRoot(from: PageNode): String
- public fun ancestors(node: PageNode): List<PageNode>
-
- /**
- * This method should return guessed filesystem location for a given [DRI]
- * It is used to decide if a [DRI] should be present in the relocation list of the
- * generated package-list so it is ok if the path differs from the one returned by [resolve]
- * @return Path to a giver [DRI] or null if path should not be considered for relocations
- */
- public fun expectedLocationForDri(dri: DRI): String =
- (listOf(dri.packageName) +
- dri.classNames?.split(".")?.map { identifierToFilename(it) }.orEmpty() +
- listOf(dri.callable?.let { identifierToFilename(it.name) } ?: "index")
- ).filterNotNull().joinToString("/")
-}
-
-public fun LocationProvider.resolveOrThrow(
- dri: DRI, sourceSets: Set<DisplaySourceSet>,
- context: PageNode? = null
-): String {
- return resolve(dri = dri, sourceSets = sourceSets, context = context)
- ?: throw DokkaException("Cannot resolve path for $dri")
-}
-
-public fun LocationProvider.resolveOrThrow(
- node: PageNode,
- context: PageNode? = null,
- skipExtension: Boolean = false
-): String {
- return resolve(node = node, context = context, skipExtension = skipExtension)
- ?: throw DokkaException("Cannot resolve path for ${node.name}")
-}
diff --git a/plugins/base/src/main/kotlin/resolvers/local/LocationProviderFactory.kt b/plugins/base/src/main/kotlin/resolvers/local/LocationProviderFactory.kt
deleted file mode 100644
index 31cac868..00000000
--- a/plugins/base/src/main/kotlin/resolvers/local/LocationProviderFactory.kt
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
- */
-
-package org.jetbrains.dokka.base.resolvers.local
-
-import org.jetbrains.dokka.pages.RootPageNode
-
-public fun interface LocationProviderFactory {
- public fun getLocationProvider(pageNode: RootPageNode): LocationProvider
-}