diff options
Diffstat (limited to 'plugins/base/src')
13 files changed, 116 insertions, 26 deletions
diff --git a/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt b/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt index 41dffa07..83a0fc5b 100644 --- a/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt +++ b/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt @@ -4,7 +4,6 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking -import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet import org.jetbrains.dokka.DokkaException import org.jetbrains.dokka.base.DokkaBase import org.jetbrains.dokka.base.resolvers.local.LocationProvider @@ -128,7 +127,7 @@ abstract class DefaultRenderer<T>( open fun T.buildDRILink( node: ContentDRILink, pageContext: ContentPage, - sourceSetRestriction: Set<DokkaSourceSet>? + sourceSetRestriction: Set<DisplaySourceSet>? ) { locationProvider.resolve(node.address, node.sourceSets, pageContext)?.let { address -> buildLink(address) { @@ -140,7 +139,7 @@ abstract class DefaultRenderer<T>( open fun T.buildResolvedLink( node: ContentResolvedLink, pageContext: ContentPage, - sourceSetRestriction: Set<DokkaSourceSet>? + sourceSetRestriction: Set<DisplaySourceSet>? ) { buildLink(node.address) { buildText(node.children, pageContext, sourceSetRestriction) diff --git a/plugins/base/src/main/kotlin/renderers/PackageListService.kt b/plugins/base/src/main/kotlin/renderers/PackageListService.kt index 42c8d66e..cde96290 100644 --- a/plugins/base/src/main/kotlin/renderers/PackageListService.kt +++ b/plugins/base/src/main/kotlin/renderers/PackageListService.kt @@ -22,14 +22,16 @@ class PackageListService(val context: DokkaContext) { fun visit(node: PageNode, parentDris: Set<DRI>) { if (node is PackagePageNode) { - packages.add(node.name) + node.name + .takeUnless { name -> name.startsWith("[") && name.endsWith("]") } // Do not include the package name for declarations without one + ?.let { packages.add(it) } } val contentPage = node.safeAs<ContentPage>() contentPage?.dri?.forEach { if (parentDris.isNotEmpty() && it.parent !in parentDris) { locationProvider.resolve(node) - ?.let { nodeLocation -> nonStandardLocations[it.toString()] = nodeLocation } + ?.let { nodeLocation -> nonStandardLocations[it.toString()] = nodeLocation } ?: context.logger.error("Cannot resolve path for ${node.name}!") } } @@ -52,4 +54,4 @@ class PackageListService(val context: DokkaContext) { companion object { const val DOKKA_PARAM_PREFIX = "\$dokka" } -}
\ No newline at end of file +} diff --git a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt index 0d20e8ac..6c1fd472 100644 --- a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt +++ b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt @@ -6,13 +6,11 @@ import kotlinx.coroutines.runBlocking import kotlinx.html.* import kotlinx.html.stream.createHTML import org.jetbrains.dokka.DokkaSourceSetID -import org.jetbrains.dokka.Platform import org.jetbrains.dokka.base.DokkaBase import org.jetbrains.dokka.base.renderers.DefaultRenderer import org.jetbrains.dokka.base.renderers.TabSortingStrategy import org.jetbrains.dokka.links.DRI import org.jetbrains.dokka.model.DisplaySourceSet -import org.jetbrains.dokka.model.dfs import org.jetbrains.dokka.model.properties.PropertyContainer import org.jetbrains.dokka.model.sourceSetIDs import org.jetbrains.dokka.model.withDescendants @@ -557,7 +555,7 @@ open class HtmlRenderer( from: PageNode? = null, block: FlowContent.() -> Unit ) = locationProvider.resolve(to, platforms.toSet(), from)?.let { buildLink(it, block) } - ?: run { context.logger.error("Cannot resolve path for $to"); block() } + ?: run { context.logger.error("Cannot resolve path for `$to` from `$from`"); block() } override fun buildError(node: ContentNode) { context.logger.error("Unknown ContentNode type: $node") @@ -574,7 +572,7 @@ open class HtmlRenderer( override fun FlowContent.buildDRILink( node: ContentDRILink, pageContext: ContentPage, - sourceSetRestriction: Set<DokkaSourceSet>? + sourceSetRestriction: Set<DisplaySourceSet>? ) = locationProvider.resolve(node.address, node.sourceSets, pageContext)?.let { address -> buildLink(address) { buildText(node.children, pageContext, sourceSetRestriction) @@ -609,7 +607,7 @@ open class HtmlRenderer( override suspend fun renderPage(page: PageNode) { super.renderPage(page) if (page is ContentPage && page !is ModulePageNode && page !is PackagePageNode) - searchbarDataInstaller.processPage(page, locationProvider.resolve(page) ?: context.logger.error("Cannot resolve path for ${page.dri}")) + searchbarDataInstaller.processPage(page, locationProvider.resolve(page) ?: run { context.logger.error("Cannot resolve path for ${page.dri}"); ""}) } override fun FlowContent.buildText(textNode: ContentText) = diff --git a/plugins/base/src/main/kotlin/resolvers/external/DefaultExternalLocationProvider.kt b/plugins/base/src/main/kotlin/resolvers/external/DefaultExternalLocationProvider.kt index 18f52cce..b92b5330 100644 --- a/plugins/base/src/main/kotlin/resolvers/external/DefaultExternalLocationProvider.kt +++ b/plugins/base/src/main/kotlin/resolvers/external/DefaultExternalLocationProvider.kt @@ -10,8 +10,10 @@ open class DefaultExternalLocationProvider( val extension: String, val dokkaContext: DokkaContext ) : ExternalLocationProvider { - override fun resolve(dri: DRI): String? { // TODO: classes without packages? + override fun resolve(dri: DRI): String? { val docURL = externalDocumentation.documentationURL.toString().removeSuffix("/") + "/" + externalDocumentation.packageList.locations[dri.toString()]?.let { path -> return "$docURL$path" } + val classNamesChecked = dri.classNames ?: return "$docURL${dri.packageName ?: ""}/index$extension" val classLink = (listOfNotNull(dri.packageName) + classNamesChecked.split('.')) .joinToString("/", transform = ::identifierToFilename) diff --git a/plugins/base/src/main/kotlin/resolvers/external/DefaultExternalLocationProviderFactory.kt b/plugins/base/src/main/kotlin/resolvers/external/DefaultExternalLocationProviderFactory.kt index bb9fb563..9f8f62da 100644 --- a/plugins/base/src/main/kotlin/resolvers/external/DefaultExternalLocationProviderFactory.kt +++ b/plugins/base/src/main/kotlin/resolvers/external/DefaultExternalLocationProviderFactory.kt @@ -10,7 +10,7 @@ class DefaultExternalLocationProviderFactory(val context: DokkaContext) : override fun getExternalLocationProvider(doc: ExternalDocumentation): ExternalLocationProvider? = when (doc.packageList.linkFormat) { RecognizedLinkFormat.KotlinWebsiteHtml, - RecognizedLinkFormat.DokkaOldHtml, + RecognizedLinkFormat.DokkaOldHtml -> Dokka010ExternalLocationProvider(doc, ".html", context) RecognizedLinkFormat.DokkaHtml -> DefaultExternalLocationProvider(doc, ".html", context) RecognizedLinkFormat.DokkaGFM, RecognizedLinkFormat.DokkaJekyll -> DefaultExternalLocationProvider(doc, ".md", context) diff --git a/plugins/base/src/main/kotlin/resolvers/external/Dokka010ExternalLocationProvider.kt b/plugins/base/src/main/kotlin/resolvers/external/Dokka010ExternalLocationProvider.kt new file mode 100644 index 00000000..33bc96d8 --- /dev/null +++ b/plugins/base/src/main/kotlin/resolvers/external/Dokka010ExternalLocationProvider.kt @@ -0,0 +1,30 @@ +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 + +open class Dokka010ExternalLocationProvider( + val externalDocumentation: ExternalDocumentation, + val extension: String, + val dokkaContext: DokkaContext +) : ExternalLocationProvider { + override fun resolve(dri: DRI): String? { + val docURL = externalDocumentation.documentationURL.toString().removeSuffix("/") + "/" + + val relocationId = + "${dri.packageName}.${dri.classNames}".let { if (dri.callable != null) it + "$" + dri.callable!!.toOldString() else it } + externalDocumentation.packageList.locations[relocationId]?.let { path -> return "$docURL$path" } + + val classNamesChecked = dri.classNames ?: 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 Callable.toOldString() = name + params.joinToString(", ", "(", ")") + receiver?.let { "#$it" } +} diff --git a/plugins/base/src/main/kotlin/resolvers/external/javadoc/JavadocExternalLocationProvider.kt b/plugins/base/src/main/kotlin/resolvers/external/javadoc/JavadocExternalLocationProvider.kt index 48cf554c..60aa540a 100644 --- a/plugins/base/src/main/kotlin/resolvers/external/javadoc/JavadocExternalLocationProvider.kt +++ b/plugins/base/src/main/kotlin/resolvers/external/javadoc/JavadocExternalLocationProvider.kt @@ -15,6 +15,8 @@ class JavadocExternalLocationProvider( override fun resolve(dri: DRI): String? { val docURL = externalDocumentation.documentationURL.toString().removeSuffix("/") + "/" + externalDocumentation.packageList.locations[dri.toString()]?.let { path -> return "$docURL$path" } + val packageLink = dri.packageName?.replace(".", "/") if (dri.classNames == null) { return "$docURL$packageLink/package-summary$extension".htmlEscape() diff --git a/plugins/base/src/main/kotlin/resolvers/external/javadoc/JavadocExternalLocationProviderFactory.kt b/plugins/base/src/main/kotlin/resolvers/external/javadoc/JavadocExternalLocationProviderFactory.kt index 6fe39d35..27e0cd02 100644 --- a/plugins/base/src/main/kotlin/resolvers/external/javadoc/JavadocExternalLocationProviderFactory.kt +++ b/plugins/base/src/main/kotlin/resolvers/external/javadoc/JavadocExternalLocationProviderFactory.kt @@ -14,10 +14,10 @@ class JavadocExternalLocationProviderFactory(val context: DokkaContext) : when (doc.packageList.linkFormat) { RecognizedLinkFormat.Javadoc1 -> JavadocExternalLocationProvider(doc, "()", ", ", context) // Covers JDK 1 - 7 - RecognizedLinkFormat.Javadoc8, - RecognizedLinkFormat.DokkaJavadoc -> + RecognizedLinkFormat.Javadoc8 -> JavadocExternalLocationProvider(doc, "--", "-", context) // Covers JDK 8 - 9 - RecognizedLinkFormat.Javadoc10 -> + 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 index 45b39eec..c25aa543 100644 --- a/plugins/base/src/main/kotlin/resolvers/local/DefaultLocationProvider.kt +++ b/plugins/base/src/main/kotlin/resolvers/local/DefaultLocationProvider.kt @@ -1,13 +1,12 @@ package org.jetbrains.dokka.base.resolvers.local -import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet import org.jetbrains.dokka.base.DokkaBase import org.jetbrains.dokka.base.resolvers.external.ExternalLocationProvider 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.pages.RootPageNode 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 @@ -25,7 +24,7 @@ abstract class DefaultLocationProvider( .sourceSets .flatMap { sourceSet -> sourceSet.externalDocumentationLinks.map { - PackageList.load(it.packageListUrl, sourceSet.jdkVersion, dokkaContext) + PackageList.load(it.packageListUrl, sourceSet.jdkVersion, dokkaContext.configuration.offlineMode) ?.let { packageList -> ExternalDocumentation(it.url, packageList) } } } @@ -35,14 +34,13 @@ abstract class DefaultLocationProvider( val externalLocationProvider = (externalLocationProviderFactories.asSequence() .mapNotNull { it.getExternalLocationProvider(extDocInfo) }.firstOrNull() ?: run { dokkaContext.logger.error("No ExternalLocationProvider for '${extDocInfo.packageList.url}' found"); null }) - run { null } packageName to externalLocationProvider } } .toMap() .filterKeys(String::isNotBlank) - protected open fun getExternalLocation(dri: DRI, sourceSets: Set<DokkaSourceSet>): String? = + protected open fun getExternalLocation(dri: DRI, sourceSets: Set<DisplaySourceSet>): String? = packagesIndex[dri.packageName]?.resolve(dri) } diff --git a/plugins/base/src/main/kotlin/resolvers/local/DokkaLocationProvider.kt b/plugins/base/src/main/kotlin/resolvers/local/DokkaLocationProvider.kt index d2e6d49b..ca2332db 100644 --- a/plugins/base/src/main/kotlin/resolvers/local/DokkaLocationProvider.kt +++ b/plugins/base/src/main/kotlin/resolvers/local/DokkaLocationProvider.kt @@ -1,8 +1,8 @@ package org.jetbrains.dokka.base.resolvers.local -import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet import org.jetbrains.dokka.base.resolvers.anchors.SymbolAnchorHint import org.jetbrains.dokka.links.DRI +import org.jetbrains.dokka.model.DisplaySourceSet import org.jetbrains.dokka.model.withDescendants import org.jetbrains.dokka.pages.* import org.jetbrains.dokka.plugability.DokkaContext @@ -44,7 +44,7 @@ open class DokkaLocationProvider( override fun resolve(node: PageNode, context: PageNode?, skipExtension: Boolean) = pathTo(node, context) + if (!skipExtension) extension else "" - override fun resolve(dri: DRI, sourceSets: Set<DokkaSourceSet>, context: PageNode?) = + override fun resolve(dri: DRI, sourceSets: Set<DisplaySourceSet>, context: PageNode?) = pagesIndex[dri]?.let { resolve(it, context) } ?: anchorsIndex[dri]?.let { resolve(it, context) + "#$dri" } // Not found in PageGraph, that means it's an external link @@ -58,7 +58,7 @@ open class DokkaLocationProvider( 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 current page graph so it is impossible to compute its path" + "${page::class.simpleName}(${page.name}) does not belong to the current page graph so it is impossible to compute its path" ) val contextNode = diff --git a/plugins/base/src/main/kotlin/resolvers/shared/PackageList.kt b/plugins/base/src/main/kotlin/resolvers/shared/PackageList.kt index 819f5f09..e5f88556 100644 --- a/plugins/base/src/main/kotlin/resolvers/shared/PackageList.kt +++ b/plugins/base/src/main/kotlin/resolvers/shared/PackageList.kt @@ -11,8 +11,8 @@ data class PackageList( val url: URL ) { companion object { - fun load(url: URL, jdkVersion: Int, dokkaContext: DokkaContext): PackageList? { - if (dokkaContext.configuration.offlineMode && url.protocol.toLowerCase() != "file") + fun load(url: URL, jdkVersion: Int, offlineMode: Boolean = false): PackageList? { + if (offlineMode && url.protocol.toLowerCase() != "file") return null val packageListStream = url.readContent() diff --git a/plugins/base/src/test/kotlin/locationProvider/Dokka010ExternalLocationProviderTest.kt b/plugins/base/src/test/kotlin/locationProvider/Dokka010ExternalLocationProviderTest.kt new file mode 100644 index 00000000..280fcc24 --- /dev/null +++ b/plugins/base/src/test/kotlin/locationProvider/Dokka010ExternalLocationProviderTest.kt @@ -0,0 +1,52 @@ +package locationProvider + +import org.jetbrains.dokka.base.resolvers.external.Dokka010ExternalLocationProvider +import org.jetbrains.dokka.plugability.DokkaContext +import org.jetbrains.dokka.base.resolvers.shared.ExternalDocumentation +import org.jetbrains.dokka.base.resolvers.shared.PackageList +import org.jetbrains.dokka.links.Callable +import org.jetbrains.dokka.links.DRI +import org.jetbrains.dokka.testApi.testRunner.AbstractCoreTest +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import java.net.URL + +class Dokka010ExternalLocationProviderTest : AbstractCoreTest() { + private val testDataDir = getTestDataDir("locationProvider").toAbsolutePath() + private val kotlinLang = "https://kotlinlang.org/api/latest/jvm/stdlib" + private val packageListURL = URL("file://$testDataDir/old-package-list") + private val configuration = dokkaConfiguration { + sourceSets { + sourceSet { + sourceRoots = listOf("src/") + classpath += jvmStdlibPath!! + externalDocumentationLink(kotlinLang, packageListURL.toString()) + } + } + } + + private fun getTestLocationProvider(context: DokkaContext? = null): Dokka010ExternalLocationProvider { + val dokkaContext = context ?: DokkaContext.create(configuration, logger, emptyList()) + val packageList = PackageList.load(packageListURL, 8, true)!! + val externalDocumentation = + ExternalDocumentation(URL(kotlinLang), packageList) + return Dokka010ExternalLocationProvider(externalDocumentation, ".html", dokkaContext) + } + + @Test + fun `ordinary link`() { + val locationProvider = getTestLocationProvider() + val dri = DRI("kotlin.reflect", "KVisibility") + + assertEquals("$kotlinLang/kotlin.reflect/-k-visibility/index.html", locationProvider.resolve(dri)) + } + + @Test + fun `relocation in package list`() { + val locationProvider = getTestLocationProvider() + val dri = DRI("kotlin.text", "StringBuilder") + + assertEquals("$kotlinLang/kotlin.relocated.text/-string-builder/index.html", locationProvider.resolve(dri)) + } +} diff --git a/plugins/base/src/test/resources/locationProvider/old-package-list b/plugins/base/src/test/resources/locationProvider/old-package-list new file mode 100644 index 00000000..bf47a5bb --- /dev/null +++ b/plugins/base/src/test/resources/locationProvider/old-package-list @@ -0,0 +1,7 @@ +$dokka.format:kotlin-website-html +$dokka.linkExtension:html +$dokka.location:kotlin.text.StringBuilderkotlin.relocated.text/-string-builder/index.html +kotlin +kotlin.text +kotlin.reflect + |