diff options
author | Simon Ogorodnik <sem-oro@yandex.ru> | 2016-11-01 02:10:32 +0300 |
---|---|---|
committer | Simon Ogorodnik <Simon.Ogorodnik@jetbrains.com> | 2016-11-01 14:46:01 +0300 |
commit | 769701f99a1aefbc9d385c1938c9c7d3a7b2e38e (patch) | |
tree | c3ea4802d9e627c90870808aba9343eb224a114c /core/src/main/kotlin/Generation | |
parent | 08bcaa257f7b48929af6ee29007dd6f0d7bb1b52 (diff) | |
download | dokka-769701f99a1aefbc9d385c1938c9c7d3a7b2e38e.tar.gz dokka-769701f99a1aefbc9d385c1938c9c7d3a7b2e38e.tar.bz2 dokka-769701f99a1aefbc9d385c1938c9c7d3a7b2e38e.zip |
Total build refactoring, prepare for new development iteration
Removed old and useless build helpers
Remove old .xml's from .idea and add .idea/shelf to .gitignore
build-docs.xml fixed, dokka_version set to 0.9.10
Diffstat (limited to 'core/src/main/kotlin/Generation')
-rw-r--r-- | core/src/main/kotlin/Generation/DokkaGenerator.kt | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/core/src/main/kotlin/Generation/DokkaGenerator.kt b/core/src/main/kotlin/Generation/DokkaGenerator.kt new file mode 100644 index 00000000..8d846904 --- /dev/null +++ b/core/src/main/kotlin/Generation/DokkaGenerator.kt @@ -0,0 +1,158 @@ +package org.jetbrains.dokka + +import com.google.inject.Guice +import com.google.inject.Injector +import com.intellij.openapi.util.Disposer +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.* +import org.jetbrains.dokka.Utilities.DokkaModule +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity +import org.jetbrains.kotlin.cli.common.messages.MessageCollector +import org.jetbrains.kotlin.cli.common.messages.MessageRenderer +import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment +import org.jetbrains.kotlin.cli.jvm.config.JavaSourceRoot +import org.jetbrains.kotlin.config.JVMConfigurationKeys +import org.jetbrains.kotlin.resolve.LazyTopDownAnalyzerForTopLevel +import org.jetbrains.kotlin.resolve.TopDownAnalysisMode +import org.jetbrains.kotlin.utils.PathUtil +import java.io.File +import kotlin.system.measureTimeMillis + +class DokkaGenerator(val logger: DokkaLogger, + val classpath: List<String>, + val sources: List<String>, + val samples: List<String>, + val includes: List<String>, + val moduleName: String, + val options: DocumentationOptions) { + fun generate() { + val environment = createAnalysisEnvironment() + + logger.info("Module: $moduleName") + logger.info("Output: ${File(options.outputDir)}") + logger.info("Sources: ${environment.sources.joinToString()}") + logger.info("Classpath: ${environment.classpath.joinToString()}") + + logger.info("Analysing sources and libraries... ") + val startAnalyse = System.currentTimeMillis() + + val injector = Guice.createInjector(DokkaModule(environment, options, logger)) + + val documentation = buildDocumentationModule(injector, moduleName, { 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) + } + + fun createAnalysisEnvironment(): AnalysisEnvironment { + val environment = AnalysisEnvironment(DokkaMessageCollector(logger)) + + environment.apply { + addClasspath(PathUtil.getJdkClassesRoots()) + // addClasspath(PathUtil.getKotlinPathsForCompiler().getRuntimePath()) + for (element in this@DokkaGenerator.classpath) { + addClasspath(File(element)) + } + + addSources(this@DokkaGenerator.sources) + addSources(this@DokkaGenerator.samples) + } + + return environment + } + + fun isSample(file: PsiFile): Boolean { + val sourceFile = File(file.virtualFile!!.path) + return samples.none { sample -> + val canonicalSample = File(sample).canonicalPath + val canonicalSource = sourceFile.canonicalPath + canonicalSource.startsWith(canonicalSample) + } + } +} + +class DokkaMessageCollector(val logger: DokkaLogger): MessageCollector { + private var seenErrors = false + + override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation) { + if (severity == CompilerMessageSeverity.ERROR) { + seenErrors = true + } + logger.error(MessageRenderer.PLAIN_FULL_PATHS.render(severity, message, location)) + } + + override fun hasErrors() = seenErrors +} + +fun buildDocumentationModule(injector: Injector, + moduleName: String, + filesToDocumentFilter: (PsiFile) -> Boolean = { file -> true }, + includes: List<String> = listOf()): DocumentationModule { + + val coreEnvironment = injector.getInstance(KotlinCoreEnvironment::class.java) + val fragmentFiles = coreEnvironment.getSourceFiles().filter(filesToDocumentFilter) + + val resolutionFacade = injector.getInstance(DokkaResolutionFacade::class.java) + val analyzer = resolutionFacade.getFrontendService(LazyTopDownAnalyzerForTopLevel::class.java) + analyzer.analyzeDeclarations(TopDownAnalysisMode.TopLevelDeclarations, fragmentFiles) + + val fragments = fragmentFiles + .map { resolutionFacade.resolveSession.getPackageFragment(it.packageFqName) } + .filterNotNull() + .distinct() + + val packageDocs = injector.getInstance(PackageDocs::class.java) + for (include in includes) { + packageDocs.parse(include, fragments.firstOrNull()) + } + val documentationModule = DocumentationModule(moduleName, packageDocs.moduleContent) + + with(injector.getInstance(DocumentationBuilder::class.java)) { + documentationModule.appendFragments(fragments, packageDocs.packageContent, + injector.getInstance(PackageDocumentationBuilder::class.java)) + } + + val javaFiles = coreEnvironment.getJavaSourceFiles().filter(filesToDocumentFilter) + with(injector.getInstance(JavaDocumentationBuilder::class.java)) { + javaFiles.map { appendFile(it, documentationModule, packageDocs.packageContent) } + } + + injector.getInstance(NodeReferenceGraph::class.java).resolveReferences() + + return documentationModule +} + + +fun KotlinCoreEnvironment.getJavaSourceFiles(): List<PsiJavaFile> { + val sourceRoots = configuration.get(JVMConfigurationKeys.CONTENT_ROOTS) + ?.filterIsInstance<JavaSourceRoot>() + ?.map { it.file } + ?: listOf() + + val result = arrayListOf<PsiJavaFile>() + val localFileSystem = VirtualFileManager.getInstance().getFileSystem("file") + sourceRoots.forEach { sourceRoot -> + sourceRoot.absoluteFile.walkTopDown().forEach { + val vFile = localFileSystem.findFileByPath(it.path) + if (vFile != null) { + val psiFile = PsiManager.getInstance(project).findFile(vFile) + if (psiFile is PsiJavaFile) { + result.add(psiFile) + } + } + } + } + return result +} |