From 2bd8bdf9dc0a8e48ce558b2eed0c8e8fd4883902 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 22 Feb 2017 17:29:39 +0100 Subject: Better separation between analysis and output generation phases --- core/src/main/kotlin/Generation/DokkaGenerator.kt | 39 ++++++---- core/src/main/kotlin/Utilities/DokkaModule.kt | 75 ------------------- core/src/main/kotlin/Utilities/DokkaModules.kt | 87 +++++++++++++++++++++++ core/src/test/kotlin/TestAPI.kt | 7 +- 4 files changed, 116 insertions(+), 92 deletions(-) delete mode 100644 core/src/main/kotlin/Utilities/DokkaModule.kt create mode 100644 core/src/main/kotlin/Utilities/DokkaModules.kt (limited to 'core/src') diff --git a/core/src/main/kotlin/Generation/DokkaGenerator.kt b/core/src/main/kotlin/Generation/DokkaGenerator.kt index 360965d5..aaf0deff 100644 --- a/core/src/main/kotlin/Generation/DokkaGenerator.kt +++ b/core/src/main/kotlin/Generation/DokkaGenerator.kt @@ -7,7 +7,8 @@ import com.intellij.openapi.vfs.VirtualFileManager import com.intellij.psi.PsiFile import com.intellij.psi.PsiJavaFile import com.intellij.psi.PsiManager -import org.jetbrains.dokka.Utilities.DokkaModule +import org.jetbrains.dokka.Utilities.DokkaAnalysisModule +import org.jetbrains.dokka.Utilities.DokkaOutputModule import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity import org.jetbrains.kotlin.cli.common.messages.MessageCollector @@ -28,7 +29,21 @@ class DokkaGenerator(val logger: DokkaLogger, val includes: List, val moduleName: String, val options: DocumentationOptions) { + + private val documentationModule = DocumentationModule(moduleName) + fun generate() { + appendSourceModule() + + val timeBuild = measureTimeMillis { + logger.info("Generating pages... ") + val outputInjector = Guice.createInjector(DokkaOutputModule(options, logger)) + outputInjector.getInstance(Generator::class.java).buildAll(documentationModule) + } + logger.info("done in ${timeBuild / 1000} secs") + } + + private fun appendSourceModule() { val environment = createAnalysisEnvironment() logger.info("Module: $moduleName") @@ -39,19 +54,13 @@ class DokkaGenerator(val logger: DokkaLogger, logger.info("Analysing sources and libraries... ") val startAnalyse = System.currentTimeMillis() - val injector = Guice.createInjector(DokkaModule(environment, options, logger)) + val injector = Guice.createInjector(DokkaAnalysisModule(environment, options, logger)) - val documentation = buildDocumentationModule(injector, moduleName, { isSample(it) }, includes) + buildDocumentationModule(injector, documentationModule, { isSample(it) }, includes) val timeAnalyse = System.currentTimeMillis() - startAnalyse logger.info("done in ${timeAnalyse / 1000} secs") - val timeBuild = measureTimeMillis { - logger.info("Generating pages... ") - injector.getInstance(Generator::class.java).buildAll(documentation) - } - logger.info("done in ${timeBuild / 1000} secs") - Disposer.dispose(environment) } @@ -100,9 +109,9 @@ class DokkaMessageCollector(val logger: DokkaLogger): MessageCollector { } fun buildDocumentationModule(injector: Injector, - moduleName: String, + documentationModule: DocumentationModule, filesToDocumentFilter: (PsiFile) -> Boolean = { file -> true }, - includes: List = listOf()): DocumentationModule { + includes: List = listOf()) { val coreEnvironment = injector.getInstance(KotlinCoreEnvironment::class.java) val fragmentFiles = coreEnvironment.getSourceFiles().filter(filesToDocumentFilter) @@ -120,7 +129,11 @@ fun buildDocumentationModule(injector: Injector, for (include in includes) { packageDocs.parse(include, fragments.firstOrNull()) } - val documentationModule = DocumentationModule(moduleName, packageDocs.moduleContent) + documentationModule.updateContent { + for (node in packageDocs.moduleContent.children) { + append(node) + } + } with(injector.getInstance(DocumentationBuilder::class.java)) { documentationModule.appendFragments(fragments, packageDocs.packageContent, @@ -133,8 +146,6 @@ fun buildDocumentationModule(injector: Injector, } injector.getInstance(NodeReferenceGraph::class.java).resolveReferences() - - return documentationModule } diff --git a/core/src/main/kotlin/Utilities/DokkaModule.kt b/core/src/main/kotlin/Utilities/DokkaModule.kt deleted file mode 100644 index e1ae829a..00000000 --- a/core/src/main/kotlin/Utilities/DokkaModule.kt +++ /dev/null @@ -1,75 +0,0 @@ -package org.jetbrains.dokka.Utilities - -import com.google.inject.Binder -import com.google.inject.Module -import com.google.inject.Provider -import com.google.inject.name.Names -import org.jetbrains.dokka.* -import org.jetbrains.dokka.Formats.FormatDescriptor -import org.jetbrains.dokka.Samples.SampleProcessingService -import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment -import java.io.File - -class DokkaModule(val environment: AnalysisEnvironment, - val options: DocumentationOptions, - val logger: DokkaLogger) : Module { - override fun configure(binder: Binder) { - binder.bind(File::class.java).annotatedWith(Names.named("outputDir")).toInstance(File(options.outputDir)) - - binder.bindNameAnnotated("singleFolder") - binder.bindNameAnnotated("singleFolder") - binder.bindNameAnnotated("folders") - binder.bindNameAnnotated("folders") - - // defaults - binder.bind(LocationService::class.java).to(FoldersLocationService::class.java) - binder.bind(FileLocationService::class.java).to(FoldersLocationService::class.java) - binder.bind(LanguageService::class.java).to(KotlinLanguageService::class.java) - - binder.bind(HtmlTemplateService::class.java).toProvider(object : Provider { - override fun get(): HtmlTemplateService = HtmlTemplateService.default("style.css") - }) - - binder.registerCategory("language") - binder.registerCategory("outline") - binder.registerCategory("format") - binder.registerCategory("generator") - - val descriptor = ServiceLocator.lookup("format", options.outputFormat) - - descriptor.outlineServiceClass?.let { clazz -> - binder.bind(OutlineFormatService::class.java).to(clazz.java) - } - descriptor.formatServiceClass?.let { clazz -> - binder.bind(FormatService::class.java).to(clazz.java) - } - binder.bind().to(descriptor.packageDocumentationBuilderClass.java) - binder.bind().to(descriptor.javaDocumentationBuilderClass.java) - binder.bind().to(descriptor.sampleProcessingService.java) - - binder.bind().to(descriptor.generatorServiceClass.java) - - val coreEnvironment = environment.createCoreEnvironment() - binder.bind().toInstance(coreEnvironment) - - val dokkaResolutionFacade = environment.createResolutionFacade(coreEnvironment) - binder.bind().toInstance(dokkaResolutionFacade) - - binder.bind().toInstance(options) - binder.bind().toInstance(logger) - } -} - -private inline fun Binder.registerCategory(category: String) { - ServiceLocator.allServices(category).forEach { - @Suppress("UNCHECKED_CAST") - bind(T::class.java).annotatedWith(Names.named(it.name)).to(T::class.java.classLoader.loadClass(it.className) as Class) - } -} - -private inline fun Binder.bindNameAnnotated(name: String) { - bind(Base::class.java).annotatedWith(Names.named(name)).to(T::class.java) -} - - -inline fun Binder.bind() = bind(T::class.java) diff --git a/core/src/main/kotlin/Utilities/DokkaModules.kt b/core/src/main/kotlin/Utilities/DokkaModules.kt new file mode 100644 index 00000000..69facaa0 --- /dev/null +++ b/core/src/main/kotlin/Utilities/DokkaModules.kt @@ -0,0 +1,87 @@ +package org.jetbrains.dokka.Utilities + +import com.google.inject.Binder +import com.google.inject.Module +import com.google.inject.Provider +import com.google.inject.name.Names +import org.jetbrains.dokka.* +import org.jetbrains.dokka.Formats.FormatDescriptor +import org.jetbrains.dokka.Samples.SampleProcessingService +import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment +import java.io.File + +class DokkaAnalysisModule(val environment: AnalysisEnvironment, + val options: DocumentationOptions, + val logger: DokkaLogger) : Module { + override fun configure(binder: Binder) { + val descriptor = ServiceLocator.lookup("format", options.outputFormat) + + binder.registerCategory("language") + binder.bind().to(descriptor.packageDocumentationBuilderClass.java) + binder.bind().to(descriptor.javaDocumentationBuilderClass.java) + binder.bind().to(descriptor.sampleProcessingService.java) + + val coreEnvironment = environment.createCoreEnvironment() + binder.bind().toInstance(coreEnvironment) + + val dokkaResolutionFacade = environment.createResolutionFacade(coreEnvironment) + binder.bind().toInstance(dokkaResolutionFacade) + + binder.bind().toInstance(options) + binder.bind().toInstance(logger) + } +} + +class DokkaOutputModule(val options: DocumentationOptions, + val logger: DokkaLogger) : Module { + override fun configure(binder: Binder) { + binder.bind(LanguageService::class.java).to(KotlinLanguageService::class.java) + + binder.bind(HtmlTemplateService::class.java).toProvider(object : Provider { + override fun get(): HtmlTemplateService = HtmlTemplateService.default("style.css") + }) + + binder.bind(File::class.java).annotatedWith(Names.named("outputDir")).toInstance(File(options.outputDir)) + + binder.bindNameAnnotated("singleFolder") + binder.bindNameAnnotated("singleFolder") + binder.bindNameAnnotated("folders") + binder.bindNameAnnotated("folders") + + // defaults + binder.bind(LocationService::class.java).to(FoldersLocationService::class.java) + binder.bind(FileLocationService::class.java).to(FoldersLocationService::class.java) + + binder.registerCategory("outline") + binder.registerCategory("format") + binder.registerCategory("generator") + + val descriptor = ServiceLocator.lookup("format", options.outputFormat) + + descriptor.outlineServiceClass?.let { clazz -> + binder.bind(OutlineFormatService::class.java).to(clazz.java) + } + descriptor.formatServiceClass?.let { clazz -> + binder.bind(FormatService::class.java).to(clazz.java) + } + + binder.bind().to(descriptor.generatorServiceClass.java) + + binder.bind().toInstance(options) + binder.bind().toInstance(logger) + } +} + +private inline fun Binder.registerCategory(category: String) { + ServiceLocator.allServices(category).forEach { + @Suppress("UNCHECKED_CAST") + bind(T::class.java).annotatedWith(Names.named(it.name)).to(T::class.java.classLoader.loadClass(it.className) as Class) + } +} + +private inline fun Binder.bindNameAnnotated(name: String) { + bind(Base::class.java).annotatedWith(Names.named(name)).to(T::class.java) +} + + +inline fun Binder.bind() = bind(T::class.java) diff --git a/core/src/test/kotlin/TestAPI.kt b/core/src/test/kotlin/TestAPI.kt index 7197d2c4..108c5bbf 100644 --- a/core/src/test/kotlin/TestAPI.kt +++ b/core/src/test/kotlin/TestAPI.kt @@ -5,7 +5,7 @@ import com.intellij.openapi.application.PathManager import com.intellij.openapi.util.Disposer import com.intellij.openapi.util.io.FileUtil import org.jetbrains.dokka.* -import org.jetbrains.dokka.Utilities.DokkaModule +import org.jetbrains.dokka.Utilities.DokkaAnalysisModule import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity import org.jetbrains.kotlin.cli.common.messages.MessageCollector @@ -65,8 +65,9 @@ fun verifyModel(vararg roots: ContentRoot, skipEmptyPackages = false, sourceLinks = listOf(), generateIndexPages = false) - val injector = Guice.createInjector(DokkaModule(environment, options, DokkaConsoleLogger)) - val documentation = buildDocumentationModule(injector, "test") + val injector = Guice.createInjector(DokkaAnalysisModule(environment, options, DokkaConsoleLogger)) + val documentation = DocumentationModule("test") + buildDocumentationModule(injector, documentation) verifier(documentation) Disposer.dispose(environment) } -- cgit