From ed56e7bcdceac7a13eae851e02f642c0762aaf40 Mon Sep 17 00:00:00 2001 From: Błażej Kardyś Date: Wed, 28 Oct 2020 21:54:00 +0100 Subject: Moving SingleGeneration to base pluing --- .../src/main/kotlin/AllModulesPageGeneration.kt | 10 +- .../src/main/kotlin/AllModulesPagePlugin.kt | 10 +- .../src/main/kotlin/testRunner/baseTestApi.kt | 111 +++++++++++++++++++++ plugins/base/src/main/kotlin/DokkaBase.kt | 25 +++-- .../kotlin/generation/SingleModuleGeneration.kt | 105 +++++++++++++++++++ .../org/jetbrains/dokka/javadoc/JavadocPlugin.kt | 2 +- 6 files changed, 247 insertions(+), 16 deletions(-) create mode 100644 plugins/base/base-test-utils/src/main/kotlin/testRunner/baseTestApi.kt create mode 100644 plugins/base/src/main/kotlin/generation/SingleModuleGeneration.kt (limited to 'plugins') diff --git a/plugins/all-module-page/src/main/kotlin/AllModulesPageGeneration.kt b/plugins/all-module-page/src/main/kotlin/AllModulesPageGeneration.kt index f654514a..1ba63627 100644 --- a/plugins/all-module-page/src/main/kotlin/AllModulesPageGeneration.kt +++ b/plugins/all-module-page/src/main/kotlin/AllModulesPageGeneration.kt @@ -6,9 +6,11 @@ import org.jetbrains.dokka.generation.Generation import org.jetbrains.dokka.pages.RootPageNode import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.plugability.plugin +import org.jetbrains.dokka.plugability.query import org.jetbrains.dokka.plugability.querySingle class AllModulesPageGeneration(private val context: DokkaContext) : Generation { + override fun Timer.generate() { report("Creating all modules page") val pages = createAllModulePage() @@ -20,17 +22,19 @@ class AllModulesPageGeneration(private val context: DokkaContext) : Generation { render(transformedPages) report("Processing submodules") - context.plugin().querySingle { templateProcessor }.process() + allModulesPagePlugin().querySingle { templateProcessor }.process() } override val generationName = "index page for project" - fun createAllModulePage() = context.single(CoreExtensions.allModulePageCreator).invoke() + fun createAllModulePage() = allModulesPagePlugin().querySingle { allModulePageCreator }.invoke() fun transformAllModulesPage(pages: RootPageNode) = - context[CoreExtensions.allModulePageTransformer].fold(pages) { acc, t -> t(acc) } + allModulesPagePlugin().query { allModulePageTransformer }.fold(pages) { acc, t -> t(acc) } fun render(transformedPages: RootPageNode) { context.single(CoreExtensions.renderer).render(transformedPages) } + + private fun allModulesPagePlugin() = context.plugin() } \ 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 index f1ed8c1e..a65c0c58 100644 --- a/plugins/all-module-page/src/main/kotlin/AllModulesPagePlugin.kt +++ b/plugins/all-module-page/src/main/kotlin/AllModulesPagePlugin.kt @@ -4,15 +4,19 @@ import org.jetbrains.dokka.CoreExtensions import org.jetbrains.dokka.allModulesPage.templates.* import org.jetbrains.dokka.base.DokkaBase import org.jetbrains.dokka.plugability.DokkaPlugin +import org.jetbrains.dokka.transformers.pages.PageCreator +import org.jetbrains.dokka.transformers.pages.PageTransformer class AllModulesPagePlugin : DokkaPlugin() { + val templateProcessor by extensionPoint() + val allModulePageCreator by extensionPoint() + val allModulePageTransformer by extensionPoint() val substitutor by extensionPoint() val allModulePageCreators by extending { - (CoreExtensions.allModulePageCreator - providing ::MultimodulePageCreator) + allModulePageCreator providing ::MultimodulePageCreator } val multimoduleLocationProvider by extending { @@ -25,7 +29,7 @@ class AllModulesPagePlugin : DokkaPlugin() { val allModulesPageGeneration by extending { (CoreExtensions.generation providing ::AllModulesPageGeneration - override CoreExtensions.singleGeneration) + override plugin().singleGeneration) } val defaultTemplateProcessor by extending { diff --git a/plugins/base/base-test-utils/src/main/kotlin/testRunner/baseTestApi.kt b/plugins/base/base-test-utils/src/main/kotlin/testRunner/baseTestApi.kt new file mode 100644 index 00000000..cfc5ed43 --- /dev/null +++ b/plugins/base/base-test-utils/src/main/kotlin/testRunner/baseTestApi.kt @@ -0,0 +1,111 @@ +package org.jetbrains.dokka.base.testApi.testRunner + +import org.jetbrains.dokka.CoreExtensions +import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.DokkaGenerator +import org.jetbrains.dokka.base.generation.SingleModuleGeneration +import org.jetbrains.dokka.model.DModule +import org.jetbrains.dokka.pages.RootPageNode +import org.jetbrains.dokka.plugability.DokkaContext +import org.jetbrains.dokka.plugability.DokkaPlugin +import org.jetbrains.dokka.testApi.logger.TestLogger +import org.jetbrains.dokka.testApi.testRunner.AbstractTest +import org.jetbrains.dokka.testApi.testRunner.DokkaTestGenerator +import org.jetbrains.dokka.testApi.testRunner.TestBuilder +import org.jetbrains.dokka.testApi.testRunner.TestMethods +import org.jetbrains.dokka.utilities.DokkaConsoleLogger +import org.jetbrains.dokka.utilities.DokkaLogger + +class BaseDokkaTestGenerator( + configuration: DokkaConfiguration, + logger: DokkaLogger, + testMethods: BaseTestMethods, + additionalPlugins: List = emptyList() +) : DokkaTestGenerator(configuration, logger, testMethods, additionalPlugins) { + + override fun generate() = with(testMethods) { + val dokkaGenerator = DokkaGenerator(configuration, logger) + + val context = + dokkaGenerator.initializePlugins(configuration, logger, additionalPlugins) + pluginsSetupStage(context) + + val singleModuleGeneration = context.single(CoreExtensions.generation) as SingleModuleGeneration + + val modulesFromPlatforms = singleModuleGeneration.createDocumentationModels() + documentablesCreationStage(modulesFromPlatforms) + + verificationStage { singleModuleGeneration.validityCheck(context) } + + val filteredModules = singleModuleGeneration.transformDocumentationModelBeforeMerge(modulesFromPlatforms) + documentablesFirstTransformationStep(filteredModules) + + val documentationModel = singleModuleGeneration.mergeDocumentationModels(filteredModules) + documentablesMergingStage(documentationModel) + + val transformedDocumentation = singleModuleGeneration.transformDocumentationModelAfterMerge(documentationModel) + documentablesTransformationStage(transformedDocumentation) + + val pages = singleModuleGeneration.createPages(transformedDocumentation) + pagesGenerationStage(pages) + + val transformedPages = singleModuleGeneration.transformPages(pages) + pagesTransformationStage(transformedPages) + + singleModuleGeneration.render(transformedPages) + renderingStage(transformedPages, context) + + singleModuleGeneration.reportAfterRendering() + } +} + +data class BaseTestMethods( + override val pluginsSetupStage: (DokkaContext) -> Unit, + override val verificationStage: (() -> Unit) -> Unit, + override val documentablesCreationStage: (List) -> Unit, + val documentablesFirstTransformationStep: (List) -> Unit, + override val documentablesMergingStage: (DModule) -> Unit, + override val documentablesTransformationStage: (DModule) -> Unit, + override val pagesGenerationStage: (RootPageNode) -> Unit, + override val pagesTransformationStage: (RootPageNode) -> Unit, + override val renderingStage: (RootPageNode, DokkaContext) -> Unit +) : TestMethods( + pluginsSetupStage, + verificationStage, + documentablesCreationStage, + documentablesMergingStage, + documentablesTransformationStage, + pagesGenerationStage, + pagesTransformationStage, + renderingStage, +) + +class BaseTestBuilder : TestBuilder() { + var pluginsSetupStage: (DokkaContext) -> Unit = {} + var verificationStage: (() -> Unit) -> Unit = {} + var documentablesCreationStage: (List) -> Unit = {} + var documentablesFirstTransformationStep: (List) -> Unit = {} + var documentablesMergingStage: (DModule) -> Unit = {} + var documentablesTransformationStage: (DModule) -> Unit = {} + var pagesGenerationStage: (RootPageNode) -> Unit = {} + var pagesTransformationStage: (RootPageNode) -> Unit = {} + var renderingStage: (RootPageNode, DokkaContext) -> Unit = { a, b -> } + + override fun build() = BaseTestMethods( + pluginsSetupStage, + verificationStage, + documentablesCreationStage, + documentablesFirstTransformationStep, + documentablesMergingStage, + documentablesTransformationStage, + pagesGenerationStage, + pagesTransformationStage, + renderingStage + ) +} + +open class BaseAbstractTest(logger: TestLogger = TestLogger(DokkaConsoleLogger)) : AbstractTest( + ::BaseTestBuilder, + ::BaseDokkaTestGenerator, + logger, +) \ 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 fce5c399..ac070ab4 100644 --- a/plugins/base/src/main/kotlin/DokkaBase.kt +++ b/plugins/base/src/main/kotlin/DokkaBase.kt @@ -16,7 +16,6 @@ import org.jetbrains.dokka.base.resolvers.local.LocationProviderFactory import org.jetbrains.dokka.base.resolvers.shared.RecognizedLinkFormat import org.jetbrains.dokka.base.signatures.KotlinSignatureProvider import org.jetbrains.dokka.base.signatures.SignatureProvider -import org.jetbrains.dokka.base.templating.Command import org.jetbrains.dokka.base.templating.ImmediateHtmlCommandConsumer import org.jetbrains.dokka.base.transformers.documentables.* import org.jetbrains.dokka.base.transformers.pages.annotations.SinceKotlinTransformer @@ -28,10 +27,14 @@ import org.jetbrains.dokka.base.transformers.pages.sourcelinks.SourceLinksTransf import org.jetbrains.dokka.base.translators.descriptors.DefaultDescriptorToDocumentableTranslator import org.jetbrains.dokka.base.translators.documentables.DefaultDocumentableToPageTranslator import org.jetbrains.dokka.base.translators.psi.DefaultPsiToDocumentableTranslator +import org.jetbrains.dokka.base.generation.SingleModuleGeneration import org.jetbrains.dokka.plugability.DokkaPlugin +import org.jetbrains.dokka.transformers.documentation.PreMergeDocumentableTransformer import org.jetbrains.dokka.transformers.pages.PageTransformer class DokkaBase : DokkaPlugin() { + + val preMergeDocumentableTransformer by extensionPoint() val pageMergerStrategy by extensionPoint() val commentsToContentConverter by extensionPoint() val signatureProvider by extensionPoint() @@ -43,6 +46,10 @@ class DokkaBase : DokkaPlugin() { val tabSortingStrategy by extensionPoint() val immediateHtmlCommandConsumer by extensionPoint() + val singleGeneration by extending { + CoreExtensions.generation providing ::SingleModuleGeneration + } + val descriptorToDocumentableTranslator by extending { CoreExtensions.sourceToDocumentableTranslator providing ::DefaultDescriptorToDocumentableTranslator } @@ -56,29 +63,29 @@ class DokkaBase : DokkaPlugin() { } val deprecatedDocumentableFilter by extending { - CoreExtensions.preMergeDocumentableTransformer providing ::DeprecatedDocumentableFilterTransformer + preMergeDocumentableTransformer providing ::DeprecatedDocumentableFilterTransformer } val suppressedDocumentableFilter by extending { - CoreExtensions.preMergeDocumentableTransformer providing ::SuppressedDocumentableFilterTransformer + preMergeDocumentableTransformer providing ::SuppressedDocumentableFilterTransformer } val documentableVisbilityFilter by extending { - CoreExtensions.preMergeDocumentableTransformer providing ::DocumentableVisibilityFilterTransformer + preMergeDocumentableTransformer providing ::DocumentableVisibilityFilterTransformer } val emptyPackagesFilter by extending { - CoreExtensions.preMergeDocumentableTransformer providing ::EmptyPackagesFilterTransformer order { + preMergeDocumentableTransformer providing ::EmptyPackagesFilterTransformer order { after(deprecatedDocumentableFilter, suppressedDocumentableFilter, documentableVisbilityFilter) } } - val actualTypealiasAdder by extending { - CoreExtensions.documentableTransformer with ActualTypealiasAdder() + val modulesAndPackagesDocumentation by extending { + preMergeDocumentableTransformer providing ::ModuleAndPackageDocumentationTransformer } - val modulesAndPackagesDocumentation by extending { - CoreExtensions.preMergeDocumentableTransformer providing ::ModuleAndPackageDocumentationTransformer + val actualTypealiasAdder by extending { + CoreExtensions.documentableTransformer with ActualTypealiasAdder() } val kotlinSignatureProvider by extending { diff --git a/plugins/base/src/main/kotlin/generation/SingleModuleGeneration.kt b/plugins/base/src/main/kotlin/generation/SingleModuleGeneration.kt new file mode 100644 index 00000000..eb405a3d --- /dev/null +++ b/plugins/base/src/main/kotlin/generation/SingleModuleGeneration.kt @@ -0,0 +1,105 @@ + +package org.jetbrains.dokka.base.generation + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.runBlocking +import org.jetbrains.dokka.CoreExtensions +import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.DokkaException +import org.jetbrains.dokka.Timer +import org.jetbrains.dokka.base.DokkaBase +import org.jetbrains.dokka.model.DModule +import org.jetbrains.dokka.pages.RootPageNode +import org.jetbrains.dokka.plugability.DokkaContext +import org.jetbrains.dokka.plugability.plugin +import org.jetbrains.dokka.plugability.query +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() + + report("Transforming documentation model before merging") + val transformedDocumentationBeforeMerge = transformDocumentationModelBeforeMerge(modulesFromPlatforms) + + report("Merging documentation models") + val documentationModel = mergeDocumentationModels(transformedDocumentationBeforeMerge) + + report("Transforming documentation model after merging") + val transformedDocumentation = transformDocumentationModelAfterMerge(documentationModel) + + report("Creating pages") + val pages = createPages(transformedDocumentation) + + report("Transforming pages") + val transformedPages = transformPages(pages) + + report("Rendering") + render(transformedPages) + + reportAfterRendering() + } + + override val generationName = " documentation for ${context.configuration.moduleName}" + + fun createDocumentationModels() = 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.plugin().query { preMergeDocumentableTransformer }.fold(modulesFromPlatforms) { acc, t -> t(acc) } + + fun mergeDocumentationModels(modulesFromPlatforms: List) = + context.single(CoreExtensions.documentableMerger).invoke(modulesFromPlatforms) + + fun transformDocumentationModelAfterMerge(documentationModel: DModule) = + context[CoreExtensions.documentableTransformer].fold(documentationModel) { acc, t -> t(acc, context) } + + fun createPages(transformedDocumentation: DModule) = + context.single(CoreExtensions.documentableToPageTranslator).invoke(transformedDocumentation) + + fun transformPages(pages: RootPageNode) = + context[CoreExtensions.pageTransformer].fold(pages) { acc, t -> t(acc) } + + fun render(transformedPages: RootPageNode) { + context.single(CoreExtensions.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.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/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/JavadocPlugin.kt b/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/JavadocPlugin.kt index d23aaa4e..0bbbbf86 100644 --- a/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/JavadocPlugin.kt +++ b/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/JavadocPlugin.kt @@ -36,7 +36,7 @@ class JavadocPlugin : DokkaPlugin() { } val documentableSourceSetFilter by extending { - CoreExtensions.preMergeDocumentableTransformer providing ::JavadocDocumentableJVMSourceSetFilter + dokkaBasePlugin.preMergeDocumentableTransformer providing ::JavadocDocumentableJVMSourceSetFilter } val javadocLocationProviderFactory by extending { -- cgit