aboutsummaryrefslogtreecommitdiff
path: root/core/src/main/kotlin/Generation
diff options
context:
space:
mode:
authorSimon Ogorodnik <sem-oro@yandex.ru>2016-11-01 02:10:32 +0300
committerSimon Ogorodnik <Simon.Ogorodnik@jetbrains.com>2016-11-01 14:46:01 +0300
commit769701f99a1aefbc9d385c1938c9c7d3a7b2e38e (patch)
treec3ea4802d9e627c90870808aba9343eb224a114c /core/src/main/kotlin/Generation
parent08bcaa257f7b48929af6ee29007dd6f0d7bb1b52 (diff)
downloaddokka-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.kt158
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
+}