aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/src/main/kotlin/CoreExtensions.kt44
-rw-r--r--core/src/main/kotlin/DokkaGenerator.kt143
-rw-r--r--core/src/main/kotlin/DokkaMultimoduleBootstrapImpl.kt29
-rw-r--r--core/src/main/kotlin/generation/Generation.kt15
-rw-r--r--core/src/main/kotlin/generation/SingleModule.kt0
-rw-r--r--core/src/main/kotlin/generation/SingleModuleGeneration.kt124
-rw-r--r--core/src/main/kotlin/plugability/DokkaContext.kt2
-rw-r--r--core/src/main/kotlin/plugability/extensions.kt2
-rw-r--r--core/test-api/src/main/kotlin/testApi/testRunner/DokkaTestGenerator.kt24
-rw-r--r--plugins/all-module-page/build.gradle.kts9
-rw-r--r--plugins/all-module-page/src/main/kotlin/AllModulesPageGeneration.kt31
-rw-r--r--plugins/all-module-page/src/main/kotlin/AllModulesPagePlugin.kt25
-rw-r--r--plugins/all-module-page/src/main/kotlin/MultimoduleLocationProvider.kt41
-rw-r--r--plugins/all-module-page/src/main/kotlin/MultimodulePageCreator.kt (renamed from plugins/base/src/main/kotlin/allModulePage/MultimodulePageCreator.kt)2
-rw-r--r--plugins/all-module-page/src/main/resources/META-INF/services/org.jetbrains.dokka.plugability.DokkaPlugin1
-rw-r--r--plugins/base/src/main/kotlin/DokkaBase.kt7
-rw-r--r--plugins/base/src/main/kotlin/parsers/moduleAndPackage/ModuleAndPackageDocumentation.kt2
-rw-r--r--plugins/base/src/main/kotlin/parsers/moduleAndPackage/ModuleAndPackageDocumentationFragment.kt2
-rw-r--r--plugins/base/src/main/kotlin/parsers/moduleAndPackage/ModuleAndPackageDocumentationParsingContext.kt4
-rw-r--r--plugins/base/src/main/kotlin/parsers/moduleAndPackage/ModuleAndPackageDocumentationSource.kt2
-rw-r--r--plugins/base/src/main/kotlin/parsers/moduleAndPackage/parseModuleAndPackageDocumentation.kt2
-rw-r--r--plugins/base/src/main/kotlin/parsers/moduleAndPackage/parseModuleAndPackageDocumentationFragments.kt4
-rw-r--r--plugins/base/src/main/kotlin/resolvers/local/DokkaLocationProvider.kt4
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaArtifacts.kt1
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleTask.kt3
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/main.kt1
-rw-r--r--settings.gradle.kts1
27 files changed, 318 insertions, 207 deletions
diff --git a/core/src/main/kotlin/CoreExtensions.kt b/core/src/main/kotlin/CoreExtensions.kt
index f5fb7604..0eea416a 100644
--- a/core/src/main/kotlin/CoreExtensions.kt
+++ b/core/src/main/kotlin/CoreExtensions.kt
@@ -1,6 +1,9 @@
package org.jetbrains.dokka
-import org.jetbrains.dokka.plugability.ExtensionPoint
+import org.jetbrains.dokka.generation.Generation
+import org.jetbrains.dokka.generation.SingleModuleGeneration
+import org.jetbrains.dokka.plugability.*
+import org.jetbrains.dokka.plugability.LazyEvaluated
import org.jetbrains.dokka.renderers.Renderer
import org.jetbrains.dokka.transformers.documentation.DocumentableMerger
import org.jetbrains.dokka.transformers.documentation.DocumentableToPageTranslator
@@ -13,19 +16,36 @@ import org.jetbrains.dokka.validity.PreGenerationChecker
import kotlin.reflect.KProperty
object CoreExtensions {
- val preGenerationCheck by coreExtension<PreGenerationChecker>()
- val sourceToDocumentableTranslator by coreExtension<SourceToDocumentableTranslator>()
- val preMergeDocumentableTransformer by coreExtension<PreMergeDocumentableTransformer>()
- 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 val extensionDelegates = mutableListOf<Lazy<Extension<*, *, *>>>()
- private fun <T : Any> coreExtension() = object {
+ val preGenerationCheck by coreExtensionPoint<PreGenerationChecker>()
+ val generation by coreExtensionPoint<Generation>()
+ val sourceToDocumentableTranslator by coreExtensionPoint<SourceToDocumentableTranslator>()
+ val preMergeDocumentableTransformer by coreExtensionPoint<PreMergeDocumentableTransformer>()
+ val documentableMerger by coreExtensionPoint<DocumentableMerger>()
+ val documentableTransformer by coreExtensionPoint<DocumentableTransformer>()
+ val documentableToPageTranslator by coreExtensionPoint<DocumentableToPageTranslator>()
+ val allModulePageCreator by coreExtensionPoint<PageCreator>()
+ val pageTransformer by coreExtensionPoint<PageTransformer>()
+ val allModulePageTransformer by coreExtensionPoint<PageTransformer>()
+ val renderer by coreExtensionPoint<Renderer>()
+
+ val singleGeneration by generation extendWith LazyEvaluated.fromRecipe(::SingleModuleGeneration)
+
+ private fun <T : Any> coreExtensionPoint() = object {
operator fun provideDelegate(thisRef: CoreExtensions, property: KProperty<*>): Lazy<ExtensionPoint<T>> =
lazy { ExtensionPoint<T>(thisRef::class.qualifiedName!!, property.name) }
}
+
+ private infix fun <T: Any> ExtensionPoint<T>.extendWith(action: LazyEvaluated<T>) = object {
+ operator fun provideDelegate(thisRef: CoreExtensions, property: KProperty<*>): Lazy<Extension<T, OrderingKind.None, OverrideKind.None>> =
+ lazy { Extension(this@extendWith, thisRef::class.qualifiedName!!, property.name, action) }
+ .also { extensionDelegates += it }
+ }
+
+ internal fun installTo(context: DokkaContextConfiguration) {
+ extensionDelegates.forEach {
+ context.installExtension(it.value)
+ }
+ }
} \ No newline at end of file
diff --git a/core/src/main/kotlin/DokkaGenerator.kt b/core/src/main/kotlin/DokkaGenerator.kt
index b3d58439..947fa737 100644
--- a/core/src/main/kotlin/DokkaGenerator.kt
+++ b/core/src/main/kotlin/DokkaGenerator.kt
@@ -2,17 +2,10 @@
package org.jetbrains.dokka
-import org.jetbrains.dokka.model.DModule
-import org.jetbrains.dokka.DokkaConfiguration.*
-import org.jetbrains.dokka.pages.RootPageNode
+import org.jetbrains.dokka.generation.GracefulGenerationExit
import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.dokka.plugability.DokkaPlugin
import org.jetbrains.dokka.utilities.DokkaLogger
-import org.jetbrains.dokka.utilities.report
-import kotlinx.coroutines.*
-import org.jetbrains.dokka.transformers.sources.AsyncSourceToDocumentableTranslator
-import org.jetbrains.dokka.utilities.parallelMap
-
/**
* DokkaGenerator is the main entry point for generating documentation
@@ -29,136 +22,21 @@ class DokkaGenerator(
report("Initializing plugins")
val context = initializePlugins(configuration, logger)
- report("Validity check")
- validityCheck(context)
-
- report("Creating documentation models")
- val modulesFromPlatforms = createDocumentationModels(context)
-
- report("Transforming documentation model before merging")
- val transformedDocumentationBeforeMerge = transformDocumentationModelBeforeMerge(modulesFromPlatforms, context)
-
- report("Merging documentation models")
- val documentationModel = mergeDocumentationModels(transformedDocumentationBeforeMerge, context)
-
- report("Transforming documentation model after merging")
- val transformedDocumentation = transformDocumentationModelAfterMerge(documentationModel, context)
-
- report("Creating pages")
- val pages = createPages(transformedDocumentation, context)
-
- report("Transforming pages")
- val transformedPages = transformPages(pages, context)
-
- report("Rendering")
- render(transformedPages, context)
-
- reportAfterRendering(context)
- }.dump("\n\n === TIME MEASUREMENT ===\n")
-
- fun generateAllModulesPage() = timed {
- report("Initializing plugins")
- val context = initializePlugins(configuration, logger)
-
- report("Creating all modules page")
- val pages = createAllModulePage(context)
-
- report("Transforming pages")
- val transformedPages = transformAllModulesPage(pages, context)
+ context.single(CoreExtensions.generation).run {
+ logger.progress("Dokka is performing: $generationName")
+ generate()
+ }
- report("Rendering")
- render(transformedPages, context)
}.dump("\n\n === TIME MEASUREMENT ===\n")
-
fun initializePlugins(
configuration: DokkaConfiguration,
logger: DokkaLogger,
additionalPlugins: List<DokkaPlugin> = emptyList()
) = DokkaContext.create(configuration, logger, additionalPlugins)
-
- fun createDocumentationModels(
- context: DokkaContext
- ) = runBlocking(Dispatchers.Default) {
- context.configuration.sourceSets.parallelMap { sourceSet -> translateSources(sourceSet, context) }.flatten()
- .also { modules -> if (modules.isEmpty()) exitGenerationGracefully("Nothing to document") }
- }
-
- fun transformDocumentationModelBeforeMerge(
- modulesFromPlatforms: List<DModule>,
- context: DokkaContext
- ) = context[CoreExtensions.preMergeDocumentableTransformer].fold(modulesFromPlatforms) { acc, t -> t(acc) }
-
- fun mergeDocumentationModels(
- modulesFromPlatforms: List<DModule>,
- context: DokkaContext
- ) = context.single(CoreExtensions.documentableMerger).invoke(modulesFromPlatforms)
-
- fun transformDocumentationModelAfterMerge(
- documentationModel: DModule,
- context: DokkaContext
- ) = context[CoreExtensions.documentableTransformer].fold(documentationModel) { acc, t -> t(acc, context) }
-
- fun createPages(
- transformedDocumentation: DModule,
- 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
- ) {
- val renderer = context.single(CoreExtensions.renderer)
- renderer.render(transformedPages)
- }
-
- fun reportAfterRendering(context: DokkaContext) {
- context.unusedPoints.takeIf { it.isNotEmpty() }?.also {
- logger.info("Unused extension points found: ${it.joinToString(", ")}")
- }
-
- logger.report()
-
- if (context.configuration.failOnWarning && (logger.warningsCount > 0 || logger.errorsCount > 0)) {
- throw DokkaException(
- "Failed with warningCount=${logger.warningsCount} and errorCount=${logger.errorsCount}"
- )
- }
- }
-
- fun validityCheck(context: DokkaContext) {
- val (preGenerationCheckResult, checkMessages) = context[CoreExtensions.preGenerationCheck].fold(
- Pair(true, emptyList<String>())
- ) { acc, checker -> checker() + acc }
- if (!preGenerationCheckResult) throw DokkaException(
- "Pre-generation validity check failed: ${checkMessages.joinToString(",")}"
- )
- }
-
- private suspend fun translateSources(sourceSet: DokkaSourceSet, context: DokkaContext) =
- context[CoreExtensions.sourceToDocumentableTranslator].parallelMap { translator ->
- when(translator){
- is AsyncSourceToDocumentableTranslator -> translator.invokeSuspending(sourceSet, context)
- else -> translator.invoke(sourceSet, context)
- }
- }
}
-private class Timer(startTime: Long, private val logger: DokkaLogger?) {
+class Timer internal constructor(startTime: Long, private val logger: DokkaLogger?) {
private val steps = mutableListOf("" to startTime)
fun report(name: String) {
@@ -168,8 +46,8 @@ private class Timer(startTime: Long, private val logger: DokkaLogger?) {
fun dump(prefix: String = "") {
logger?.info(prefix)
- val namePad = steps.map { it.first.length }.max() ?: 0
- val timePad = steps.windowed(2).map { (p1, p2) -> p2.second - p1.second }.max()?.toString()?.length ?: 0
+ val namePad = steps.map { it.first.length }.maxOrNull() ?: 0
+ val timePad = steps.windowed(2).map { (p1, p2) -> p2.second - p1.second }.maxOrNull()?.toString()?.length ?: 0
steps.windowed(2).forEach { (p1, p2) ->
if (p1.first.isNotBlank()) {
logger?.info("${p1.first.padStart(namePad)}: ${(p2.second - p1.second).toString().padStart(timePad)}")
@@ -189,8 +67,3 @@ private fun timed(logger: DokkaLogger? = null, block: Timer.() -> Unit): Timer =
}
}
-private fun exitGenerationGracefully(reason: String): Nothing {
- throw GracefulGenerationExit(reason)
-}
-
-private class GracefulGenerationExit(val reason: String) : Throwable()
diff --git a/core/src/main/kotlin/DokkaMultimoduleBootstrapImpl.kt b/core/src/main/kotlin/DokkaMultimoduleBootstrapImpl.kt
deleted file mode 100644
index c0726584..00000000
--- a/core/src/main/kotlin/DokkaMultimoduleBootstrapImpl.kt
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * Accessed with reflection
- */
-@file:Suppress("unused")
-
-package org.jetbrains.dokka
-
-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(serializedConfigurationJSON: String, logger: BiConsumer<String, String>) = configure(
- DokkaProxyLogger(logger),
- DokkaConfigurationImpl(serializedConfigurationJSON)
- )
-
- override fun generate() {
- generator.generateAllModulesPage()
- }
-
-}
diff --git a/core/src/main/kotlin/generation/Generation.kt b/core/src/main/kotlin/generation/Generation.kt
new file mode 100644
index 00000000..230cdae1
--- /dev/null
+++ b/core/src/main/kotlin/generation/Generation.kt
@@ -0,0 +1,15 @@
+package org.jetbrains.dokka.generation
+
+import org.jetbrains.dokka.Timer
+
+interface Generation {
+ fun Timer.generate()
+ val generationName: String
+}
+
+// This needs to be public for now but in the future it should be replaced with system of checks provided by EP
+fun exitGenerationGracefully(reason: String): Nothing {
+ throw GracefulGenerationExit(reason)
+}
+
+class GracefulGenerationExit(val reason: String) : Throwable() \ No newline at end of file
diff --git a/core/src/main/kotlin/generation/SingleModule.kt b/core/src/main/kotlin/generation/SingleModule.kt
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/core/src/main/kotlin/generation/SingleModule.kt
diff --git a/core/src/main/kotlin/generation/SingleModuleGeneration.kt b/core/src/main/kotlin/generation/SingleModuleGeneration.kt
new file mode 100644
index 00000000..59514632
--- /dev/null
+++ b/core/src/main/kotlin/generation/SingleModuleGeneration.kt
@@ -0,0 +1,124 @@
+package org.jetbrains.dokka.generation
+
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.runBlocking
+import org.jetbrains.dokka.*
+import org.jetbrains.dokka.model.DModule
+import org.jetbrains.dokka.pages.RootPageNode
+import org.jetbrains.dokka.plugability.DokkaContext
+import org.jetbrains.dokka.transformers.sources.AsyncSourceToDocumentableTranslator
+import org.jetbrains.dokka.utilities.parallelMap
+import org.jetbrains.dokka.utilities.report
+
+class SingleModuleGeneration(private val context: DokkaContext): Generation {
+ override fun Timer.generate() {
+ report("Validity check")
+ validityCheck(context)
+
+ report("Creating documentation models")
+ val modulesFromPlatforms = createDocumentationModels(context)
+
+ report("Transforming documentation model before merging")
+ val transformedDocumentationBeforeMerge = transformDocumentationModelBeforeMerge(modulesFromPlatforms, context)
+
+ report("Merging documentation models")
+ val documentationModel = mergeDocumentationModels(transformedDocumentationBeforeMerge, context)
+
+ report("Transforming documentation model after merging")
+ val transformedDocumentation = transformDocumentationModelAfterMerge(documentationModel, context)
+
+ report("Creating pages")
+ val pages = createPages(transformedDocumentation, context)
+
+ report("Transforming pages")
+ val transformedPages = transformPages(pages, context)
+
+ report("Rendering")
+ render(transformedPages, context)
+
+ reportAfterRendering(context)
+ }
+
+ override val generationName: String
+ get() = TODO("Not yet implemented")
+
+ fun createDocumentationModels(
+ context: DokkaContext
+ ) = runBlocking(Dispatchers.Default) {
+ context.configuration.sourceSets.parallelMap { sourceSet -> translateSources(sourceSet, context) }.flatten()
+ .also { modules -> if (modules.isEmpty()) exitGenerationGracefully("Nothing to document") }
+ }
+
+ fun transformDocumentationModelBeforeMerge(
+ modulesFromPlatforms: List<DModule>,
+ context: DokkaContext
+ ) = context[CoreExtensions.preMergeDocumentableTransformer].fold(modulesFromPlatforms) { acc, t -> t(acc) }
+
+ fun mergeDocumentationModels(
+ modulesFromPlatforms: List<DModule>,
+ context: DokkaContext
+ ) = context.single(CoreExtensions.documentableMerger).invoke(modulesFromPlatforms)
+
+ fun transformDocumentationModelAfterMerge(
+ documentationModel: DModule,
+ context: DokkaContext
+ ) = context[CoreExtensions.documentableTransformer].fold(documentationModel) { acc, t -> t(acc, context) }
+
+ fun createPages(
+ transformedDocumentation: DModule,
+ 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
+ ) {
+ val renderer = context.single(CoreExtensions.renderer)
+ renderer.render(transformedPages)
+ }
+
+ fun validityCheck(context: DokkaContext) {
+ val (preGenerationCheckResult, checkMessages) = context[CoreExtensions.preGenerationCheck].fold(
+ Pair(true, emptyList<String>())
+ ) { acc, checker -> checker() + acc }
+ if (!preGenerationCheckResult) throw DokkaException(
+ "Pre-generation validity check failed: ${checkMessages.joinToString(",")}"
+ )
+ }
+
+ fun reportAfterRendering(context: DokkaContext) {
+ context.unusedPoints.takeIf { it.isNotEmpty() }?.also {
+ context.logger.info("Unused extension points found: ${it.joinToString(", ")}")
+ }
+
+ context.logger.report()
+
+ if (context.configuration.failOnWarning && (context.logger.warningsCount > 0 || context.logger.errorsCount > 0)) {
+ throw DokkaException(
+ "Failed with warningCount=${context.logger.warningsCount} and errorCount=${context.logger.errorsCount}"
+ )
+ }
+ }
+
+ private suspend fun translateSources(sourceSet: DokkaConfiguration.DokkaSourceSet, context: DokkaContext) =
+ context[CoreExtensions.sourceToDocumentableTranslator].parallelMap { translator ->
+ when(translator){
+ is AsyncSourceToDocumentableTranslator -> translator.invokeSuspending(sourceSet, context)
+ else -> translator.invoke(sourceSet, context)
+ }
+ }
+} \ No newline at end of file
diff --git a/core/src/main/kotlin/plugability/DokkaContext.kt b/core/src/main/kotlin/plugability/DokkaContext.kt
index 323039e9..1f5f6018 100644
--- a/core/src/main/kotlin/plugability/DokkaContext.kt
+++ b/core/src/main/kotlin/plugability/DokkaContext.kt
@@ -1,5 +1,6 @@
package org.jetbrains.dokka.plugability
+import org.jetbrains.dokka.CoreExtensions
import org.jetbrains.dokka.DokkaConfiguration
import org.jetbrains.dokka.utilities.DokkaLogger
import java.io.File
@@ -29,6 +30,7 @@ interface DokkaContext {
pluginOverrides: List<DokkaPlugin>
): DokkaContext =
DokkaContextConfigurationImpl(logger, configuration).apply {
+ CoreExtensions.installTo(this)
// File(it.path) is a workaround for an incorrect filesystem in a File instance returned by Gradle.
configuration.pluginsClasspath.map { File(it.path).toURI().toURL() }
.toTypedArray()
diff --git a/core/src/main/kotlin/plugability/extensions.kt b/core/src/main/kotlin/plugability/extensions.kt
index be45c237..46739951 100644
--- a/core/src/main/kotlin/plugability/extensions.kt
+++ b/core/src/main/kotlin/plugability/extensions.kt
@@ -40,7 +40,7 @@ class Extension<T : Any, Ordering : OrderingKind, Override : OverrideKind> inter
get() = { conditions.all { it(this) } }
}
-private fun <T : Any> Extension(
+internal fun <T : Any> Extension(
extensionPoint: ExtensionPoint<T>,
pluginClass: String,
extensionName: String,
diff --git a/core/test-api/src/main/kotlin/testApi/testRunner/DokkaTestGenerator.kt b/core/test-api/src/main/kotlin/testApi/testRunner/DokkaTestGenerator.kt
index 98f8965c..0f5814f6 100644
--- a/core/test-api/src/main/kotlin/testApi/testRunner/DokkaTestGenerator.kt
+++ b/core/test-api/src/main/kotlin/testApi/testRunner/DokkaTestGenerator.kt
@@ -1,7 +1,9 @@
package org.jetbrains.dokka.testApi.testRunner
+import org.jetbrains.dokka.CoreExtensions
import org.jetbrains.dokka.DokkaConfiguration
import org.jetbrains.dokka.DokkaGenerator
+import org.jetbrains.dokka.generation.SingleModuleGeneration
import org.jetbrains.dokka.plugability.DokkaPlugin
import org.jetbrains.dokka.utilities.DokkaLogger
@@ -19,31 +21,31 @@ internal class DokkaTestGenerator(
dokkaGenerator.initializePlugins(configuration, logger, additionalPlugins)
pluginsSetupStage(context)
- verificationStage {
- dokkaGenerator.validityCheck(context)
- }
+ val singleModuleGeneration = context.single(CoreExtensions.generation) as SingleModuleGeneration
- val modulesFromPlatforms = dokkaGenerator.createDocumentationModels(context)
+ val modulesFromPlatforms = singleModuleGeneration.createDocumentationModels()
documentablesCreationStage(modulesFromPlatforms)
- val filteredModules = dokkaGenerator.transformDocumentationModelBeforeMerge(modulesFromPlatforms, context)
+ verificationStage { singleModuleGeneration.validityCheck(context) }
+
+ val filteredModules = singleModuleGeneration.transformDocumentationModelBeforeMerge(modulesFromPlatforms)
documentablesFirstTransformationStep(filteredModules)
- val documentationModel = dokkaGenerator.mergeDocumentationModels(filteredModules, context)
+ val documentationModel = singleModuleGeneration.mergeDocumentationModels(filteredModules)
documentablesMergingStage(documentationModel)
- val transformedDocumentation = dokkaGenerator.transformDocumentationModelAfterMerge(documentationModel, context)
+ val transformedDocumentation = singleModuleGeneration.transformDocumentationModelAfterMerge(documentationModel)
documentablesTransformationStage(transformedDocumentation)
- val pages = dokkaGenerator.createPages(transformedDocumentation, context)
+ val pages = singleModuleGeneration.createPages(transformedDocumentation)
pagesGenerationStage(pages)
- val transformedPages = dokkaGenerator.transformPages(pages, context)
+ val transformedPages = singleModuleGeneration.transformPages(pages)
pagesTransformationStage(transformedPages)
- dokkaGenerator.render(transformedPages, context)
+ singleModuleGeneration.render(transformedPages)
renderingStage(transformedPages, context)
- dokkaGenerator.reportAfterRendering(context)
+ singleModuleGeneration.reportAfterRendering()
}
}
diff --git a/plugins/all-module-page/build.gradle.kts b/plugins/all-module-page/build.gradle.kts
new file mode 100644
index 00000000..dc5e0a6a
--- /dev/null
+++ b/plugins/all-module-page/build.gradle.kts
@@ -0,0 +1,9 @@
+import org.jetbrains.registerDokkaArtifactPublication
+
+registerDokkaArtifactPublication("dokkaAllModulesPage") {
+ artifactId = "all-modules-page-plugin"
+}
+
+dependencies {
+ implementation(project(":plugins:base"))
+} \ No newline at end of file
diff --git a/plugins/all-module-page/src/main/kotlin/AllModulesPageGeneration.kt b/plugins/all-module-page/src/main/kotlin/AllModulesPageGeneration.kt
new file mode 100644
index 00000000..815cf160
--- /dev/null
+++ b/plugins/all-module-page/src/main/kotlin/AllModulesPageGeneration.kt
@@ -0,0 +1,31 @@
+package org.jetbrains.dokka.allModulesPage
+
+import org.jetbrains.dokka.CoreExtensions
+import org.jetbrains.dokka.Timer
+import org.jetbrains.dokka.generation.Generation
+import org.jetbrains.dokka.pages.RootPageNode
+import org.jetbrains.dokka.plugability.DokkaContext
+
+class AllModulesPageGeneration(private val context: DokkaContext) : Generation {
+ override fun Timer.generate() {
+ report("Creating all modules page")
+ val pages = createAllModulePage()
+
+ report("Transforming pages")
+ val transformedPages = transformAllModulesPage(pages)
+
+ report("Rendering")
+ render(transformedPages)
+ }
+
+ override val generationName = "index page for project"
+
+ fun createAllModulePage() = context.single(CoreExtensions.allModulePageCreator).invoke()
+
+ fun transformAllModulesPage(pages: RootPageNode) =
+ context[CoreExtensions.allModulePageTransformer].fold(pages) { acc, t -> t(acc) }
+
+ fun render(transformedPages: RootPageNode) {
+ context.single(CoreExtensions.renderer).render(transformedPages)
+ }
+} \ No newline at end of file
diff --git a/plugins/all-module-page/src/main/kotlin/AllModulesPagePlugin.kt b/plugins/all-module-page/src/main/kotlin/AllModulesPagePlugin.kt
new file mode 100644
index 00000000..163f13ab
--- /dev/null
+++ b/plugins/all-module-page/src/main/kotlin/AllModulesPagePlugin.kt
@@ -0,0 +1,25 @@
+package org.jetbrains.dokka.allModulesPage
+
+import org.jetbrains.dokka.CoreExtensions
+import org.jetbrains.dokka.base.DokkaBase
+import org.jetbrains.dokka.plugability.DokkaPlugin
+
+class AllModulesPagePlugin : DokkaPlugin() {
+ val allModulePageCreators by extending {
+ (CoreExtensions.allModulePageCreator
+ providing ::MultimodulePageCreator)
+ }
+
+ val multimoduleLocationProvider by extending {
+ (plugin<DokkaBase>().locationProviderFactory
+ providing MultimoduleLocationProvider::Factory
+ override plugin<DokkaBase>().locationProvider
+ applyIf { modules.size > 1 })
+ }
+
+ val allModulesPageGeneration by extending {
+ (CoreExtensions.generation
+ providing ::AllModulesPageGeneration
+ override CoreExtensions.singleGeneration)
+ }
+} \ No newline at end of file
diff --git a/plugins/all-module-page/src/main/kotlin/MultimoduleLocationProvider.kt b/plugins/all-module-page/src/main/kotlin/MultimoduleLocationProvider.kt
new file mode 100644
index 00000000..29107136
--- /dev/null
+++ b/plugins/all-module-page/src/main/kotlin/MultimoduleLocationProvider.kt
@@ -0,0 +1,41 @@
+package org.jetbrains.dokka.allModulesPage
+
+import org.jetbrains.dokka.base.resolvers.local.DokkaLocationProvider
+import org.jetbrains.dokka.base.resolvers.local.DokkaLocationProvider.Companion.identifierToFilename
+import org.jetbrains.dokka.base.resolvers.local.LocationProvider
+import org.jetbrains.dokka.base.resolvers.local.LocationProviderFactory
+import org.jetbrains.dokka.links.DRI
+import org.jetbrains.dokka.model.DisplaySourceSet
+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 {
+
+ private val defaultLocationProvider = DokkaLocationProvider(root, context)
+
+ val paths = context.configuration.modules.map {
+ it.name to it.relativePathToOutputDirectory
+ }.toMap()
+
+ override fun resolve(dri: DRI, sourceSets: Set<DisplaySourceSet>, context: PageNode?) =
+ dri.takeIf { it.packageName == MULTIMODULE_PACKAGE_PLACEHOLDER }?.classNames?.let { paths[it] }?.let {
+ "$it/${identifierToFilename(dri.classNames.orEmpty())}/index.html"
+ } ?: defaultLocationProvider.resolve(dri, sourceSets, context)
+
+ override fun resolve(node: PageNode, context: PageNode?, skipExtension: Boolean) =
+ defaultLocationProvider.resolve(node, context, skipExtension)
+
+ override fun pathToRoot(from: PageNode): String = defaultLocationProvider.pathToRoot(from)
+
+ override fun ancestors(node: PageNode): List<PageNode> = listOf(root)
+
+ companion object {
+ const val MULTIMODULE_PACKAGE_PLACEHOLDER = ".ext"
+ }
+
+ class Factory(private val context: DokkaContext): LocationProviderFactory {
+ override fun getLocationProvider(pageNode: RootPageNode) =
+ MultimoduleLocationProvider(pageNode, context)
+ }
+} \ No newline at end of file
diff --git a/plugins/base/src/main/kotlin/allModulePage/MultimodulePageCreator.kt b/plugins/all-module-page/src/main/kotlin/MultimodulePageCreator.kt
index 3c4f1dea..3ad3e0ce 100644
--- a/plugins/base/src/main/kotlin/allModulePage/MultimodulePageCreator.kt
+++ b/plugins/all-module-page/src/main/kotlin/MultimodulePageCreator.kt
@@ -1,4 +1,4 @@
-package org.jetbrains.dokka.base.allModulePage
+package org.jetbrains.dokka.allModulesPage
import org.jetbrains.dokka.DokkaConfiguration.DokkaModuleDescription
import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet
diff --git a/plugins/all-module-page/src/main/resources/META-INF/services/org.jetbrains.dokka.plugability.DokkaPlugin b/plugins/all-module-page/src/main/resources/META-INF/services/org.jetbrains.dokka.plugability.DokkaPlugin
new file mode 100644
index 00000000..3ac59dc6
--- /dev/null
+++ b/plugins/all-module-page/src/main/resources/META-INF/services/org.jetbrains.dokka.plugability.DokkaPlugin
@@ -0,0 +1 @@
+org.jetbrains.dokka.allModulesPage.AllModulesPagePlugin
diff --git a/plugins/base/src/main/kotlin/DokkaBase.kt b/plugins/base/src/main/kotlin/DokkaBase.kt
index e92759ff..de7e1e5e 100644
--- a/plugins/base/src/main/kotlin/DokkaBase.kt
+++ b/plugins/base/src/main/kotlin/DokkaBase.kt
@@ -4,7 +4,6 @@ package org.jetbrains.dokka.base
import org.jetbrains.dokka.CoreExtensions
import org.jetbrains.dokka.analysis.KotlinAnalysis
-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.resolvers.external.ExternalLocationProviderFactory
@@ -205,12 +204,6 @@ class DokkaBase : DokkaPlugin() {
htmlPreprocessors providing ::SourcesetDependencyAppender order { after(rootCreator) }
}
- val allModulePageCreators by extending {
- CoreExtensions.allModulePageCreator providing {
- MultimodulePageCreator(it)
- }
- }
-
val baseSearchbarDataInstaller by extending {
htmlPreprocessors providing ::SearchbarDataInstaller order { after(sourceLinksTransformer) }
}
diff --git a/plugins/base/src/main/kotlin/parsers/moduleAndPackage/ModuleAndPackageDocumentation.kt b/plugins/base/src/main/kotlin/parsers/moduleAndPackage/ModuleAndPackageDocumentation.kt
index 5139c872..ee67fad1 100644
--- a/plugins/base/src/main/kotlin/parsers/moduleAndPackage/ModuleAndPackageDocumentation.kt
+++ b/plugins/base/src/main/kotlin/parsers/moduleAndPackage/ModuleAndPackageDocumentation.kt
@@ -2,7 +2,7 @@ package org.jetbrains.dokka.base.parsers.moduleAndPackage
import org.jetbrains.dokka.model.doc.DocumentationNode
-internal data class ModuleAndPackageDocumentation(
+data class ModuleAndPackageDocumentation(
val name: String,
val classifier: Classifier,
val documentation: DocumentationNode
diff --git a/plugins/base/src/main/kotlin/parsers/moduleAndPackage/ModuleAndPackageDocumentationFragment.kt b/plugins/base/src/main/kotlin/parsers/moduleAndPackage/ModuleAndPackageDocumentationFragment.kt
index fa99a8e2..06fef72c 100644
--- a/plugins/base/src/main/kotlin/parsers/moduleAndPackage/ModuleAndPackageDocumentationFragment.kt
+++ b/plugins/base/src/main/kotlin/parsers/moduleAndPackage/ModuleAndPackageDocumentationFragment.kt
@@ -2,7 +2,7 @@ package org.jetbrains.dokka.base.parsers.moduleAndPackage
import org.jetbrains.dokka.base.parsers.moduleAndPackage.ModuleAndPackageDocumentation.*
-internal data class ModuleAndPackageDocumentationFragment(
+data class ModuleAndPackageDocumentationFragment(
val name: String,
val classifier: Classifier,
val documentation: String,
diff --git a/plugins/base/src/main/kotlin/parsers/moduleAndPackage/ModuleAndPackageDocumentationParsingContext.kt b/plugins/base/src/main/kotlin/parsers/moduleAndPackage/ModuleAndPackageDocumentationParsingContext.kt
index 64441447..afdcc43f 100644
--- a/plugins/base/src/main/kotlin/parsers/moduleAndPackage/ModuleAndPackageDocumentationParsingContext.kt
+++ b/plugins/base/src/main/kotlin/parsers/moduleAndPackage/ModuleAndPackageDocumentationParsingContext.kt
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.idea.kdoc.resolveKDocLink
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
-internal fun interface ModuleAndPackageDocumentationParsingContext {
+fun interface ModuleAndPackageDocumentationParsingContext {
fun markdownParserFor(fragment: ModuleAndPackageDocumentationFragment): MarkdownParser
}
@@ -27,7 +27,7 @@ internal fun ModuleAndPackageDocumentationParsingContext.parse(
return markdownParserFor(fragment).parse(fragment.documentation)
}
-internal fun ModuleAndPackageDocumentationParsingContext(
+fun ModuleAndPackageDocumentationParsingContext(
logger: DokkaLogger,
facade: DokkaResolutionFacade? = null
) = ModuleAndPackageDocumentationParsingContext { fragment ->
diff --git a/plugins/base/src/main/kotlin/parsers/moduleAndPackage/ModuleAndPackageDocumentationSource.kt b/plugins/base/src/main/kotlin/parsers/moduleAndPackage/ModuleAndPackageDocumentationSource.kt
index 90dc9ca8..9514adb4 100644
--- a/plugins/base/src/main/kotlin/parsers/moduleAndPackage/ModuleAndPackageDocumentationSource.kt
+++ b/plugins/base/src/main/kotlin/parsers/moduleAndPackage/ModuleAndPackageDocumentationSource.kt
@@ -2,7 +2,7 @@ package org.jetbrains.dokka.base.parsers.moduleAndPackage
import java.io.File
-internal abstract class ModuleAndPackageDocumentationSource {
+abstract class ModuleAndPackageDocumentationSource {
abstract val sourceDescription: String
abstract val documentation: String
override fun toString(): String = sourceDescription
diff --git a/plugins/base/src/main/kotlin/parsers/moduleAndPackage/parseModuleAndPackageDocumentation.kt b/plugins/base/src/main/kotlin/parsers/moduleAndPackage/parseModuleAndPackageDocumentation.kt
index a2876308..5ef9d7ef 100644
--- a/plugins/base/src/main/kotlin/parsers/moduleAndPackage/parseModuleAndPackageDocumentation.kt
+++ b/plugins/base/src/main/kotlin/parsers/moduleAndPackage/parseModuleAndPackageDocumentation.kt
@@ -2,7 +2,7 @@
package org.jetbrains.dokka.base.parsers.moduleAndPackage
-internal fun parseModuleAndPackageDocumentation(
+fun parseModuleAndPackageDocumentation(
context: ModuleAndPackageDocumentationParsingContext,
fragment: ModuleAndPackageDocumentationFragment
): ModuleAndPackageDocumentation {
diff --git a/plugins/base/src/main/kotlin/parsers/moduleAndPackage/parseModuleAndPackageDocumentationFragments.kt b/plugins/base/src/main/kotlin/parsers/moduleAndPackage/parseModuleAndPackageDocumentationFragments.kt
index 7dcaccfa..d193ec0a 100644
--- a/plugins/base/src/main/kotlin/parsers/moduleAndPackage/parseModuleAndPackageDocumentationFragments.kt
+++ b/plugins/base/src/main/kotlin/parsers/moduleAndPackage/parseModuleAndPackageDocumentationFragments.kt
@@ -4,11 +4,11 @@ import org.jetbrains.dokka.base.parsers.moduleAndPackage.ModuleAndPackageDocumen
import java.io.File
-internal fun parseModuleAndPackageDocumentationFragments(source: File): List<ModuleAndPackageDocumentationFragment> {
+fun parseModuleAndPackageDocumentationFragments(source: File): List<ModuleAndPackageDocumentationFragment> {
return parseModuleAndPackageDocumentationFragments(ModuleAndPackageDocumentationFile(source))
}
-internal fun parseModuleAndPackageDocumentationFragments(
+fun parseModuleAndPackageDocumentationFragments(
source: ModuleAndPackageDocumentationSource
): List<ModuleAndPackageDocumentationFragment> {
val fragmentStrings = source.documentation.split(Regex("(|^)#\\s*(?=(Module|Package))"))
diff --git a/plugins/base/src/main/kotlin/resolvers/local/DokkaLocationProvider.kt b/plugins/base/src/main/kotlin/resolvers/local/DokkaLocationProvider.kt
index 3ef8bcce..030197a5 100644
--- a/plugins/base/src/main/kotlin/resolvers/local/DokkaLocationProvider.kt
+++ b/plugins/base/src/main/kotlin/resolvers/local/DokkaLocationProvider.kt
@@ -129,12 +129,12 @@ open class DokkaLocationProvider(
protected data class PageWithKind(val page: ContentPage, val kind: Kind)
companion object {
- internal val reservedFilenames = setOf("index", "con", "aux", "lst", "prn", "nul", "eof", "inp", "out")
+ val reservedFilenames = 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('|', '>', '<', '*', ':', '"', '?', '%')
- internal fun identifierToFilename(name: String): String {
+ fun identifierToFilename(name: String): String {
if (name.isEmpty()) return "--root--"
return sanitizeFileName(name, reservedFilenames, reservedCharacters)
}
diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaArtifacts.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaArtifacts.kt
index 90d51015..726dd950 100644
--- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaArtifacts.kt
+++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaArtifacts.kt
@@ -9,6 +9,7 @@ internal class DokkaArtifacts(private val project: Project) {
private fun fromModuleName(name: String) =
project.dependencies.create("org.jetbrains.dokka:$name:${DokkaVersion.version}")
+ val allModulesPage get() = fromModuleName("all-modules-page-plugin")
val dokkaCore get() = fromModuleName("dokka-core")
val dokkaBase get() = fromModuleName("dokka-base")
val javadocPlugin get() = fromModuleName("javadoc-plugin")
diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleTask.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleTask.kt
index 03e0b4d7..74f17215 100644
--- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleTask.kt
+++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleTask.kt
@@ -3,6 +3,7 @@ package org.jetbrains.dokka.gradle
import org.gradle.api.internal.tasks.TaskDependencyInternal
import org.gradle.api.provider.Property
import org.gradle.api.tasks.*
+import org.jetbrains.dokka.DokkaBootstrapImpl
import org.jetbrains.dokka.DokkaConfigurationImpl
import org.jetbrains.dokka.DokkaModuleDescriptionImpl
import org.jetbrains.dokka.DokkaMultimoduleBootstrapImpl
@@ -15,7 +16,7 @@ typealias DokkaMultimoduleTask = DokkaMultiModuleTask
private typealias TaskPath = String
-abstract class DokkaMultiModuleTask : AbstractDokkaParentTask(DokkaMultimoduleBootstrapImpl::class) {
+abstract class DokkaMultiModuleTask : AbstractDokkaParentTask(DokkaBootstrapImpl::class) {
@Internal
val fileLayout: Property<DokkaMultiModuleFileLayout> = project.objects.safeProperty<DokkaMultiModuleFileLayout>()
diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/main.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/main.kt
index f5dc9366..1cda5c39 100644
--- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/main.kt
+++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/main.kt
@@ -57,6 +57,7 @@ open class DokkaPlugin : Plugin<Project> {
addSubprojectChildTasks(name)
configuration()
description = "Runs all subprojects '$name' tasks and generates module navigation page"
+ plugins.dependencies.add(project.dokkaArtifacts.allModulesPage)
}
project.tasks.register<DefaultTask>("${name}Multimodule") {
diff --git a/settings.gradle.kts b/settings.gradle.kts
index f40e88d8..52b16dc3 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -16,6 +16,7 @@ include("plugins:base")
include("plugins:base:frontend")
include("plugins:base:search-component")
include("plugins:base:base-test-utils")
+include("plugins:all-module-page")
include("plugins:mathjax")
include("plugins:gfm")