From c8a83153a88fe6f5b50b6f459295421f90a21583 Mon Sep 17 00:00:00 2001 From: Paweł Marks Date: Wed, 16 Sep 2020 16:36:54 +0200 Subject: Extracting dokka generation to the dedicated extension point --- core/src/main/kotlin/CoreExtensions.kt | 44 +++++-- core/src/main/kotlin/DokkaGenerator.kt | 143 ++------------------- .../main/kotlin/DokkaMultimoduleBootstrapImpl.kt | 29 ----- core/src/main/kotlin/generation/Generation.kt | 15 +++ core/src/main/kotlin/generation/SingleModule.kt | 0 .../kotlin/generation/SingleModuleGeneration.kt | 124 ++++++++++++++++++ core/src/main/kotlin/plugability/DokkaContext.kt | 2 + core/src/main/kotlin/plugability/extensions.kt | 2 +- .../testApi/testRunner/DokkaTestGenerator.kt | 24 ++-- plugins/all-module-page/build.gradle.kts | 9 ++ .../src/main/kotlin/AllModulesPageGeneration.kt | 31 +++++ .../src/main/kotlin/AllModulesPagePlugin.kt | 25 ++++ .../src/main/kotlin/MultimoduleLocationProvider.kt | 41 ++++++ .../src/main/kotlin/MultimodulePageCreator.kt | 100 ++++++++++++++ .../org.jetbrains.dokka.plugability.DokkaPlugin | 1 + plugins/base/src/main/kotlin/DokkaBase.kt | 7 - .../kotlin/allModulePage/MultimodulePageCreator.kt | 100 -------------- .../ModuleAndPackageDocumentation.kt | 2 +- .../ModuleAndPackageDocumentationFragment.kt | 2 +- .../ModuleAndPackageDocumentationParsingContext.kt | 4 +- .../ModuleAndPackageDocumentationSource.kt | 2 +- .../parseModuleAndPackageDocumentation.kt | 2 +- .../parseModuleAndPackageDocumentationFragments.kt | 4 +- .../resolvers/local/DokkaLocationProvider.kt | 4 +- .../org/jetbrains/dokka/gradle/DokkaArtifacts.kt | 1 + .../jetbrains/dokka/gradle/DokkaMultiModuleTask.kt | 3 +- .../main/kotlin/org/jetbrains/dokka/gradle/main.kt | 1 + settings.gradle.kts | 1 + 28 files changed, 417 insertions(+), 306 deletions(-) delete mode 100644 core/src/main/kotlin/DokkaMultimoduleBootstrapImpl.kt create mode 100644 core/src/main/kotlin/generation/Generation.kt create mode 100644 core/src/main/kotlin/generation/SingleModule.kt create mode 100644 core/src/main/kotlin/generation/SingleModuleGeneration.kt create mode 100644 plugins/all-module-page/build.gradle.kts create mode 100644 plugins/all-module-page/src/main/kotlin/AllModulesPageGeneration.kt create mode 100644 plugins/all-module-page/src/main/kotlin/AllModulesPagePlugin.kt create mode 100644 plugins/all-module-page/src/main/kotlin/MultimoduleLocationProvider.kt create mode 100644 plugins/all-module-page/src/main/kotlin/MultimodulePageCreator.kt create mode 100644 plugins/all-module-page/src/main/resources/META-INF/services/org.jetbrains.dokka.plugability.DokkaPlugin delete mode 100644 plugins/base/src/main/kotlin/allModulePage/MultimodulePageCreator.kt 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() - val sourceToDocumentableTranslator by coreExtension() - val preMergeDocumentableTransformer by coreExtension() - val documentableMerger by coreExtension() - val documentableTransformer by coreExtension() - val documentableToPageTranslator by coreExtension() - val allModulePageCreator by coreExtension() - val pageTransformer by coreExtension() - val allModulePageTransformer by coreExtension() - val renderer by coreExtension() + private val extensionDelegates = mutableListOf>>() - private fun coreExtension() = object { + val preGenerationCheck by coreExtensionPoint() + val generation by coreExtensionPoint() + val sourceToDocumentableTranslator by coreExtensionPoint() + val preMergeDocumentableTransformer by coreExtensionPoint() + val documentableMerger by coreExtensionPoint() + val documentableTransformer by coreExtensionPoint() + val documentableToPageTranslator by coreExtensionPoint() + val allModulePageCreator by coreExtensionPoint() + val pageTransformer by coreExtensionPoint() + val allModulePageTransformer by coreExtensionPoint() + val renderer by coreExtensionPoint() + + val singleGeneration by generation extendWith LazyEvaluated.fromRecipe(::SingleModuleGeneration) + + private fun coreExtensionPoint() = object { operator fun provideDelegate(thisRef: CoreExtensions, property: KProperty<*>): Lazy> = lazy { ExtensionPoint(thisRef::class.qualifiedName!!, property.name) } } + + private infix fun ExtensionPoint.extendWith(action: LazyEvaluated) = object { + operator fun provideDelegate(thisRef: CoreExtensions, property: KProperty<*>): Lazy> = + 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 = 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, - context: DokkaContext - ) = context[CoreExtensions.preMergeDocumentableTransformer].fold(modulesFromPlatforms) { acc, t -> t(acc) } - - fun mergeDocumentationModels( - modulesFromPlatforms: List, - 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()) - ) { 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) = 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 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, + context: DokkaContext + ) = context[CoreExtensions.preMergeDocumentableTransformer].fold(modulesFromPlatforms) { acc, t -> t(acc) } + + fun mergeDocumentationModels( + modulesFromPlatforms: List, + 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()) + ) { 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 ): 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 inter get() = { conditions.all { it(this) } } } -private fun Extension( +internal fun Extension( extensionPoint: ExtensionPoint, 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().locationProviderFactory + providing MultimoduleLocationProvider::Factory + override plugin().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, 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 = 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/all-module-page/src/main/kotlin/MultimodulePageCreator.kt b/plugins/all-module-page/src/main/kotlin/MultimodulePageCreator.kt new file mode 100644 index 00000000..3ad3e0ce --- /dev/null +++ b/plugins/all-module-page/src/main/kotlin/MultimodulePageCreator.kt @@ -0,0 +1,100 @@ +package org.jetbrains.dokka.allModulesPage + +import org.jetbrains.dokka.DokkaConfiguration.DokkaModuleDescription +import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet +import org.jetbrains.dokka.base.DokkaBase +import org.jetbrains.dokka.base.parsers.moduleAndPackage.ModuleAndPackageDocumentation.Classifier.Module +import org.jetbrains.dokka.base.parsers.moduleAndPackage.ModuleAndPackageDocumentationParsingContext +import org.jetbrains.dokka.base.parsers.moduleAndPackage.parseModuleAndPackageDocumentation +import org.jetbrains.dokka.base.parsers.moduleAndPackage.parseModuleAndPackageDocumentationFragments +import org.jetbrains.dokka.base.resolvers.anchors.SymbolAnchorHint +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.doc.DocTag +import org.jetbrains.dokka.model.doc.DocumentationNode +import org.jetbrains.dokka.model.doc.P +import org.jetbrains.dokka.model.properties.PropertyContainer +import org.jetbrains.dokka.pages.* +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 + +class MultimodulePageCreator( + private val context: DokkaContext, +) : PageCreator { + private val logger: DokkaLogger = context.logger + + override fun invoke(): RootPageNode { + 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() + 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.map { module -> + val displayedModuleDocumentation = getDisplayedModuleDocumentation(module) + val dri = DRI(packageName = MULTIMODULE_PACKAGE_PLACEHOLDER, classNames = module.name) + val dci = DCI(setOf(dri), ContentKind.Comment) + val extraWithAnchor = PropertyContainer.withAll(SymbolAnchorHint(module.name, ContentKind.Main)) + val header = linkNode(module.name, dri, DCI(setOf(dri), ContentKind.Main), extra = extraWithAnchor) + val content = ContentGroup( + children = + if (displayedModuleDocumentation != null) + DocTagToContentConverter().buildContent(displayedModuleDocumentation, dci, emptySet()) + else emptyList(), + dci = dci, + sourceSets = emptySet(), + style = emptySet() + ) + ContentGroup(listOf(header, content), dci, emptySet(), emptySet(), extraWithAnchor) + } + } + } + return MultimoduleRootPageNode( + "Modules", + setOf(DRI(packageName = MULTIMODULE_PACKAGE_PLACEHOLDER, classNames = "allModules")), + contentNode + ) + } + + private fun getDisplayedModuleDocumentation(module: DokkaModuleDescription): P? { + val parsingContext = ModuleAndPackageDocumentationParsingContext(logger) + + val documentationFragment = module.includes + .flatMap { include -> parseModuleAndPackageDocumentationFragments(include) } + .firstOrNull { fragment -> fragment.classifier == Module && fragment.name == module.name } + ?: return null + + val moduleDocumentation = parseModuleAndPackageDocumentation(parsingContext, documentationFragment) + return moduleDocumentation.documentation.firstParagraph() + } + + private fun DocumentationNode.firstParagraph(): P? = + this.children + .map { it.root } + .mapNotNull { it.firstParagraph() } + .firstOrNull() + + /** + * @return The very first, most inner paragraph. If any [P] is wrapped inside another [P], the inner one + * is preferred. + */ + private fun DocTag.firstParagraph(): P? { + val firstChildParagraph = children.mapNotNull { it.firstParagraph() }.firstOrNull() + return if (firstChildParagraph == null && this is P) this + else firstChildParagraph + } +} 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/allModulePage/MultimodulePageCreator.kt b/plugins/base/src/main/kotlin/allModulePage/MultimodulePageCreator.kt deleted file mode 100644 index 3c4f1dea..00000000 --- a/plugins/base/src/main/kotlin/allModulePage/MultimodulePageCreator.kt +++ /dev/null @@ -1,100 +0,0 @@ -package org.jetbrains.dokka.base.allModulePage - -import org.jetbrains.dokka.DokkaConfiguration.DokkaModuleDescription -import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet -import org.jetbrains.dokka.base.DokkaBase -import org.jetbrains.dokka.base.parsers.moduleAndPackage.ModuleAndPackageDocumentation.Classifier.Module -import org.jetbrains.dokka.base.parsers.moduleAndPackage.ModuleAndPackageDocumentationParsingContext -import org.jetbrains.dokka.base.parsers.moduleAndPackage.parseModuleAndPackageDocumentation -import org.jetbrains.dokka.base.parsers.moduleAndPackage.parseModuleAndPackageDocumentationFragments -import org.jetbrains.dokka.base.resolvers.anchors.SymbolAnchorHint -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.doc.DocTag -import org.jetbrains.dokka.model.doc.DocumentationNode -import org.jetbrains.dokka.model.doc.P -import org.jetbrains.dokka.model.properties.PropertyContainer -import org.jetbrains.dokka.pages.* -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 - -class MultimodulePageCreator( - private val context: DokkaContext, -) : PageCreator { - private val logger: DokkaLogger = context.logger - - override fun invoke(): RootPageNode { - 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() - 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.map { module -> - val displayedModuleDocumentation = getDisplayedModuleDocumentation(module) - val dri = DRI(packageName = MULTIMODULE_PACKAGE_PLACEHOLDER, classNames = module.name) - val dci = DCI(setOf(dri), ContentKind.Comment) - val extraWithAnchor = PropertyContainer.withAll(SymbolAnchorHint(module.name, ContentKind.Main)) - val header = linkNode(module.name, dri, DCI(setOf(dri), ContentKind.Main), extra = extraWithAnchor) - val content = ContentGroup( - children = - if (displayedModuleDocumentation != null) - DocTagToContentConverter().buildContent(displayedModuleDocumentation, dci, emptySet()) - else emptyList(), - dci = dci, - sourceSets = emptySet(), - style = emptySet() - ) - ContentGroup(listOf(header, content), dci, emptySet(), emptySet(), extraWithAnchor) - } - } - } - return MultimoduleRootPageNode( - "Modules", - setOf(DRI(packageName = MULTIMODULE_PACKAGE_PLACEHOLDER, classNames = "allModules")), - contentNode - ) - } - - private fun getDisplayedModuleDocumentation(module: DokkaModuleDescription): P? { - val parsingContext = ModuleAndPackageDocumentationParsingContext(logger) - - val documentationFragment = module.includes - .flatMap { include -> parseModuleAndPackageDocumentationFragments(include) } - .firstOrNull { fragment -> fragment.classifier == Module && fragment.name == module.name } - ?: return null - - val moduleDocumentation = parseModuleAndPackageDocumentation(parsingContext, documentationFragment) - return moduleDocumentation.documentation.firstParagraph() - } - - private fun DocumentationNode.firstParagraph(): P? = - this.children - .map { it.root } - .mapNotNull { it.firstParagraph() } - .firstOrNull() - - /** - * @return The very first, most inner paragraph. If any [P] is wrapped inside another [P], the inner one - * is preferred. - */ - private fun DocTag.firstParagraph(): P? { - val firstChildParagraph = children.mapNotNull { it.firstParagraph() }.firstOrNull() - return if (firstChildParagraph == null && this is P) this - else firstChildParagraph - } -} 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 { +fun parseModuleAndPackageDocumentationFragments(source: File): List { return parseModuleAndPackageDocumentationFragments(ModuleAndPackageDocumentationFile(source)) } -internal fun parseModuleAndPackageDocumentationFragments( +fun parseModuleAndPackageDocumentationFragments( source: ModuleAndPackageDocumentationSource ): List { 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 = project.objects.safeProperty() 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 { addSubprojectChildTasks(name) configuration() description = "Runs all subprojects '$name' tasks and generates module navigation page" + plugins.dependencies.add(project.dokkaArtifacts.allModulesPage) } project.tasks.register("${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") -- cgit