aboutsummaryrefslogtreecommitdiff
path: root/src/main.kt
diff options
context:
space:
mode:
authorDmitry Jemerov <yole@jetbrains.com>2015-12-03 16:22:11 +0100
committerDmitry Jemerov <yole@jetbrains.com>2015-12-03 16:22:49 +0100
commit39631054c58df5841ea268b7002b820ec55f6e0a (patch)
treecefedd8411c859243bd181568e16fcdd372a38c8 /src/main.kt
parent797cb4732c53bf1e3b2091add8cf731fc436607f (diff)
downloaddokka-39631054c58df5841ea268b7002b820ec55f6e0a.tar.gz
dokka-39631054c58df5841ea268b7002b820ec55f6e0a.tar.bz2
dokka-39631054c58df5841ea268b7002b820ec55f6e0a.zip
restructure Dokka build to use Gradle for everything except for the Maven plugin
Diffstat (limited to 'src/main.kt')
-rw-r--r--src/main.kt262
1 files changed, 0 insertions, 262 deletions
diff --git a/src/main.kt b/src/main.kt
deleted file mode 100644
index 5a7514c4..00000000
--- a/src/main.kt
+++ /dev/null
@@ -1,262 +0,0 @@
-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 com.sampullara.cli.Args
-import com.sampullara.cli.Argument
-import org.jetbrains.dokka.Utilities.DokkaModule
-import org.jetbrains.kotlin.cli.common.arguments.ValueDescription
-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.CommonConfigurationKeys
-import org.jetbrains.kotlin.resolve.LazyTopDownAnalyzerForTopLevel
-import org.jetbrains.kotlin.resolve.TopDownAnalysisMode
-import org.jetbrains.kotlin.utils.PathUtil
-import java.io.File
-import kotlin.util.measureTimeMillis
-
-class DokkaArguments {
- @set:Argument(value = "src", description = "Source file or directory (allows many paths separated by the system path separator)")
- @ValueDescription("<path>")
- public var src: String = ""
-
- @set:Argument(value = "srcLink", description = "Mapping between a source directory and a Web site for browsing the code")
- @ValueDescription("<path>=<url>[#lineSuffix]")
- public var srcLink: String = ""
-
- @set:Argument(value = "include", description = "Markdown files to load (allows many paths separated by the system path separator)")
- @ValueDescription("<path>")
- public var include: String = ""
-
- @set:Argument(value = "samples", description = "Source root for samples")
- @ValueDescription("<path>")
- public var samples: String = ""
-
- @set:Argument(value = "output", description = "Output directory path")
- @ValueDescription("<path>")
- public var outputDir: String = "out/doc/"
-
- @set:Argument(value = "format", description = "Output format (text, html, markdown, jekyll, kotlin-website)")
- @ValueDescription("<name>")
- public var outputFormat: String = "html"
-
- @set:Argument(value = "module", description = "Name of the documentation module")
- @ValueDescription("<name>")
- public var moduleName: String = ""
-
- @set:Argument(value = "classpath", description = "Classpath for symbol resolution")
- @ValueDescription("<path>")
- public var classpath: String = ""
-
- @set:Argument(value = "nodeprecated", description = "Exclude deprecated members from documentation")
- public var nodeprecated: Boolean = false
-
-}
-
-private fun parseSourceLinkDefinition(srcLink: String): SourceLinkDefinition {
- val (path, urlAndLine) = srcLink.split('=')
- return SourceLinkDefinition(File(path).absolutePath,
- urlAndLine.substringBefore("#"),
- urlAndLine.substringAfter("#", "").let { if (it.isEmpty()) null else "#" + it })
-}
-
-public fun main(args: Array<String>) {
- val arguments = DokkaArguments()
- val freeArgs: List<String> = Args.parse(arguments, args) ?: listOf()
- val sources = if (arguments.src.isNotEmpty()) arguments.src.split(File.pathSeparatorChar).toList() + freeArgs else freeArgs
- val samples = if (arguments.samples.isNotEmpty()) arguments.samples.split(File.pathSeparatorChar).toList() else listOf()
- val includes = if (arguments.include.isNotEmpty()) arguments.include.split(File.pathSeparatorChar).toList() else listOf()
-
- val sourceLinks = if (arguments.srcLink.isNotEmpty() && arguments.srcLink.contains("="))
- listOf(parseSourceLinkDefinition(arguments.srcLink))
- else {
- if (arguments.srcLink.isNotEmpty()) {
- println("Warning: Invalid -srcLink syntax. Expected: <path>=<url>[#lineSuffix]. No source links will be generated.")
- }
- listOf()
- }
-
- val classPath = arguments.classpath.split(File.pathSeparatorChar).toList()
- val generator = DokkaGenerator(
- DokkaConsoleLogger,
- classPath,
- sources,
- samples,
- includes,
- arguments.moduleName,
- arguments.outputDir.let { if (it.endsWith('/')) it else it + '/' },
- arguments.outputFormat,
- sourceLinks,
- arguments.nodeprecated)
-
- generator.generate()
- DokkaConsoleLogger.report()
-}
-
-interface DokkaLogger {
- fun info(message: String)
- fun warn(message: String)
- fun error(message: String)
-}
-
-object DokkaConsoleLogger: DokkaLogger {
- var warningCount: Int = 0
-
- override fun info(message: String) = println(message)
- override fun warn(message: String) {
- println("WARN: $message")
- warningCount++
- }
-
- override fun error(message: String) = println("ERROR: $message")
-
- fun report() {
- if (warningCount > 0) {
- println("Generation completed with $warningCount warnings")
- } else {
- println("Generation completed successfully")
- }
- }
-}
-
-class DokkaMessageCollector(val logger: DokkaLogger): MessageCollector {
- override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation) {
- logger.error(MessageRenderer.PLAIN_FULL_PATHS.render(severity, message, location))
- }
-}
-
-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 outputDir: String,
- val outputFormat: String,
- val sourceLinks: List<SourceLinkDefinition>,
- val skipDeprecated: Boolean = false) {
- fun generate() {
- val environment = createAnalysisEnvironment()
-
- logger.info("Module: $moduleName")
- logger.info("Output: ${File(outputDir)}")
- logger.info("Sources: ${environment.sources.joinToString()}")
- logger.info("Classpath: ${environment.classpath.joinToString()}")
-
- logger.info("Analysing sources and libraries... ")
- val startAnalyse = System.currentTimeMillis()
-
- val options = DocumentationOptions(outputDir, outputFormat, false, sourceLinks = sourceLinks, skipDeprecated = skipDeprecated)
-
- 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)
- }
- }
-}
-
-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(CommonConfigurationKeys.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
-}