diff options
author | Ignat Beresnev <ignat.beresnev@jetbrains.com> | 2023-11-10 11:46:54 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-10 11:46:54 +0100 |
commit | 8e5c63d035ef44a269b8c43430f43f5c8eebfb63 (patch) | |
tree | 1b915207b2b9f61951ddbf0ff2e687efd053d555 /plugins/base/src/main/kotlin/resolvers | |
parent | a44efd4ba0c2e4ab921ff75e0f53fc9335aa79db (diff) | |
download | dokka-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')
21 files changed, 0 insertions, 855 deletions
diff --git a/plugins/base/src/main/kotlin/resolvers/anchors/AnchorsHint.kt b/plugins/base/src/main/kotlin/resolvers/anchors/AnchorsHint.kt deleted file mode 100644 index c9218947..00000000 --- a/plugins/base/src/main/kotlin/resolvers/anchors/AnchorsHint.kt +++ /dev/null @@ -1,19 +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.anchors - -import org.jetbrains.dokka.model.Documentable -import org.jetbrains.dokka.model.properties.ExtraProperty -import org.jetbrains.dokka.pages.ContentNode -import org.jetbrains.dokka.pages.Kind - -public data class SymbolAnchorHint(val anchorName: String, val contentKind: Kind) : ExtraProperty<ContentNode> { - override val key: ExtraProperty.Key<ContentNode, SymbolAnchorHint> = SymbolAnchorHint - - public companion object : ExtraProperty.Key<ContentNode, SymbolAnchorHint> { - public fun from(d: Documentable, contentKind: Kind): SymbolAnchorHint? = - d.name?.let { SymbolAnchorHint(it, contentKind) } - } -} diff --git a/plugins/base/src/main/kotlin/resolvers/external/DefaultExternalLocationProvider.kt b/plugins/base/src/main/kotlin/resolvers/external/DefaultExternalLocationProvider.kt deleted file mode 100644 index 32825303..00000000 --- a/plugins/base/src/main/kotlin/resolvers/external/DefaultExternalLocationProvider.kt +++ /dev/null @@ -1,46 +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.external - -import org.jetbrains.dokka.base.resolvers.local.DokkaLocationProvider.Companion.identifierToFilename -import org.jetbrains.dokka.base.resolvers.shared.ExternalDocumentation -import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.plugability.DokkaContext - -public open class DefaultExternalLocationProvider( - public val externalDocumentation: ExternalDocumentation, - public val extension: String, - public val dokkaContext: DokkaContext -) : ExternalLocationProvider { - public val docURL: String = externalDocumentation.documentationURL.toString().removeSuffix("/") + "/" - - override fun resolve(dri: DRI): String? { - externalDocumentation.packageList.locations[dri.toString()]?.let { path -> return "$docURL$path" } - - if (dri.packageName !in externalDocumentation.packageList.packages) - return null - - return dri.constructPath() - } - - protected open fun DRI.constructPath(): String { - val modulePart = packageName?.let { packageName -> - externalDocumentation.packageList.moduleFor(packageName)?.let { - if (it.isNotBlank()) - "$it/" - else - "" - } - }.orEmpty() - - val docWithModule = docURL + modulePart - val classNamesChecked = classNames ?: return "$docWithModule${packageName ?: ""}/index$extension" - val classLink = (listOfNotNull(packageName) + classNamesChecked.split('.')) - .joinToString("/", transform = ::identifierToFilename) - - val fileName = callable?.let { identifierToFilename(it.name) } ?: "index" - return "$docWithModule$classLink/$fileName$extension" - } -} diff --git a/plugins/base/src/main/kotlin/resolvers/external/DefaultExternalLocationProviderFactory.kt b/plugins/base/src/main/kotlin/resolvers/external/DefaultExternalLocationProviderFactory.kt deleted file mode 100644 index 09ddca01..00000000 --- a/plugins/base/src/main/kotlin/resolvers/external/DefaultExternalLocationProviderFactory.kt +++ /dev/null @@ -1,28 +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.external - -import org.jetbrains.dokka.base.resolvers.shared.RecognizedLinkFormat -import org.jetbrains.dokka.plugability.DokkaContext - -public class DefaultExternalLocationProviderFactory( - public val context: DokkaContext, -) : ExternalLocationProviderFactory by ExternalLocationProviderFactoryWithCache( - { doc -> - when (doc.packageList.linkFormat) { - RecognizedLinkFormat.KotlinWebsite, - RecognizedLinkFormat.KotlinWebsiteHtml, - RecognizedLinkFormat.DokkaOldHtml, - -> Dokka010ExternalLocationProvider(doc, ".html", context) - - RecognizedLinkFormat.DokkaHtml -> DefaultExternalLocationProvider(doc, ".html", context) - RecognizedLinkFormat.DokkaGFM, - RecognizedLinkFormat.DokkaJekyll, - -> DefaultExternalLocationProvider(doc, ".md", context) - - else -> null - } - } -) diff --git a/plugins/base/src/main/kotlin/resolvers/external/Dokka010ExternalLocationProvider.kt b/plugins/base/src/main/kotlin/resolvers/external/Dokka010ExternalLocationProvider.kt deleted file mode 100644 index f887c9bc..00000000 --- a/plugins/base/src/main/kotlin/resolvers/external/Dokka010ExternalLocationProvider.kt +++ /dev/null @@ -1,46 +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.external - -import org.jetbrains.dokka.base.resolvers.local.DokkaLocationProvider.Companion.identifierToFilename -import org.jetbrains.dokka.base.resolvers.shared.ExternalDocumentation -import org.jetbrains.dokka.links.Callable -import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.plugability.DokkaContext - -public open class Dokka010ExternalLocationProvider( - public val externalDocumentation: ExternalDocumentation, - public val extension: String, - public val dokkaContext: DokkaContext -) : ExternalLocationProvider { - public val docURL: String = externalDocumentation.documentationURL.toString().removeSuffix("/") + "/" - - override fun resolve(dri: DRI): String? { - - val fqName = listOfNotNull( - dri.packageName.takeIf { it?.isNotBlank() == true }, - dri.classNames.takeIf { it?.isNotBlank() == true }?.removeCompanion() - ).joinToString(".") - val relocationId = - fqName.let { if (dri.callable != null) it + "$" + dri.callable!!.toOldString() else it } - externalDocumentation.packageList.locations[relocationId]?.let { path -> return "$docURL$path" } - - if (dri.packageName !in externalDocumentation.packageList.packages) - return null - - val classNamesChecked = dri.classNames?.removeCompanion() - ?: return "$docURL${dri.packageName ?: ""}/index$extension" - - val classLink = (listOfNotNull(dri.packageName) + classNamesChecked.split('.')) - .joinToString("/", transform = ::identifierToFilename) - - val callableChecked = dri.callable ?: return "$docURL$classLink/index$extension" - return "$docURL$classLink/" + identifierToFilename(callableChecked.name) + extension - } - - private fun String.removeCompanion() = removeSuffix(".Companion") - - private fun Callable.toOldString() = name + params.joinToString(", ", "(", ")") + (receiver?.let { "#$it" } ?: "") -} diff --git a/plugins/base/src/main/kotlin/resolvers/external/ExternalLocationProvider.kt b/plugins/base/src/main/kotlin/resolvers/external/ExternalLocationProvider.kt deleted file mode 100644 index 238b6342..00000000 --- a/plugins/base/src/main/kotlin/resolvers/external/ExternalLocationProvider.kt +++ /dev/null @@ -1,18 +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.external - -import org.jetbrains.dokka.links.DRI - -/** - * Provides the path to the page documenting a [DRI] in an external documentation source - */ -public fun interface ExternalLocationProvider { - /** - * @return Path to the page containing the [dri] or null if the path cannot be created - * (eg. when the package-list does not contain [dri]'s package) - */ - public fun resolve(dri: DRI): String? -} diff --git a/plugins/base/src/main/kotlin/resolvers/external/ExternalLocationProviderFactory.kt b/plugins/base/src/main/kotlin/resolvers/external/ExternalLocationProviderFactory.kt deleted file mode 100644 index 952f4d51..00000000 --- a/plugins/base/src/main/kotlin/resolvers/external/ExternalLocationProviderFactory.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.external - -import org.jetbrains.dokka.base.resolvers.shared.ExternalDocumentation - -public fun interface ExternalLocationProviderFactory { - public fun getExternalLocationProvider(doc: ExternalDocumentation): ExternalLocationProvider? -} diff --git a/plugins/base/src/main/kotlin/resolvers/external/ExternalLocationProviderFactoryWithCache.kt b/plugins/base/src/main/kotlin/resolvers/external/ExternalLocationProviderFactoryWithCache.kt deleted file mode 100644 index 0b56e174..00000000 --- a/plugins/base/src/main/kotlin/resolvers/external/ExternalLocationProviderFactoryWithCache.kt +++ /dev/null @@ -1,21 +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.external - -import org.jetbrains.dokka.base.resolvers.shared.ExternalDocumentation -import java.util.concurrent.ConcurrentHashMap - -public class ExternalLocationProviderFactoryWithCache( - public val ext: ExternalLocationProviderFactory -) : ExternalLocationProviderFactory { - - private val locationProviders = ConcurrentHashMap<ExternalDocumentation, CacheWrapper>() - - override fun getExternalLocationProvider(doc: ExternalDocumentation): ExternalLocationProvider? = - locationProviders.getOrPut(doc) { CacheWrapper(ext.getExternalLocationProvider(doc)) }.provider - - private class CacheWrapper(val provider: ExternalLocationProvider?) -} - diff --git a/plugins/base/src/main/kotlin/resolvers/external/javadoc/AndroidExternalLocationProvider.kt b/plugins/base/src/main/kotlin/resolvers/external/javadoc/AndroidExternalLocationProvider.kt deleted file mode 100644 index 8c18be0c..00000000 --- a/plugins/base/src/main/kotlin/resolvers/external/javadoc/AndroidExternalLocationProvider.kt +++ /dev/null @@ -1,18 +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.external.javadoc - -import org.jetbrains.dokka.base.resolvers.shared.ExternalDocumentation -import org.jetbrains.dokka.links.Callable -import org.jetbrains.dokka.plugability.DokkaContext - -public open class AndroidExternalLocationProvider( - externalDocumentation: ExternalDocumentation, - dokkaContext: DokkaContext -) : JavadocExternalLocationProvider(externalDocumentation, "", "", dokkaContext) { - - override fun anchorPart(callable: Callable): String = callable.name.toLowerCase() - -} diff --git a/plugins/base/src/main/kotlin/resolvers/external/javadoc/JavadocExternalLocationProvider.kt b/plugins/base/src/main/kotlin/resolvers/external/javadoc/JavadocExternalLocationProvider.kt deleted file mode 100644 index 65ee0e02..00000000 --- a/plugins/base/src/main/kotlin/resolvers/external/javadoc/JavadocExternalLocationProvider.kt +++ /dev/null @@ -1,62 +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.external.javadoc - -import org.jetbrains.dokka.base.resolvers.external.DefaultExternalLocationProvider -import org.jetbrains.dokka.base.resolvers.shared.ExternalDocumentation -import org.jetbrains.dokka.links.Callable -import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.links.DRIExtraContainer -import org.jetbrains.dokka.links.EnumEntryDRIExtra -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.utilities.htmlEscape - -public open class JavadocExternalLocationProvider( - externalDocumentation: ExternalDocumentation, - public val brackets: String, - public val separator: String, - dokkaContext: DokkaContext -) : DefaultExternalLocationProvider(externalDocumentation, ".html", dokkaContext) { - - override fun DRI.constructPath(): String { - val packageLink = packageName?.replace(".", "/") - val modulePart = packageName?.let { packageName -> - externalDocumentation.packageList.moduleFor(packageName)?.let { - if (it.isNotBlank()) - "$it/" - else - "" - } - }.orEmpty() - - val docWithModule = docURL + modulePart - - if (classNames == null) { - return "$docWithModule$packageLink/package-summary$extension".htmlEscape() - } - - if (DRIExtraContainer(extra)[EnumEntryDRIExtra] != null) { - val lastIndex = classNames?.lastIndexOf(".") ?: 0 - val (classSplit, enumEntityAnchor) = - classNames?.substring(0, lastIndex) to classNames?.substring(lastIndex + 1) - - val classLink = - if (packageLink == null) "${classSplit}$extension" else "$packageLink/${classSplit}$extension" - return "$docWithModule$classLink#$enumEntityAnchor".htmlEscape() - } - - val classLink = if (packageLink == null) "${classNames}$extension" else "$packageLink/${classNames}$extension" - val callableChecked = callable ?: return "$docWithModule$classLink".htmlEscape() - - return ("$docWithModule$classLink#" + anchorPart(callableChecked)).htmlEscape() - } - - protected open fun anchorPart(callable: Callable): String { - return callable.name + - "${brackets.first()}" + - callable.params.joinToString(separator) + - "${brackets.last()}" - } -} diff --git a/plugins/base/src/main/kotlin/resolvers/external/javadoc/JavadocExternalLocationProviderFactory.kt b/plugins/base/src/main/kotlin/resolvers/external/javadoc/JavadocExternalLocationProviderFactory.kt deleted file mode 100644 index dc184e49..00000000 --- a/plugins/base/src/main/kotlin/resolvers/external/javadoc/JavadocExternalLocationProviderFactory.kt +++ /dev/null @@ -1,39 +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.external.javadoc - -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.androidSdk -import org.jetbrains.dokka.androidX -import org.jetbrains.dokka.base.resolvers.external.ExternalLocationProviderFactory -import org.jetbrains.dokka.base.resolvers.external.ExternalLocationProviderFactoryWithCache -import org.jetbrains.dokka.base.resolvers.shared.RecognizedLinkFormat -import org.jetbrains.dokka.plugability.DokkaContext - -public class JavadocExternalLocationProviderFactory( - public val context: DokkaContext, -) : ExternalLocationProviderFactory by ExternalLocationProviderFactoryWithCache( - { doc -> - when (doc.packageList.url) { - DokkaConfiguration.ExternalDocumentationLink.androidX().packageListUrl, - DokkaConfiguration.ExternalDocumentationLink.androidSdk().packageListUrl, - -> - AndroidExternalLocationProvider(doc, context) - - else -> - when (doc.packageList.linkFormat) { - RecognizedLinkFormat.Javadoc1 -> - JavadocExternalLocationProvider(doc, "()", ", ", context) // Covers JDK 1 - 7 - RecognizedLinkFormat.Javadoc8 -> - JavadocExternalLocationProvider(doc, "--", "-", context) // Covers JDK 8 - 9 - RecognizedLinkFormat.Javadoc10, - RecognizedLinkFormat.DokkaJavadoc, - -> - JavadocExternalLocationProvider(doc, "()", ",", context) // Covers JDK 10 - else -> null - } - } - } -) 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 -} diff --git a/plugins/base/src/main/kotlin/resolvers/shared/ExternalDocumentation.kt b/plugins/base/src/main/kotlin/resolvers/shared/ExternalDocumentation.kt deleted file mode 100644 index db0c5492..00000000 --- a/plugins/base/src/main/kotlin/resolvers/shared/ExternalDocumentation.kt +++ /dev/null @@ -1,9 +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.shared - -import java.net.URL - -public data class ExternalDocumentation(val documentationURL: URL, val packageList: PackageList) diff --git a/plugins/base/src/main/kotlin/resolvers/shared/LinkFormat.kt b/plugins/base/src/main/kotlin/resolvers/shared/LinkFormat.kt deleted file mode 100644 index 4f0d4932..00000000 --- a/plugins/base/src/main/kotlin/resolvers/shared/LinkFormat.kt +++ /dev/null @@ -1,10 +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.shared - -public interface LinkFormat { - public val formatName: String - public val linkExtension: String -} diff --git a/plugins/base/src/main/kotlin/resolvers/shared/PackageList.kt b/plugins/base/src/main/kotlin/resolvers/shared/PackageList.kt deleted file mode 100644 index 8297f875..00000000 --- a/plugins/base/src/main/kotlin/resolvers/shared/PackageList.kt +++ /dev/null @@ -1,83 +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.shared - -import java.net.URL - -public typealias Module = String - -public data class PackageList( - val linkFormat: RecognizedLinkFormat, - val modules: Map<Module, Set<String>>, - val locations: Map<String, String>, - val url: URL -) { - val packages: Set<String> - get() = modules.values.flatten().toSet() - - public fun moduleFor(packageName: String): Module? { - return modules.asSequence() - .filter { it.value.contains(packageName) } - .firstOrNull()?.key - } - - public companion object { - public const val PACKAGE_LIST_NAME: String = "package-list" - public const val MODULE_DELIMITER: String = "module:" - public const val DOKKA_PARAM_PREFIX: String = "\$dokka" - public const val SINGLE_MODULE_NAME: String = "" - - public fun load(url: URL, jdkVersion: Int, offlineMode: Boolean = false): PackageList? { - if (offlineMode && url.protocol.toLowerCase() != "file") - return null - - 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 - }.getOrThrow() - - val (params, packages) = packageListStream - .bufferedReader() - .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) - - val modulesMap = splitPackages(packages) - return PackageList(format, modulesMap, locations, url) - } - - private fun splitParams(params: List<String>) = params.asSequence() - .map { it.removePrefix("$DOKKA_PARAM_PREFIX.").split(":", limit = 2) } - .groupBy({ (key, _) -> key }, { (_, value) -> value }) - - private fun splitLocations(locations: List<String>) = locations.map { it.split("\u001f", limit = 2) } - .associate { (key, value) -> key to value } - - private fun splitPackages(packages: List<String>): Map<Module, Set<String>> = - packages.fold(("" to mutableMapOf<Module, Set<String>>())) { (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) } - ?: when { - jdkVersion < 8 -> RecognizedLinkFormat.Javadoc1 // Covers JDK 1 - 7 - jdkVersion < 10 -> RecognizedLinkFormat.Javadoc8 // Covers JDK 8 - 9 - else -> RecognizedLinkFormat.Javadoc10 // Covers JDK 10+ - } - } -} diff --git a/plugins/base/src/main/kotlin/resolvers/shared/RecognizedLinkFormat.kt b/plugins/base/src/main/kotlin/resolvers/shared/RecognizedLinkFormat.kt deleted file mode 100644 index 4810c9e5..00000000 --- a/plugins/base/src/main/kotlin/resolvers/shared/RecognizedLinkFormat.kt +++ /dev/null @@ -1,29 +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.shared - -public enum class RecognizedLinkFormat( - override val formatName: String, - override val linkExtension: String -) : LinkFormat { - DokkaHtml("html-v1", "html"), - DokkaJavadoc("javadoc-v1", "html"), - DokkaGFM("gfm-v1", "md"), - DokkaJekyll("jekyll-v1", "html"), - Javadoc1("javadoc1", "html"), - Javadoc8("javadoc8", "html"), - Javadoc10("javadoc10", "html"), - DokkaOldHtml("html", "html"), - KotlinWebsite("kotlin-website", "html"), - KotlinWebsiteHtml("kotlin-website-html", "html"); - - public companion object { - private val values = values() - - public fun fromString(formatName: String): RecognizedLinkFormat? { - return values.firstOrNull { it.formatName == formatName } - } - } -} diff --git a/plugins/base/src/main/kotlin/resolvers/shared/utils.kt b/plugins/base/src/main/kotlin/resolvers/shared/utils.kt deleted file mode 100644 index a6d9afc6..00000000 --- a/plugins/base/src/main/kotlin/resolvers/shared/utils.kt +++ /dev/null @@ -1,41 +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.shared - -import java.io.InputStream -import java.net.HttpURLConnection -import java.net.URL -import java.net.URLConnection - -internal fun URL.readContent(timeout: Int = 10000, redirectsAllowed: Int = 16): InputStream { - fun URL.doOpenConnection(timeout: Int, redirectsAllowed: Int): URLConnection { - val connection = this.openConnection().apply { - connectTimeout = timeout - readTimeout = timeout - } - - when (connection) { - is HttpURLConnection -> return when (connection.responseCode) { - in 200..299 -> connection - - HttpURLConnection.HTTP_MOVED_PERM, - HttpURLConnection.HTTP_MOVED_TEMP, - HttpURLConnection.HTTP_SEE_OTHER -> { - if (redirectsAllowed > 0) { - val newUrl = connection.getHeaderField("Location") - URL(newUrl).doOpenConnection(timeout, redirectsAllowed - 1) - } else { - throw RuntimeException("Too many redirects") - } - } - - else -> throw RuntimeException("Unhandled HTTP code: ${connection.responseCode}") - } - - else -> return connection - } - } - return doOpenConnection(timeout, redirectsAllowed).getInputStream() -} |