diff options
-rw-r--r-- | .idea/ant.xml | 6 | ||||
-rw-r--r-- | .idea/artifacts/dokka_jar.xml | 4 | ||||
-rw-r--r-- | .idea/libraries/ant_1_9_4.xml | 9 | ||||
-rw-r--r-- | .idea/modules.xml | 4 | ||||
-rw-r--r-- | ant/ant.iml | 14 | ||||
-rw-r--r-- | ant/src/dokka-antlib.xml | 3 | ||||
-rw-r--r-- | ant/src/dokka.kt | 85 | ||||
-rw-r--r-- | build.xml | 9 | ||||
-rw-r--r-- | lib/ant-1.9.4.jar | bin | 0 -> 2019274 bytes | |||
-rw-r--r-- | src/Kotlin/DocumentationBuilder.kt | 4 | ||||
-rw-r--r-- | src/main.kt | 203 | ||||
-rw-r--r-- | test/src/TestAPI.kt | 2 |
12 files changed, 259 insertions, 84 deletions
diff --git a/.idea/ant.xml b/.idea/ant.xml new file mode 100644 index 00000000..a2a47698 --- /dev/null +++ b/.idea/ant.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="AntConfiguration"> + <buildFile url="file://$PROJECT_DIR$/build.xml" /> + </component> +</project>
\ No newline at end of file diff --git a/.idea/artifacts/dokka_jar.xml b/.idea/artifacts/dokka_jar.xml index 9aba0ca1..fd03fd07 100644 --- a/.idea/artifacts/dokka_jar.xml +++ b/.idea/artifacts/dokka_jar.xml @@ -5,8 +5,8 @@ <element id="module-output" name="dokka" /> <element id="extracted-dir" path="$KOTLIN_BUNDLED$/lib/kotlin-runtime.jar" path-in-jar="/" /> <element id="extracted-dir" path="$KOTLIN_BUNDLED$/lib/kotlin-compiler.jar" path-in-jar="/" /> - <element id="extracted-dir" path="$PROJECT_DIR$/lib/junit-4.11.jar" path-in-jar="/" /> - <element id="extracted-dir" path="$PROJECT_DIR$/lib/hamcrest-core-1.3.jar" path-in-jar="/" /> + <element id="module-output" name="ant" /> + <element id="extracted-dir" path="$PROJECT_DIR$/lib/markdown.jar" path-in-jar="/" /> </root> </artifact> </component>
\ No newline at end of file diff --git a/.idea/libraries/ant_1_9_4.xml b/.idea/libraries/ant_1_9_4.xml new file mode 100644 index 00000000..f68d9a6b --- /dev/null +++ b/.idea/libraries/ant_1_9_4.xml @@ -0,0 +1,9 @@ +<component name="libraryTable"> + <library name="ant-1.9.4"> + <CLASSES> + <root url="jar://$PROJECT_DIR$/lib/ant-1.9.4.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES /> + </library> +</component>
\ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml index 142d525a..bfcf8757 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -2,8 +2,8 @@ <project version="4"> <component name="ProjectModuleManager"> <modules> + <module fileurl="file://$PROJECT_DIR$/ant/ant.iml" filepath="$PROJECT_DIR$/ant/ant.iml" /> <module fileurl="file://$PROJECT_DIR$/dokka.iml" filepath="$PROJECT_DIR$/dokka.iml" /> </modules> </component> -</project> - +</project>
\ No newline at end of file diff --git a/ant/ant.iml b/ant/ant.iml new file mode 100644 index 00000000..0761035c --- /dev/null +++ b/ant/ant.iml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module type="JAVA_MODULE" version="4"> + <component name="NewModuleRootManager" inherit-compiler-output="true"> + <exclude-output /> + <content url="file://$MODULE_DIR$"> + <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /> + </content> + <orderEntry type="inheritedJdk" /> + <orderEntry type="sourceFolder" forTests="false" /> + <orderEntry type="library" name="kotlin" level="project" /> + <orderEntry type="library" name="ant-1.9.4" level="project" /> + <orderEntry type="module" module-name="dokka" /> + </component> +</module>
\ No newline at end of file diff --git a/ant/src/dokka-antlib.xml b/ant/src/dokka-antlib.xml new file mode 100644 index 00000000..9c3373d5 --- /dev/null +++ b/ant/src/dokka-antlib.xml @@ -0,0 +1,3 @@ +<antlib> + <taskdef name="dokka" classname="org.jetbrains.dokka.ant.DokkaAntTask"/> +</antlib> diff --git a/ant/src/dokka.kt b/ant/src/dokka.kt new file mode 100644 index 00000000..9510f78b --- /dev/null +++ b/ant/src/dokka.kt @@ -0,0 +1,85 @@ +package org.jetbrains.dokka.ant + +import org.apache.tools.ant.Task +import org.apache.tools.ant.types.Path +import org.apache.tools.ant.types.Reference +import org.apache.tools.ant.BuildException +import org.apache.tools.ant.Project +import org.jetbrains.dokka.DokkaLogger +import org.jetbrains.dokka.DokkaGenerator + +class AntLogger(val task: Task): DokkaLogger { + override fun info(message: String) = task.log(message, Project.MSG_INFO) + override fun warn(message: String) = task.log(message, Project.MSG_WARN) + override fun error(message: String) = task.log(message, Project.MSG_ERR) +} + +class DokkaAntTask(): Task() { + public var moduleName: String? = null + public var outputDir: String? = null + public var outputFormat: String = "html" + + public val compileClasspath: Path = Path(getProject()) + public val sourcePath: Path = Path(getProject()) + public val samplesPath: Path = Path(getProject()) + public val includesPath: Path = Path(getProject()) + + public fun setClasspath(classpath: Path) { + compileClasspath.append(classpath) + } + + public fun setClasspathRef(ref: Reference) { + compileClasspath.createPath().setRefid(ref) + } + + public fun setSrc(src: Path) { + log("setSrc($src)") + sourcePath.append(src) + log("sourcePath=${sourcePath.list().join(",")}") + } + + public fun setSrcRef(ref: Reference) { + sourcePath.createPath().setRefid(ref) + } + + public fun setSamples(samples: Path) { + samplesPath.append(samples) + } + + public fun setSamplesRef(ref: Reference) { + samplesPath.createPath().setRefid(ref) + } + + public fun setInclude(include: Path) { + includesPath.append(include) + } + + override fun execute() { + if (sourcePath.list().size() == 0) { + throw BuildException("At least one source path needs to be specified") + } + if (moduleName == null) { + throw BuildException("Module name needs to be specified") + } + if (outputDir == null) { + throw BuildException("Output directory needs to be specified") + } + + val url = javaClass<DokkaAntTask>().getResource("/org/jetbrains/dokka/ant/DokkaAntTask.class") + val jarRoot = url.getPath().substringBefore("!/").trimLeading("file:") + log(jarRoot) + + val generator = DokkaGenerator( + AntLogger(this), + listOf(jarRoot) + compileClasspath.list().toList(), + sourcePath.list().toList(), + samplesPath.list().toList(), + includesPath.list().toList(), + moduleName!!, + outputDir!!, + outputFormat, + listOf() + ) + generator.generate() + } +}
\ No newline at end of file diff --git a/build.xml b/build.xml new file mode 100644 index 00000000..81a4dea9 --- /dev/null +++ b/build.xml @@ -0,0 +1,9 @@ +<project name="Dokka" default="document"> + <!-- Demonstrates the usage of the Dokka Ant task. Assumes Dokka has already been compiled --> + + <typedef resource="dokka-antlib.xml" classpath="out/artifacts/dokka.jar"/> + + <target name="document"> + <dokka src="src" outputdir="doc" modulename="dokka"/> + </target> +</project> diff --git a/lib/ant-1.9.4.jar b/lib/ant-1.9.4.jar Binary files differnew file mode 100644 index 00000000..24641e74 --- /dev/null +++ b/lib/ant-1.9.4.jar diff --git a/src/Kotlin/DocumentationBuilder.kt b/src/Kotlin/DocumentationBuilder.kt index c0533437..976626db 100644 --- a/src/Kotlin/DocumentationBuilder.kt +++ b/src/Kotlin/DocumentationBuilder.kt @@ -32,7 +32,7 @@ private fun isSamePackage(descriptor1: DeclarationDescriptor, descriptor2: Decla return package1 != null && package2 != null && package1.fqName == package2.fqName } -class DocumentationBuilder(val session: ResolveSession, val options: DocumentationOptions) { +class DocumentationBuilder(val session: ResolveSession, val options: DocumentationOptions, val logger: DokkaLogger) { val visibleToDocumentation = setOf(Visibilities.INTERNAL, Visibilities.PROTECTED, Visibilities.PUBLIC) val descriptorToNode = hashMapOf<DeclarationDescriptor, DocumentationNode>() val nodeToDescriptor = hashMapOf<DocumentationNode, DeclarationDescriptor>() @@ -246,7 +246,7 @@ class DocumentationBuilder(val session: ResolveSession, val options: Documentati descriptors.put(name.asString(), parts.flatMap { it.getMemberScope().getAllDescriptors() }) } for ((packageName, declarations) in descriptors) { - println(" package $packageName: ${declarations.count()} declarations") + logger.info(" package $packageName: ${declarations.count()} declarations") val packageNode = DocumentationNode(packageName, Content.Empty, Kind.Package) val externalClassNodes = hashMapOf<FqName, DocumentationNode>() declarations.forEach { descriptor -> diff --git a/src/main.kt b/src/main.kt index 9ebe0b1e..63725942 100644 --- a/src/main.kt +++ b/src/main.kt @@ -68,95 +68,144 @@ public fun main(args: Array<String>) { listOf() } - val environment = AnalysisEnvironment(MessageCollectorPlainTextToStream.PLAIN_TEXT_TO_SYSTEM_ERR) { - addClasspath(PathUtil.getJdkClassesRoots()) - // addClasspath(PathUtil.getKotlinPathsForCompiler().getRuntimePath()) - for (element in arguments.classpath.split(File.pathSeparatorChar)) { - addClasspath(File(element)) - } - - addSources(sources) - addSources(samples) - } - - println("Module: ${arguments.moduleName}") - println("Output: ${arguments.outputDir}") - println("Sources: ${environment.sources.join()}") - println("Classpath: ${environment.classpath.joinToString()}") + val classPath = arguments.classpath.split(File.pathSeparatorChar).toList() + val generator = DokkaGenerator( + DokkaConsoleLogger, + classPath, + sources, + samples, + includes, + arguments.moduleName, + arguments.outputDir, + arguments.outputFormat, + sourceLinks) + + generator.generate() +} - println() +trait DokkaLogger { + fun info(message: String) + fun warn(message: String) + fun error(message: String) +} - println("Analysing sources and libraries... ") - val startAnalyse = System.currentTimeMillis() +object DokkaConsoleLogger: DokkaLogger { + override fun info(message: String) = println(message) + override fun warn(message: String) = println("WARN: $message") + override fun error(message: String) = println("ERROR: $message") +} +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)) + } +} - val documentation = environment.withContext { environment, session -> - val fragmentFiles = environment.getSourceFiles().filter { - val sourceFile = File(it.getVirtualFile()!!.getPath()) - samples.none { sample -> - val canonicalSample = File(sample).canonicalPath - val canonicalSource = sourceFile.canonicalPath - canonicalSource.startsWith(canonicalSample) +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>) { + fun generate() { + val environment = createAnalysisEnvironment() + + logger.info("Module: ${moduleName}") + logger.info("Output: ${outputDir}") + logger.info("Sources: ${environment.sources.join()}") + logger.info("Classpath: ${environment.classpath.joinToString()}") + + logger.info("Analysing sources and libraries... ") + val startAnalyse = System.currentTimeMillis() + + val documentation = buildDocumentationModule(environment) + + val timeAnalyse = System.currentTimeMillis() - startAnalyse + logger.info("done in ${timeAnalyse / 1000} secs") + + val startBuild = System.currentTimeMillis() + val signatureGenerator = KotlinLanguageService() + val locationService = FoldersLocationService(outputDir) + val templateService = HtmlTemplateService.default("/dokka/styles/style.css") + + val (formatter, outlineFormatter) = when (outputFormat) { + "html" -> { + val htmlFormatService = HtmlFormatService(locationService, signatureGenerator, templateService) + htmlFormatService to htmlFormatService + } + "markdown" -> MarkdownFormatService(locationService, signatureGenerator) to null + "jekyll" -> JekyllFormatService(locationService, signatureGenerator) to null + "kotlin-website" -> KotlinWebsiteFormatService(locationService, signatureGenerator) to + YamlOutlineService(locationService, signatureGenerator) + else -> { + logger.error("Unrecognized output format ${outputFormat}") + null to null } } - val fragments = fragmentFiles.map { session.getPackageFragment(it.getPackageFqName()) }.filterNotNull().distinct() - val options = DocumentationOptions(false, sourceLinks) - val documentationBuilder = DocumentationBuilder(session, options) - - with(documentationBuilder) { - - val moduleContent = Content() - for (include in includes) { - val file = File(include) - if (file.exists()) { - val text = file.readText() - val tree = parseMarkdown(text) - val content = buildContent(tree) - moduleContent.children.addAll(content.children) - } else { - println("WARN: Include file $file was not found.") - } + if (formatter == null) return + + val generator = FileGenerator(signatureGenerator, locationService, formatter, outlineFormatter) + logger.info("Generating pages... ") + generator.buildPage(documentation) + generator.buildOutline(documentation) + val timeBuild = System.currentTimeMillis() - startBuild + logger.info("done in ${timeBuild / 1000} secs") + Disposer.dispose(environment) + } + + fun createAnalysisEnvironment(): AnalysisEnvironment { + val environment = AnalysisEnvironment(DokkaMessageCollector(logger)) { + addClasspath(PathUtil.getJdkClassesRoots()) + // addClasspath(PathUtil.getKotlinPathsForCompiler().getRuntimePath()) + for (element in this@DokkaGenerator.classpath) { + addClasspath(File(element)) } - val documentationModule = DocumentationModule(arguments.moduleName, moduleContent) - documentationModule.appendFragments(fragments) - documentationBuilder.resolveReferences(documentationModule) - documentationModule + addSources(this@DokkaGenerator.sources) + addSources(this@DokkaGenerator.samples) } + return environment } - val timeAnalyse = System.currentTimeMillis() - startAnalyse - println("done in ${timeAnalyse / 1000} secs") - - val startBuild = System.currentTimeMillis() - val signatureGenerator = KotlinLanguageService() - val locationService = FoldersLocationService(arguments.outputDir) - val templateService = HtmlTemplateService.default("/dokka/styles/style.css") + fun buildDocumentationModule(environment: AnalysisEnvironment): DocumentationModule { + val documentation = environment.withContext { environment, session -> + val fragmentFiles = environment.getSourceFiles().filter { + val sourceFile = File(it.getVirtualFile()!!.getPath()) + samples.none { sample -> + val canonicalSample = File(sample).canonicalPath + val canonicalSource = sourceFile.canonicalPath + canonicalSource.startsWith(canonicalSample) + } + } + val fragments = fragmentFiles.map { session.getPackageFragment(it.getPackageFqName()) }.filterNotNull().distinct() + val options = DocumentationOptions(false, sourceLinks) + val documentationBuilder = DocumentationBuilder(session, options, logger) + + with(documentationBuilder) { + + val moduleContent = Content() + for (include in includes) { + val file = File(include) + if (file.exists()) { + val text = file.readText() + val tree = parseMarkdown(text) + val content = buildContent(tree, session.getPackageFragment(FqName.ROOT)) + moduleContent.children.addAll(content.children) + } else { + logger.warn("Include file $file was not found.") + } + } - val (formatter, outlineFormatter) = when (arguments.outputFormat) { - "html" -> { - val htmlFormatService = HtmlFormatService(locationService, signatureGenerator, templateService) - htmlFormatService to htmlFormatService - } - "markdown" -> MarkdownFormatService(locationService, signatureGenerator) to null - "jekyll" -> JekyllFormatService(locationService, signatureGenerator) to null - "kotlin-website" -> KotlinWebsiteFormatService(locationService, signatureGenerator) to - YamlOutlineService(locationService, signatureGenerator) - else -> { - print("Unrecognized output format ${arguments.outputFormat}") - null to null + val documentationModule = DocumentationModule(moduleName, moduleContent) + documentationModule.appendFragments(fragments) + documentationBuilder.resolveReferences(documentationModule) + documentationModule + } } + + return documentation } - if (formatter == null) return - - val generator = FileGenerator(signatureGenerator, locationService, formatter, outlineFormatter) - print("Generating pages... ") - generator.buildPage(documentation) - generator.buildOutline(documentation) - val timeBuild = System.currentTimeMillis() - startBuild - println("done in ${timeBuild / 1000} secs") - println() - println("Done.") - Disposer.dispose(environment) } - diff --git a/test/src/TestAPI.kt b/test/src/TestAPI.kt index 2cdaad5d..b0e23e0f 100644 --- a/test/src/TestAPI.kt +++ b/test/src/TestAPI.kt @@ -38,7 +38,7 @@ public fun verifyModel(vararg files: String, verifier: (DocumentationModule) -> val fragments = environment.getSourceFiles().map { session.getPackageFragment(it.getPackageFqName()) }.filterNotNull().distinct() val documentationModule = DocumentationModule("test") - val documentationBuilder = DocumentationBuilder(session, options) + val documentationBuilder = DocumentationBuilder(session, options, DokkaConsoleLogger) with(documentationBuilder) { documentationModule.appendFragments(fragments) } |