aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBłażej Kardyś <bkardys@virtuslab.com>2020-05-27 01:16:48 +0200
committerBłażej Kardyś <bkardys@virtuslab.com>2020-06-04 11:26:05 +0200
commit6dc9498ca849645ecb4ec923bb7116b245dca706 (patch)
tree23022e6d6f3aea18b9e8efaaa482cafae9bee989
parentb614604effda51ca7c76c8901be78ced62b642b2 (diff)
downloaddokka-6dc9498ca849645ecb4ec923bb7116b245dca706.tar.gz
dokka-6dc9498ca849645ecb4ec923bb7116b245dca706.tar.bz2
dokka-6dc9498ca849645ecb4ec923bb7116b245dca706.zip
All modules page generation
-rw-r--r--.idea/compiler.xml2
-rw-r--r--core/.gitignore2
-rw-r--r--core/src/main/kotlin/CoreExtensions.kt3
-rw-r--r--core/src/main/kotlin/DokkaBootstrapImpl.kt2
-rw-r--r--core/src/main/kotlin/DokkaGenerator.kt25
-rw-r--r--core/src/main/kotlin/DokkaMultimoduleBootstrapImpl.kt25
-rw-r--r--core/src/main/kotlin/configuration.kt7
-rw-r--r--core/src/main/kotlin/defaultConfiguration.kt8
-rw-r--r--core/src/main/kotlin/pages/ContentNodes.kt3
-rw-r--r--core/src/main/kotlin/pages/PageNodes.kt25
-rw-r--r--core/src/main/kotlin/parsers/MarkdownParser.kt22
-rw-r--r--core/src/main/kotlin/transformers/pages/PageCreator.kt8
-rw-r--r--plugins/.gitignore2
-rw-r--r--plugins/base/src/main/kotlin/DokkaBase.kt7
-rw-r--r--plugins/base/src/main/kotlin/allModulePage/MultimodulePageCreator.kt65
-rw-r--r--plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt17
-rw-r--r--plugins/base/src/main/kotlin/resolvers/local/DefaultLocationProviderFactory.kt4
-rw-r--r--plugins/base/src/main/kotlin/resolvers/local/MultimoduleLocationProvider.kt32
-rw-r--r--plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt23
-rw-r--r--plugins/base/src/main/resources/dokka/scripts/main.js2
-rw-r--r--plugins/base/src/main/resources/dokka/scripts/main.js.map2
-rw-r--r--plugins/base/src/test/kotlin/renderers/RenderingOnlyTestBase.kt2
-rw-r--r--runners/cli/src/main/kotlin/cli/main.kt2
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaMultimoduleTask.kt97
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/configurationImplementations.kt7
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/main.kt24
-rw-r--r--runners/maven-plugin/src/main/kotlin/DokkaMojo.kt3
-rw-r--r--testApi/src/main/kotlin/testApi/testRunner/TestRunner.kt3
28 files changed, 387 insertions, 37 deletions
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index a7e03ba2..b87e1115 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -45,6 +45,8 @@
<module name="dokka.integration.main" target="1.8" />
<module name="dokka.integration.test" target="1.8" />
<module name="dokka.plugins.base.main" target="1.8" />
+ <module name="dokka.plugins.base.search-component.main" target="1.8" />
+ <module name="dokka.plugins.base.search-component.test" target="1.8" />
<module name="dokka.plugins.base.test" target="1.8" />
<module name="dokka.plugins.gfm.main" target="1.8" />
<module name="dokka.plugins.gfm.test" target="1.8" />
diff --git a/core/.gitignore b/core/.gitignore
index afd3caa6..1e1b410b 100644
--- a/core/.gitignore
+++ b/core/.gitignore
@@ -1,3 +1 @@
-src/main/resources/dokka/scripts/main.js
-src/main/resources/dokka/scripts/main.js.map
src/main/resources/dokka/scripts/*.svg \ No newline at end of file
diff --git a/core/src/main/kotlin/CoreExtensions.kt b/core/src/main/kotlin/CoreExtensions.kt
index 7b4c9baa..b8689154 100644
--- a/core/src/main/kotlin/CoreExtensions.kt
+++ b/core/src/main/kotlin/CoreExtensions.kt
@@ -6,6 +6,7 @@ import org.jetbrains.dokka.transformers.documentation.DocumentableMerger
import org.jetbrains.dokka.transformers.documentation.DocumentableToPageTranslator
import org.jetbrains.dokka.transformers.documentation.DocumentableTransformer
import org.jetbrains.dokka.transformers.documentation.PreMergeDocumentableTransformer
+import org.jetbrains.dokka.transformers.pages.PageCreator
import org.jetbrains.dokka.transformers.pages.PageTransformer
import org.jetbrains.dokka.transformers.sources.SourceToDocumentableTranslator
import kotlin.reflect.KProperty
@@ -16,7 +17,9 @@ object CoreExtensions {
val documentableMerger by coreExtension<DocumentableMerger>()
val documentableTransformer by coreExtension<DocumentableTransformer>()
val documentableToPageTranslator by coreExtension<DocumentableToPageTranslator>()
+ val allModulePageCreator by coreExtension<PageCreator>()
val pageTransformer by coreExtension<PageTransformer>()
+ val allModulePageTransformer by coreExtension<PageTransformer>()
val renderer by coreExtension<Renderer>()
private fun <T : Any> coreExtension() = object {
diff --git a/core/src/main/kotlin/DokkaBootstrapImpl.kt b/core/src/main/kotlin/DokkaBootstrapImpl.kt
index f164a3c1..56e837fc 100644
--- a/core/src/main/kotlin/DokkaBootstrapImpl.kt
+++ b/core/src/main/kotlin/DokkaBootstrapImpl.kt
@@ -32,7 +32,7 @@ fun parsePerPackageOptions(arg: String): List<PackageOptions> {
class DokkaBootstrapImpl : DokkaBootstrap {
- private class DokkaProxyLogger(val consumer: BiConsumer<String, String>) : DokkaLogger {
+ class DokkaProxyLogger(val consumer: BiConsumer<String, String>) : DokkaLogger {
override var warningsCount: Int = 0
override var errorsCount: Int = 0
diff --git a/core/src/main/kotlin/DokkaGenerator.kt b/core/src/main/kotlin/DokkaGenerator.kt
index 6e62c033..7f90fe9a 100644
--- a/core/src/main/kotlin/DokkaGenerator.kt
+++ b/core/src/main/kotlin/DokkaGenerator.kt
@@ -60,6 +60,22 @@ class DokkaGenerator(
logger.report()
}.dump("\n\n === TIME MEASUREMENT ===\n")
+ fun generateAllModulesPage() = timed {
+ val sourceSetsCache = SourceSetCache()
+ val sourceSets = emptyMap<SourceSetData, EnvironmentAndFacade>()
+ report("Initializing plugins")
+ val context = initializePlugins(configuration, logger, sourceSets, sourceSetsCache)
+
+ report("Creating all modules page")
+ val pages = createAllModulePage(context)
+
+ report("Transforming pages")
+ val transformedPages = transformAllModulesPage(pages, context)
+
+ report("Rendering")
+ render(transformedPages, context)
+ }.dump("\n\n === TIME MEASUREMENT ===\n")
+
fun setUpAnalysis(
configuration: DokkaConfiguration,
sourceSetsCache: SourceSetCache
@@ -101,11 +117,20 @@ class DokkaGenerator(
context: DokkaContext
) = context.single(CoreExtensions.documentableToPageTranslator).invoke(transformedDocumentation)
+ fun createAllModulePage(
+ context: DokkaContext
+ ) = context.single(CoreExtensions.allModulePageCreator).invoke()
+
fun transformPages(
pages: RootPageNode,
context: DokkaContext
) = context[CoreExtensions.pageTransformer].fold(pages) { acc, t -> t(acc) }
+ fun transformAllModulesPage(
+ pages: RootPageNode,
+ context: DokkaContext
+ ) = context[CoreExtensions.allModulePageTransformer].fold(pages) { acc, t -> t(acc) }
+
fun render(
transformedPages: RootPageNode,
context: DokkaContext
diff --git a/core/src/main/kotlin/DokkaMultimoduleBootstrapImpl.kt b/core/src/main/kotlin/DokkaMultimoduleBootstrapImpl.kt
new file mode 100644
index 00000000..6825ce64
--- /dev/null
+++ b/core/src/main/kotlin/DokkaMultimoduleBootstrapImpl.kt
@@ -0,0 +1,25 @@
+package org.jetbrains.dokka
+
+import com.google.gson.Gson
+import org.jetbrains.dokka.DokkaBootstrapImpl.DokkaProxyLogger
+import org.jetbrains.dokka.utilities.DokkaLogger
+import java.util.function.BiConsumer
+
+class DokkaMultimoduleBootstrapImpl : DokkaBootstrap {
+
+ private lateinit var generator: DokkaGenerator
+
+ fun configure(logger: DokkaLogger, configuration: DokkaConfiguration) {
+ generator = DokkaGenerator(configuration, logger)
+ }
+
+ override fun configure(logger: BiConsumer<String, String>, serializedConfigurationJSON: String) = configure(
+ DokkaProxyLogger(logger),
+ Gson().fromJson(serializedConfigurationJSON, DokkaConfigurationImpl::class.java)
+ )
+
+ override fun generate() {
+ generator.generateAllModulesPage()
+ }
+
+} \ No newline at end of file
diff --git a/core/src/main/kotlin/configuration.kt b/core/src/main/kotlin/configuration.kt
index e74d10d7..c38d0234 100644
--- a/core/src/main/kotlin/configuration.kt
+++ b/core/src/main/kotlin/configuration.kt
@@ -30,6 +30,7 @@ interface DokkaConfiguration {
val generateIndexPages: Boolean
val cacheRoot: String?
val passesConfigurations: List<PassConfiguration>
+ val modules: List<DokkaModuleDescription>
val impliedPlatforms: List<String>
val pluginsClasspath: List<File>
val pluginsConfiguration: Map<String, String>
@@ -73,6 +74,12 @@ interface DokkaConfiguration {
val lineSuffix: String?
}
+ interface DokkaModuleDescription {
+ val name: String
+ val path: String
+ val docFile: String
+ }
+
interface PackageOptions {
val prefix: String
val includeNonPublic: Boolean
diff --git a/core/src/main/kotlin/defaultConfiguration.kt b/core/src/main/kotlin/defaultConfiguration.kt
index 9f36606a..acfa55d4 100644
--- a/core/src/main/kotlin/defaultConfiguration.kt
+++ b/core/src/main/kotlin/defaultConfiguration.kt
@@ -11,7 +11,8 @@ data class DokkaConfigurationImpl(
override val impliedPlatforms: List<String>,
override val passesConfigurations: List<PassConfigurationImpl>,
override val pluginsClasspath: List<File>,
- override val pluginsConfiguration: Map<String, String>
+ override val pluginsConfiguration: Map<String, String>,
+ override val modules: List<DokkaModuleDescriptionImpl>
) : DokkaConfiguration
data class PassConfigurationImpl (
@@ -43,6 +44,11 @@ data class PassConfigurationImpl (
override val sinceKotlin: String?
) : DokkaConfiguration.PassConfiguration
+data class DokkaModuleDescriptionImpl(
+ override val name: String,
+ override val path: String,
+ override val docFile: String
+): DokkaConfiguration.DokkaModuleDescription
data class SourceRootImpl(
override val path: String
diff --git a/core/src/main/kotlin/pages/ContentNodes.kt b/core/src/main/kotlin/pages/ContentNodes.kt
index 7b702841..95b7b371 100644
--- a/core/src/main/kotlin/pages/ContentNodes.kt
+++ b/core/src/main/kotlin/pages/ContentNodes.kt
@@ -46,7 +46,6 @@ data class ContentHeader(
override val extra: PropertyContainer<ContentNode> = PropertyContainer.empty()
) : ContentComposite {
constructor(level: Int, c: ContentComposite) : this(c.children, level, c.dci, c.sourceSets, c.style, c.extra)
-
override fun withNewExtras(newExtras: PropertyContainer<ContentNode>): ContentHeader = copy(extra = newExtras)
}
@@ -226,6 +225,8 @@ enum class ContentStyle : Style {
object CommentTable: Style
+object MultimoduleTable: Style
+
fun ContentNode.dfs(predicate: (ContentNode) -> Boolean): ContentNode? = if (predicate(this)) {
this
} else {
diff --git a/core/src/main/kotlin/pages/PageNodes.kt b/core/src/main/kotlin/pages/PageNodes.kt
index 32b2846e..b28e36d6 100644
--- a/core/src/main/kotlin/pages/PageNodes.kt
+++ b/core/src/main/kotlin/pages/PageNodes.kt
@@ -163,6 +163,31 @@ fun PageNode.asSequence(): Sequence<PageNode> = sequence {
children.asSequence().flatMap { it.asSequence() }.forEach { yield(it) }
}
+class MultimoduleRootPageNode(
+ override val name: String,
+ override val dri: Set<DRI>,
+ override val content: ContentNode,
+ override val embeddedResources: List<String> = emptyList()
+) : RootPageNode(), ContentPage {
+
+ override val children: List<PageNode> = emptyList()
+
+ override val documentable: Documentable? = null
+
+ override fun modified(name: String, children: List<PageNode>): RootPageNode =
+ MultimoduleRootPageNode(name, dri, content, embeddedResources)
+
+ override fun modified(
+ name: String,
+ content: ContentNode,
+ dri: Set<DRI>,
+ embeddedResources: List<String>,
+ children: List<PageNode>
+ ) =
+ if (name == this.name && content === this.content && embeddedResources === this.embeddedResources && children shallowEq this.children) this
+ else MultimoduleRootPageNode(name, dri, content, embeddedResources)
+}
+
inline fun <reified T: PageNode> PageNode.children() = children.filterIsInstance<T>()
private infix fun <T> List<T>.shallowEq(other: List<T>) =
diff --git a/core/src/main/kotlin/parsers/MarkdownParser.kt b/core/src/main/kotlin/parsers/MarkdownParser.kt
index 145e085c..308a8fb6 100644
--- a/core/src/main/kotlin/parsers/MarkdownParser.kt
+++ b/core/src/main/kotlin/parsers/MarkdownParser.kt
@@ -25,8 +25,8 @@ import java.net.MalformedURLException
import org.intellij.markdown.parser.MarkdownParser as IntellijMarkdownParser
class MarkdownParser(
- private val resolutionFacade: DokkaResolutionFacade,
- private val declarationDescriptor: DeclarationDescriptor,
+ private val resolutionFacade: DokkaResolutionFacade? = null,
+ private val declarationDescriptor: DeclarationDescriptor? = null,
private val logger: DokkaLogger
) : Parser() {
@@ -110,13 +110,15 @@ class MarkdownParser(
null
} catch (e: MalformedURLException) {
try {
- resolveKDocLink(
- resolutionFacade.resolveSession.bindingContext,
- resolutionFacade,
- declarationDescriptor,
- null,
- link.split('.')
- ).minBy { it is ClassDescriptor }?.let { DRI.from(it) }
+ if (resolutionFacade != null && declarationDescriptor != null) {
+ resolveKDocLink(
+ resolutionFacade.resolveSession.bindingContext,
+ resolutionFacade,
+ declarationDescriptor,
+ null,
+ link.split('.')
+ ).minBy { it is ClassDescriptor }?.let { DRI.from(it) }
+ } else null
} catch (e1: IllegalArgumentException) {
null
}
@@ -394,7 +396,7 @@ class MarkdownParser(
parseStringToDocNode("[${it.getSubjectName()}]")
.let {
val link = it.children[0]
- if(link is DocumentationLink) link.dri
+ if (link is DocumentationLink) link.dri
else null
}
)
diff --git a/core/src/main/kotlin/transformers/pages/PageCreator.kt b/core/src/main/kotlin/transformers/pages/PageCreator.kt
new file mode 100644
index 00000000..f74b5efa
--- /dev/null
+++ b/core/src/main/kotlin/transformers/pages/PageCreator.kt
@@ -0,0 +1,8 @@
+package org.jetbrains.dokka.transformers.pages
+
+import org.jetbrains.dokka.pages.RootPageNode
+import org.jetbrains.dokka.plugability.DokkaContext
+
+interface PageCreator {
+ operator fun invoke(): RootPageNode
+} \ No newline at end of file
diff --git a/plugins/.gitignore b/plugins/.gitignore
new file mode 100644
index 00000000..b9e934b8
--- /dev/null
+++ b/plugins/.gitignore
@@ -0,0 +1,2 @@
+base/src/main/resources/dokka/scripts/main.js
+base/src/main/resources/dokka/scripts/main.js.map \ No newline at end of file
diff --git a/plugins/base/src/main/kotlin/DokkaBase.kt b/plugins/base/src/main/kotlin/DokkaBase.kt
index f217bbf1..c99372af 100644
--- a/plugins/base/src/main/kotlin/DokkaBase.kt
+++ b/plugins/base/src/main/kotlin/DokkaBase.kt
@@ -1,6 +1,7 @@
package org.jetbrains.dokka.base
import org.jetbrains.dokka.CoreExtensions
+import org.jetbrains.dokka.base.allModulePage.MultimodulePageCreator
import org.jetbrains.dokka.base.renderers.*
import org.jetbrains.dokka.base.renderers.html.*
import org.jetbrains.dokka.base.signatures.KotlinSignatureProvider
@@ -177,5 +178,9 @@ class DokkaBase : DokkaPlugin() {
htmlPreprocessors providing ::SourcesetDependencyAppender order { after(rootCreator)}
}
-
+ val allModulePageCreators by extending {
+ CoreExtensions.allModulePageCreator providing {
+ MultimodulePageCreator(it)
+ }
+ }
} \ No newline at end of file
diff --git a/plugins/base/src/main/kotlin/allModulePage/MultimodulePageCreator.kt b/plugins/base/src/main/kotlin/allModulePage/MultimodulePageCreator.kt
new file mode 100644
index 00000000..ea1d8510
--- /dev/null
+++ b/plugins/base/src/main/kotlin/allModulePage/MultimodulePageCreator.kt
@@ -0,0 +1,65 @@
+package org.jetbrains.dokka.base.allModulePage
+
+import org.jetbrains.dokka.base.DokkaBase
+import org.jetbrains.dokka.base.resolvers.local.MultimoduleLocationProvider.Companion.MULTIMODULE_PACKAGE_PLACEHOLDER
+import org.jetbrains.dokka.base.transformers.pages.comments.DocTagToContentConverter
+import org.jetbrains.dokka.base.translators.documentables.PageContentBuilder
+import org.jetbrains.dokka.links.DRI
+import org.jetbrains.dokka.model.SourceSetData
+import org.jetbrains.dokka.model.doc.DocumentationNode
+import org.jetbrains.dokka.model.doc.P
+import org.jetbrains.dokka.pages.*
+import org.jetbrains.dokka.parsers.MarkdownParser
+import org.jetbrains.dokka.plugability.DokkaContext
+import org.jetbrains.dokka.plugability.querySingle
+import org.jetbrains.dokka.transformers.pages.PageCreator
+import org.jetbrains.dokka.utilities.DokkaLogger
+import java.io.File
+
+class MultimodulePageCreator(
+ val context: DokkaContext
+) : PageCreator {
+ private val logger: DokkaLogger = context.logger
+
+ override fun invoke(): RootPageNode {
+ val parser = MarkdownParser(logger = logger)
+ val modules = context.configuration.modules
+
+ val commentsConverter = context.plugin(DokkaBase::class)?.querySingle { commentsToContentConverter }
+ val signatureProvider = context.plugin(DokkaBase::class)?.querySingle { signatureProvider }
+ if (commentsConverter == null || signatureProvider == null)
+ throw IllegalStateException("Both comments converter and signature provider must not be null")
+
+ val sourceSetData = emptySet<SourceSetData>()
+ val builder = PageContentBuilder(commentsConverter, signatureProvider, context.logger)
+ val contentNode = builder.contentFor(dri = DRI(MULTIMODULE_PACKAGE_PLACEHOLDER), kind = ContentKind.Cover, sourceSets = sourceSetData) {
+ header(2, "All modules:")
+ table(styles = setOf(MultimoduleTable)) {
+ modules.mapNotNull { module ->
+ val paragraph = module.docFile.let(::File).readText().let { parser.parse(it).firstParagraph() }
+ paragraph?.let {
+ val dri = DRI(packageName = MULTIMODULE_PACKAGE_PLACEHOLDER, classNames = module.name)
+ val dci = DCI(setOf(dri), ContentKind.Main)
+ val header =
+ ContentHeader(listOf(linkNode(module.name, dri)), 2, dci, emptySet(), emptySet())
+ val content = ContentGroup(
+ DocTagToContentConverter.buildContent(it, dci, emptySet()),
+ dci,
+ emptySet(),
+ emptySet()
+ )
+ ContentGroup(listOf(header, content), dci, emptySet(), emptySet())
+ }
+ }
+ }
+ }
+ return MultimoduleRootPageNode(
+ "Modules",
+ setOf(DRI(packageName = MULTIMODULE_PACKAGE_PLACEHOLDER, classNames = "allModules")),
+ contentNode
+ )
+ }
+
+ private fun DocumentationNode.firstParagraph() =
+ this.children.flatMap { it.root.children }.filterIsInstance<P>().firstOrNull()
+} \ 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 e73a36b2..76a52a83 100644
--- a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt
+++ b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt
@@ -265,7 +265,8 @@ open class HtmlRenderer(
private fun FlowContent.buildRow(
node: ContentGroup,
pageContext: ContentPage,
- sourceSetRestriction: Set<SourceSetData>?
+ sourceSetRestriction: Set<SourceSetData>?,
+ style: Set<Style>
) {
node.children
.filter { sourceSetRestriction == null || it.sourceSets.any { s -> s in sourceSetRestriction } }
@@ -273,11 +274,13 @@ open class HtmlRenderer(
?.let {
withAnchor(node.dci.dri.first().toString()) {
div(classes = "table-row") {
- attributes["data-filterable-current"] = node.sourceSets.joinToString(" ") {
- it.sourceSetName
- }
- attributes["data-filterable-set"] = node.sourceSets.joinToString(" ") {
- it.sourceSetName
+ if (!style.contains(MultimoduleTable)) {
+ attributes["data-filterable-current"] = node.sourceSets.joinToString(" ") {
+ it.sourceSetName
+ }
+ attributes["data-filterable-set"] = node.sourceSets.joinToString(" ") {
+ it.sourceSetName
+ }
}
it.filterIsInstance<ContentLink>().takeIf { it.isNotEmpty() }?.let {
div("main-subrow " + node.style.joinToString(" ")) {
@@ -344,7 +347,7 @@ open class HtmlRenderer(
else -> div(classes = "table") {
node.extra.extraHtmlAttributes().forEach { attributes[it.extraKey] = it.extraValue }
node.children.forEach {
- buildRow(it, pageContext, sourceSetRestriction)
+ buildRow(it, pageContext, sourceSetRestriction, node.style)
}
}
}
diff --git a/plugins/base/src/main/kotlin/resolvers/local/DefaultLocationProviderFactory.kt b/plugins/base/src/main/kotlin/resolvers/local/DefaultLocationProviderFactory.kt
index 57f53ba6..1918472b 100644
--- a/plugins/base/src/main/kotlin/resolvers/local/DefaultLocationProviderFactory.kt
+++ b/plugins/base/src/main/kotlin/resolvers/local/DefaultLocationProviderFactory.kt
@@ -1,10 +1,12 @@
package org.jetbrains.dokka.base.resolvers.local
+import org.jetbrains.dokka.pages.MultimoduleRootPageNode
import org.jetbrains.dokka.pages.RootPageNode
import org.jetbrains.dokka.plugability.DokkaContext
class DefaultLocationProviderFactory(private val context: DokkaContext) : LocationProviderFactory {
override fun getLocationProvider(pageNode: RootPageNode) =
- DefaultLocationProvider(pageNode, context)
+ if (pageNode.children.first() is MultimoduleRootPageNode) MultimoduleLocationProvider(pageNode, context)
+ else DefaultLocationProvider(pageNode, context)
} \ No newline at end of file
diff --git a/plugins/base/src/main/kotlin/resolvers/local/MultimoduleLocationProvider.kt b/plugins/base/src/main/kotlin/resolvers/local/MultimoduleLocationProvider.kt
new file mode 100644
index 00000000..21692bf9
--- /dev/null
+++ b/plugins/base/src/main/kotlin/resolvers/local/MultimoduleLocationProvider.kt
@@ -0,0 +1,32 @@
+package org.jetbrains.dokka.base.resolvers.local
+
+import org.jetbrains.dokka.links.DRI
+import org.jetbrains.dokka.model.SourceSetData
+import org.jetbrains.dokka.pages.PageNode
+import org.jetbrains.dokka.pages.RootPageNode
+import org.jetbrains.dokka.plugability.DokkaContext
+
+class MultimoduleLocationProvider(private val root: RootPageNode, context: DokkaContext) : LocationProvider {
+
+ val defaultLocationProvider = DefaultLocationProvider(root, context)
+
+ val paths = context.configuration.modules.map {
+ it.name to it.path
+ }.toMap()
+
+ override fun resolve(dri: DRI, platforms: List<SourceSetData>, context: PageNode?): String =
+ dri.takeIf { it.packageName == MULTIMODULE_PACKAGE_PLACEHOLDER }?.classNames?.let { paths[it] }?.let {
+ "$it/${dri.classNames}/index.html"
+ } ?: defaultLocationProvider.resolve(dri, platforms, context)
+
+ override fun resolve(node: PageNode, context: PageNode?, skipExtension: Boolean): String =
+ defaultLocationProvider.resolve(node, context, skipExtension)
+
+ override fun resolveRoot(node: PageNode): String = defaultLocationProvider.resolveRoot(node)
+
+ override fun ancestors(node: PageNode): List<PageNode> = listOf(root)
+
+ companion object {
+ const val MULTIMODULE_PACKAGE_PLACEHOLDER = ".ext"
+ }
+} \ No newline at end of file
diff --git a/plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt b/plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt
index 5ff5a954..b670626a 100644
--- a/plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt
+++ b/plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt
@@ -100,7 +100,7 @@ open class PageContentBuilder(
kind,
styles,
extra + SimpleAttr("anchor", text.replace("\\s".toRegex(), "").toLowerCase())
- ){
+ ) {
text(text)
block()
}
@@ -206,14 +206,23 @@ open class PageContentBuilder(
styles: Set<Style> = mainStyles,
extra: PropertyContainer<ContentNode> = mainExtra
) {
- contents += ContentDRILink(
- listOf(createText(text, kind, sourceSets, styles, extra)),
- address,
- DCI(mainDRI, kind),
- sourceSets
- )
+ contents += linkNode(text, address, kind, sourceSets, styles, extra)
}
+ fun linkNode(
+ text: String,
+ address: DRI,
+ kind: Kind = ContentKind.Main,
+ sourceSets: Set<SourceSetData> = mainPlatformData,
+ styles: Set<Style> = mainStyles,
+ extra: PropertyContainer<ContentNode> = mainExtra
+ ) = ContentDRILink(
+ listOf(createText(text, kind, sourceSets, styles, extra)),
+ address,
+ DCI(mainDRI, kind),
+ sourceSets
+ )
+
fun link(
text: String,
address: String,
diff --git a/plugins/base/src/main/resources/dokka/scripts/main.js b/plugins/base/src/main/resources/dokka/scripts/main.js
index f510ca2d..88e7b504 100644
--- a/plugins/base/src/main/resources/dokka/scripts/main.js
+++ b/plugins/base/src/main/resources/dokka/scripts/main.js
@@ -55,5 +55,5 @@ object-assign
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
- */var r,o,i,a,l;if("undefined"==typeof window||"function"!=typeof MessageChannel){var c=null,s=null,u=function(){if(null!==c)try{var e=t.unstable_now();c(!0,e),c=null}catch(e){throw setTimeout(u,0),e}},f=Date.now();t.unstable_now=function(){return Date.now()-f},r=function(e){null!==c?setTimeout(r,0,e):(c=e,setTimeout(u,0))},o=function(e,t){s=setTimeout(e,t)},i=function(){clearTimeout(s)},a=function(){return!1},l=t.unstable_forceFrameRate=function(){}}else{var p=window.performance,d=window.Date,h=window.setTimeout,v=window.clearTimeout;if("undefined"!=typeof console){var g=window.cancelAnimationFrame;"function"!=typeof window.requestAnimationFrame&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"),"function"!=typeof g&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills")}if("object"==typeof p&&"function"==typeof p.now)t.unstable_now=function(){return p.now()};else{var m=d.now();t.unstable_now=function(){return d.now()-m}}var y=!1,b=null,w=-1,_=5,x=0;a=function(){return t.unstable_now()>=x},l=function(){},t.unstable_forceFrameRate=function(e){0>e||125<e?console.error("forceFrameRate takes a positive int between 0 and 125, forcing framerates higher than 125 fps is not unsupported"):_=0<e?Math.floor(1e3/e):5};var S=new MessageChannel,k=S.port2;S.port1.onmessage=function(){if(null!==b){var e=t.unstable_now();x=e+_;try{b(!0,e)?k.postMessage(null):(y=!1,b=null)}catch(e){throw k.postMessage(null),e}}else y=!1},r=function(e){b=e,y||(y=!0,k.postMessage(null))},o=function(e,n){w=h((function(){e(t.unstable_now())}),n)},i=function(){v(w),w=-1}}function O(e,t){var n=e.length;e.push(t);e:for(;;){var r=n-1>>>1,o=e[r];if(!(void 0!==o&&0<T(o,t)))break e;e[r]=t,e[n]=o,n=r}}function z(e){return void 0===(e=e[0])?null:e}function E(e){var t=e[0];if(void 0!==t){var n=e.pop();if(n!==t){e[0]=n;e:for(var r=0,o=e.length;r<o;){var i=2*(r+1)-1,a=e[i],l=i+1,c=e[l];if(void 0!==a&&0>T(a,n))void 0!==c&&0>T(c,a)?(e[r]=c,e[l]=n,r=l):(e[r]=a,e[i]=n,r=i);else{if(!(void 0!==c&&0>T(c,n)))break e;e[r]=c,e[l]=n,r=l}}}return t}return null}function T(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}var C=[],M=[],P=1,I=null,A=3,L=!1,R=!1,H=!1;function j(e){for(var t=z(M);null!==t;){if(null===t.callback)E(M);else{if(!(t.startTime<=e))break;E(M),t.sortIndex=t.expirationTime,O(C,t)}t=z(M)}}function N(e){if(H=!1,j(e),!R)if(null!==z(C))R=!0,r(F);else{var t=z(M);null!==t&&o(N,t.startTime-e)}}function F(e,n){R=!1,H&&(H=!1,i()),L=!0;var r=A;try{for(j(n),I=z(C);null!==I&&(!(I.expirationTime>n)||e&&!a());){var l=I.callback;if(null!==l){I.callback=null,A=I.priorityLevel;var c=l(I.expirationTime<=n);n=t.unstable_now(),"function"==typeof c?I.callback=c:I===z(C)&&E(C),j(n)}else E(C);I=z(C)}if(null!==I)var s=!0;else{var u=z(M);null!==u&&o(N,u.startTime-n),s=!1}return s}finally{I=null,A=r,L=!1}}function V(e){switch(e){case 1:return-1;case 2:return 250;case 5:return 1073741823;case 4:return 1e4;default:return 5e3}}var B=l;t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_continueExecution=function(){R||L||(R=!0,r(F))},t.unstable_getCurrentPriorityLevel=function(){return A},t.unstable_getFirstCallbackNode=function(){return z(C)},t.unstable_next=function(e){switch(A){case 1:case 2:case 3:var t=3;break;default:t=A}var n=A;A=t;try{return e()}finally{A=n}},t.unstable_pauseExecution=function(){},t.unstable_requestPaint=B,t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=A;A=e;try{return t()}finally{A=n}},t.unstable_scheduleCallback=function(e,n,a){var l=t.unstable_now();if("object"==typeof a&&null!==a){var c=a.delay;c="number"==typeof c&&0<c?l+c:l,a="number"==typeof a.timeout?a.timeout:V(e)}else a=V(e),c=l;return e={id:P++,callback:n,priorityLevel:e,startTime:c,expirationTime:a=c+a,sortIndex:-1},c>l?(e.sortIndex=c,O(M,e),null===z(C)&&e===z(M)&&(H?i():H=!0,o(N,c-l))):(e.sortIndex=a,O(C,e),R||L||(R=!0,r(F))),e},t.unstable_shouldYield=function(){var e=t.unstable_now();j(e);var n=z(C);return n!==I&&null!==I&&null!==n&&null!==n.callback&&n.startTime<=e&&n.expirationTime<I.expirationTime||a()},t.unstable_wrapCallback=function(e){var t=A;return function(){var n=A;A=t;try{return e.apply(this,arguments)}finally{A=n}}}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.__RewireAPI__=t.__ResetDependency__=t.__set__=t.__Rewire__=t.__GetDependency__=t.__get__=t.RedBoxError=void 0;var r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},o=function(e,t){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return function(e,t){var n=[],r=!0,o=!1,i=void 0;tr