diff options
author | Ilya Ryzhenkov <orangy@jetbrains.com> | 2014-07-14 15:00:33 +0400 |
---|---|---|
committer | Ilya Ryzhenkov <orangy@jetbrains.com> | 2014-07-14 15:00:33 +0400 |
commit | a0bfdbd8cc365cb11c26e81ee7587f0ec25df79d (patch) | |
tree | c68610d2003d2a4712b3fbc95561ac20390a161d | |
parent | 6168541bd5bb141c40a1e2a909afa84441b35ed5 (diff) | |
download | dokka-a0bfdbd8cc365cb11c26e81ee7587f0ec25df79d.tar.gz dokka-a0bfdbd8cc365cb11c26e81ee7587f0ec25df79d.tar.bz2 dokka-a0bfdbd8cc365cb11c26e81ee7587f0ec25df79d.zip |
Location services, formatting services, initial self-documentation output.
-rw-r--r-- | src/Analysis/CommentsAPI.kt | 2 | ||||
-rw-r--r-- | src/Analysis/CompilerAPI.kt | 2 | ||||
-rw-r--r-- | src/Formats/FormatService.kt | 8 | ||||
-rw-r--r-- | src/Formats/HtmlFormatService.kt | 62 | ||||
-rw-r--r-- | src/Formats/MarkdownFormatService.kt | 34 | ||||
-rw-r--r-- | src/Formats/TextFormatService.kt | 19 | ||||
-rw-r--r-- | src/Generation/ConsoleGenerator.kt | 3 | ||||
-rw-r--r-- | src/Generation/FileGenerator.kt | 18 | ||||
-rw-r--r-- | src/Generation/JavaSignatureGenerator.kt | 2 | ||||
-rw-r--r-- | src/Generation/KotlinSignatureGenerator.kt | 2 | ||||
-rw-r--r-- | src/Generation/SignatureGenerator.kt | 4 | ||||
-rw-r--r-- | src/Locations/FoldersLocationService.kt | 17 | ||||
-rw-r--r-- | src/Locations/LocationService.kt | 18 | ||||
-rw-r--r-- | src/Locations/SingleFolderLocationService.kt | 11 | ||||
-rw-r--r-- | src/Model/Diagnostics.kt | 2 | ||||
-rw-r--r-- | src/Model/DocumentationNode.kt | 8 | ||||
-rw-r--r-- | src/Utilities/Path.kt | 21 | ||||
-rw-r--r-- | src/main.kt | 8 |
18 files changed, 229 insertions, 12 deletions
diff --git a/src/Analysis/CommentsAPI.kt b/src/Analysis/CommentsAPI.kt index a1823740..5df4bd38 100644 --- a/src/Analysis/CommentsAPI.kt +++ b/src/Analysis/CommentsAPI.kt @@ -26,7 +26,7 @@ fun KDoc?.extractText(): String { return "" val lines = text.replace("\r", "").split("\n") return lines.map { - val comment = it.trim().dropWhile { it == '/' || it == '*'} + val comment = it.trim().dropWhile { it == '/' || it == '*' } (if (comment.endsWith("*/")) comment.substring(0, comment.length - 2) else diff --git a/src/Analysis/CompilerAPI.kt b/src/Analysis/CompilerAPI.kt index a9dc3b0c..bc0e6e93 100644 --- a/src/Analysis/CompilerAPI.kt +++ b/src/Analysis/CompilerAPI.kt @@ -66,7 +66,7 @@ fun DeclarationDescriptor.isUserCode() = public fun getPackageInnerScope(descriptor: PackageFragmentDescriptor): JetScope { val module = descriptor.getContainingDeclaration() val packageScope = ChainedScope(descriptor, "Package ${descriptor.getName()} scope", descriptor.getMemberScope(), - module.getPackage(FqName.ROOT)!!.getMemberScope()) + module.getPackage(FqName.ROOT)!!.getMemberScope()) return packageScope } diff --git a/src/Formats/FormatService.kt b/src/Formats/FormatService.kt new file mode 100644 index 00000000..9e36c400 --- /dev/null +++ b/src/Formats/FormatService.kt @@ -0,0 +1,8 @@ +package org.jetbrains.dokka + +public trait FormatService { + val extension: String + fun format(node: DocumentationNode, to: StringBuilder) +} + +fun FormatService.format(node: DocumentationNode): String = StringBuilder { format(node, this) }.toString()
\ No newline at end of file diff --git a/src/Formats/HtmlFormatService.kt b/src/Formats/HtmlFormatService.kt new file mode 100644 index 00000000..4a0bca6f --- /dev/null +++ b/src/Formats/HtmlFormatService.kt @@ -0,0 +1,62 @@ +package org.jetbrains.dokka + +public class HtmlFormatService(val locationService: LocationService, + val signatureGenerator: SignatureGenerator) : FormatService { + override val extension: String = "html" + override fun format(node: DocumentationNode, to: StringBuilder) { + with (to) { + appendln("<h2>") + appendln("Summary for ${node.name}") + appendln("</h2>") + appendln("<code>") + appendln(signatureGenerator.render(node)) + appendln("</code>") + appendln() + appendln("<p>") + appendln(node.doc.summary) + appendln("</p>") + appendln("<hr/>") + + for (section in node.doc.sections) { + appendln("<h3>") + appendln(section.label) + appendln("</h3>") + appendln("<p>") + appendln(section.text) + appendln("</p>") + } + + appendln("<h3>") + appendln("Members") + appendln("</h3>") + appendln("<table>") + + appendln("<thead>") + appendln("<tr>") + appendln("<td>Member</td>") + appendln("<td>Signature</td>") + appendln("<td>Summary</td>") + appendln("</tr>") + appendln("</thead>") + + appendln("<tbody>") + for (member in node.members.sortBy { it.name }) { + val relativePath = locationService.relativeLocation(node, member, extension) + appendln("<tr>") + appendln("<td>") + append("<a href=\"${relativePath}\">${member.name}</a>") + appendln("</td>") + appendln("<td>") + append("${signatureGenerator.render(member)}") + appendln("</td>") + appendln("<td>") + append("${member.doc.summary}") + appendln("</td>") + appendln("</tr>") + } + appendln("</tbody>") + appendln("</table>") + + } + } +}
\ No newline at end of file diff --git a/src/Formats/MarkdownFormatService.kt b/src/Formats/MarkdownFormatService.kt new file mode 100644 index 00000000..032667dd --- /dev/null +++ b/src/Formats/MarkdownFormatService.kt @@ -0,0 +1,34 @@ +package org.jetbrains.dokka + +public class MarkdownFormatService(val locationService: LocationService, + val signatureGenerator: SignatureGenerator) : FormatService { + override val extension: String = "md" + override fun format(node: DocumentationNode, to: StringBuilder) { + with (to) { + appendln(node.path.map { "[${it.name}](${locationService.relativeLocation(node, it, extension)})" }.joinToString(" / ")) + appendln() + append("# ") + appendln(signatureGenerator.render(node)) + appendln() + appendln(node.doc.summary) + appendln() + for (section in node.doc.sections) { + append("### ") + appendln(section.label) + appendln(section.text) + } + + + appendln("### Members") + appendln("| Name | Signature | Summary |") + appendln("|------|-----------|---------|") + for (member in node.members.sortBy { it.name }) { + val relativePath = locationService.relativeLocation(node, member, extension) + append("|[${member.name}](${relativePath})") + append("|${signatureGenerator.render(member)}") + append("|${member.doc.summary} ") + appendln("|") + } + } + } +}
\ No newline at end of file diff --git a/src/Formats/TextFormatService.kt b/src/Formats/TextFormatService.kt new file mode 100644 index 00000000..1da1c0d0 --- /dev/null +++ b/src/Formats/TextFormatService.kt @@ -0,0 +1,19 @@ +package org.jetbrains.dokka + +public class TextFormatService(val signatureGenerator: SignatureGenerator) : FormatService { + override val extension: String = "txt" + override fun format(node: DocumentationNode, to: StringBuilder) { + with (to) { + appendln(signatureGenerator.render(node)) + appendln() + appendln(node.doc.summary) + for (n in node.doc.summary.indices) + append("=") + + for (section in node.doc.sections) { + appendln(section.label) + appendln(section.text) + } + } + } +}
\ No newline at end of file diff --git a/src/Generation/ConsoleGenerator.kt b/src/Generation/ConsoleGenerator.kt index 17fb6532..17e6957b 100644 --- a/src/Generation/ConsoleGenerator.kt +++ b/src/Generation/ConsoleGenerator.kt @@ -1,9 +1,10 @@ package org.jetbrains.dokka -public class ConsoleGenerator(val signatureGenerator : SignatureGenerator) { +public class ConsoleGenerator(val signatureGenerator: SignatureGenerator, val locationService: LocationService) { val IndentStep = " " public fun generate(node: DocumentationNode, indent: String = "") { + println("@${locationService.location(node).file}") generateHeader(node, indent) //generateDetails(node, indent) generateMembers(node, indent) diff --git a/src/Generation/FileGenerator.kt b/src/Generation/FileGenerator.kt new file mode 100644 index 00000000..c1e88a76 --- /dev/null +++ b/src/Generation/FileGenerator.kt @@ -0,0 +1,18 @@ +package org.jetbrains.dokka + +import java.io.File + +public class FileGenerator(val signatureGenerator: SignatureGenerator, + val locationService: LocationService, + val formatService: FormatService) { + public fun generate(node: DocumentationNode) { + val location = locationService.location(node) + println("@${location.file} : ${signatureGenerator.render(node)}") + val file = location.file.appendExtension(formatService.extension) + file.getParentFile()?.mkdirs() + file.writeText(formatService.format(node), defaultCharset) + val items = node.members.sortBy { it.name } + for (child in items) + generate(child) + } +}
\ No newline at end of file diff --git a/src/Generation/JavaSignatureGenerator.kt b/src/Generation/JavaSignatureGenerator.kt index 774eaeb4..e7458eba 100644 --- a/src/Generation/JavaSignatureGenerator.kt +++ b/src/Generation/JavaSignatureGenerator.kt @@ -74,7 +74,7 @@ class JavaSignatureGenerator : SignatureGenerator { } override fun renderModifiersForNode(node: DocumentationNode): String { - val modifiers = node.details(Kind.Modifier).map { renderModifier(it) }.filter { it != ""} + val modifiers = node.details(Kind.Modifier).map { renderModifier(it) }.filter { it != "" } if (modifiers.none()) return "" return modifiers.join(" ", postfix = " ") diff --git a/src/Generation/KotlinSignatureGenerator.kt b/src/Generation/KotlinSignatureGenerator.kt index 50704f1c..1fae62f0 100644 --- a/src/Generation/KotlinSignatureGenerator.kt +++ b/src/Generation/KotlinSignatureGenerator.kt @@ -65,7 +65,7 @@ class KotlinSignatureGenerator : SignatureGenerator { } override fun renderModifiersForNode(node: DocumentationNode): String { - val modifiers = node.details(Kind.Modifier).map { renderModifier(it) }.filter { it != ""} + val modifiers = node.details(Kind.Modifier).map { renderModifier(it) }.filter { it != "" } if (modifiers.none()) return "" return modifiers.join(" ", postfix = " ") diff --git a/src/Generation/SignatureGenerator.kt b/src/Generation/SignatureGenerator.kt index 176f8d40..158c4336 100644 --- a/src/Generation/SignatureGenerator.kt +++ b/src/Generation/SignatureGenerator.kt @@ -10,7 +10,7 @@ trait SignatureGenerator { fun renderType(node: DocumentationNode): String fun renderPackage(node: DocumentationNode): String fun renderProperty(node: DocumentationNode): String - open fun renderModifier(node: DocumentationNode): String - open fun renderModifiersForNode(node: DocumentationNode): String + fun renderModifier(node: DocumentationNode): String + fun renderModifiersForNode(node: DocumentationNode): String } diff --git a/src/Locations/FoldersLocationService.kt b/src/Locations/FoldersLocationService.kt new file mode 100644 index 00000000..6bfa9446 --- /dev/null +++ b/src/Locations/FoldersLocationService.kt @@ -0,0 +1,17 @@ +package org.jetbrains.dokka + +import java.io.File + +public fun FoldersLocationService(root: String): FoldersLocationService = FoldersLocationService(File(root)) +public class FoldersLocationService(val root: File) : LocationService { + override fun location(node: DocumentationNode): Location { + val parts = node.path.map { escapeUri(it.name) } + val folder = if (node.members.none()) { + // leaf node, use file in owner's folder + parts.joinToString("/", limit = parts.size - 1, truncated = "") + "/" + parts.last() + } else { + parts.joinToString("/") + (if (parts.none()) "" else "/") + "index" + } + return Location(File(root, folder)) + } +}
\ No newline at end of file diff --git a/src/Locations/LocationService.kt b/src/Locations/LocationService.kt new file mode 100644 index 00000000..03f22d08 --- /dev/null +++ b/src/Locations/LocationService.kt @@ -0,0 +1,18 @@ +package org.jetbrains.dokka + +import java.io.File + +data class Location(val file: File) + +public trait LocationService { + fun location(node: DocumentationNode): Location +} + + +public fun escapeUri(path: String): String = path.replace('<', '_').replace('>', '_') + +fun LocationService.relativeLocation(node: DocumentationNode, link: DocumentationNode, extension: String): File { + val ownerFolder = location(node).file.getParentFile()!! + val memberPath = location(link).file.appendExtension(extension) + return ownerFolder.getRelativePath(memberPath) +} diff --git a/src/Locations/SingleFolderLocationService.kt b/src/Locations/SingleFolderLocationService.kt new file mode 100644 index 00000000..8fc6a201 --- /dev/null +++ b/src/Locations/SingleFolderLocationService.kt @@ -0,0 +1,11 @@ +package org.jetbrains.dokka + +import java.io.File + +public fun SingleFolderLocationService(root: String): SingleFolderLocationService = SingleFolderLocationService(File(root)) +public class SingleFolderLocationService(val root: File) : LocationService { + override fun location(node: DocumentationNode): Location { + val filename = node.path.map { escapeUri(it.name) }.joinToString("-") + return Location(File(root, filename)) + } +}
\ No newline at end of file diff --git a/src/Model/Diagnostics.kt b/src/Model/Diagnostics.kt index a464107f..1077da7c 100644 --- a/src/Model/Diagnostics.kt +++ b/src/Model/Diagnostics.kt @@ -4,7 +4,7 @@ import org.jetbrains.jet.lang.descriptors.* import org.jetbrains.jet.lang.resolve.name.* import org.jetbrains.jet.lang.resolve.BindingContext -fun BindingContext.checkResolveChildren(node : DocumentationNode) { +fun BindingContext.checkResolveChildren(node: DocumentationNode) { if (node.kind != DocumentationNode.Kind.Module && node.kind != DocumentationNode.Kind.Package) { // TODO: we don't resolve packages and modules for now diff --git a/src/Model/DocumentationNode.kt b/src/Model/DocumentationNode.kt index 8132c419..5469774d 100644 --- a/src/Model/DocumentationNode.kt +++ b/src/Model/DocumentationNode.kt @@ -73,4 +73,10 @@ public open class DocumentationNode(val descriptor: DeclarationDescriptor, } - +val DocumentationNode.path: List<DocumentationNode> + get() { + val parent = owner + if (parent == null) + return listOf(this) + return parent.path + this + }
\ No newline at end of file diff --git a/src/Utilities/Path.kt b/src/Utilities/Path.kt new file mode 100644 index 00000000..5498d36e --- /dev/null +++ b/src/Utilities/Path.kt @@ -0,0 +1,21 @@ +package org.jetbrains.dokka + +import java.io.* + +fun File.getRelativePath(name: File): File { + val parent = getParentFile() + + if (parent == null) + throw IOException("No common directory"); + + val basePath = getCanonicalPath(); + val targetPath = name.getCanonicalPath(); + + if (targetPath.startsWith(basePath)) { + return File(targetPath.substring(basePath.length() + 1)) + } else { + return File(".." + File.separator + parent.getRelativePath(name)) + } +} + +fun File.appendExtension(extension: String) = File(getPath() + "." + extension) diff --git a/src/main.kt b/src/main.kt index 0faa357b..fbbb53d6 100644 --- a/src/main.kt +++ b/src/main.kt @@ -4,7 +4,6 @@ import com.sampullara.cli.* import com.intellij.openapi.util.* import org.jetbrains.jet.cli.common.messages.* import org.jetbrains.jet.cli.common.arguments.* -import org.jetbrains.jet.utils.PathUtil class DokkaArguments { Argument(value = "src", description = "Source file or directory (allows many paths separated by the system path separator)") @@ -41,7 +40,10 @@ public fun main(args: Array<String>) { context.createDocumentationModule(module, file) }.reduce {(aggregate, item) -> aggregate.merge(item) } - ConsoleGenerator(KotlinSignatureGenerator()).generate(documentation) - + val signatureGenerator = KotlinSignatureGenerator() + val locationService = FoldersLocationService(arguments.outputDir ?: "out/doc/") + val markdown = MarkdownFormatService(locationService, signatureGenerator) + val generator = FileGenerator(signatureGenerator, locationService, markdown) + generator.generate(documentation) Disposer.dispose(environment) }
\ No newline at end of file |