diff options
-rw-r--r-- | src/Analysis/CommentsAPI.kt | 21 | ||||
-rw-r--r-- | src/Generation/ConsoleGenerator.kt | 27 | ||||
-rw-r--r-- | src/Model/DocumentationBuilder.kt | 12 | ||||
-rw-r--r-- | src/main.kt | 23 | ||||
-rw-r--r-- | test/data/comments/emptyDoc.kt | 1 | ||||
-rw-r--r-- | test/data/comments/emptyDocButComment.kt | 2 | ||||
-rw-r--r-- | test/data/comments/multilineDoc.kt | 6 | ||||
-rw-r--r-- | test/data/comments/multilineDocWithComment.kt | 7 | ||||
-rw-r--r-- | test/data/comments/multipleDocs.kt | 8 | ||||
-rw-r--r-- | test/data/comments/oneLineDoc.kt | 2 | ||||
-rw-r--r-- | test/data/comments/oneLineDocWithComment.kt | 3 | ||||
-rw-r--r-- | test/data/comments/oneLineDocWithEmptyLine.kt | 3 | ||||
-rw-r--r-- | test/playground.kt | 6 | ||||
-rw-r--r-- | test/src/model/CommentTest.kt | 76 |
14 files changed, 180 insertions, 17 deletions
diff --git a/src/Analysis/CommentsAPI.kt b/src/Analysis/CommentsAPI.kt index a32ee734..03b1911c 100644 --- a/src/Analysis/CommentsAPI.kt +++ b/src/Analysis/CommentsAPI.kt @@ -5,12 +5,21 @@ import org.jetbrains.jet.lang.resolve.* import org.jetbrains.jet.kdoc.psi.api.* import org.jetbrains.jet.lang.psi.* -fun BindingContext.getDocumentation(descriptor: DeclarationDescriptor): KDoc? { +fun BindingContext.getDocumentation(descriptor: DeclarationDescriptor): String { + return getDocumentationElements(descriptor).map { it.extractText() }.join("\n") +} + +fun BindingContext.getDocumentationElements(descriptor: DeclarationDescriptor): List<KDoc> { val psiElement = DescriptorToSourceUtils.descriptorToDeclaration(descriptor) if (psiElement == null) throw IllegalArgumentException("$descriptor doesn't have connection to source code, is it synthetic?") - return psiElement.previousSiblings().takeWhile { it !is JetDeclaration }.firstOrNull { it is KDoc } as KDoc? + return psiElement.previousSiblings() // go backwards + .takeWhile { it !is JetDeclaration } // till previous declaration + .filter { it is KDoc } // get KDocs + .map { it as KDoc } // cast + .toList() + .reverse() // make reversed list } fun KDoc?.extractText(): String { @@ -21,10 +30,14 @@ fun KDoc?.extractText(): String { return "" val lines = text.replace("\r", "").split("\n") return lines.map { - it.dropWhile { java.lang.Character.isWhitespace(it) } + val comment = it.trim() .dropWhile { it == '/' } .dropWhile { it == '*' } .dropWhile { it == '/' } - .dropWhile { java.lang.Character.isWhitespace(it) } + .trim() + if (comment.endsWith("*/")) + comment.substring(0, comment.length - 2).trim() + else + comment }.filter { it.any() }.join("\n") }
\ No newline at end of file diff --git a/src/Generation/ConsoleGenerator.kt b/src/Generation/ConsoleGenerator.kt new file mode 100644 index 00000000..e46cac31 --- /dev/null +++ b/src/Generation/ConsoleGenerator.kt @@ -0,0 +1,27 @@ +package org.jetbrains.dokka + +public class ConsoleGenerator() { + val IndentStep = " " + + public fun generate(node: DocumentationNode, indent: String = "") { + generateHeader(node, indent) + generateDetails(node, indent) + generateMembers(node, indent) + } + + public fun generateHeader(node: DocumentationNode, indent: String = "") { + println("$indent${node.kind}: ${node.name}") + println("$indent\"${node.doc.replace("\n", "\n$indent")}\"") + println() + } + + public fun generateDetails(node: DocumentationNode, indent: String = "") { + for (child in node.details) + generate(child, indent + IndentStep) + } + + public fun generateMembers(node: DocumentationNode, indent: String = "") { + for (child in node.members) + generate(child, indent + IndentStep) + } +}
\ No newline at end of file diff --git a/src/Model/DocumentationBuilder.kt b/src/Model/DocumentationBuilder.kt index 77f74eb2..08298926 100644 --- a/src/Model/DocumentationBuilder.kt +++ b/src/Model/DocumentationBuilder.kt @@ -19,21 +19,21 @@ fun BindingContext.createDocumentation(file: JetFile): DocumentationModel { class DocumentationBuilderVisitor(val context: BindingContext) : DeclarationDescriptorVisitorEmptyBodies<DocumentationNode, DocumentationNode>() { override fun visitDeclarationDescriptor(descriptor: DeclarationDescriptor?, data: DocumentationNode?): DocumentationNode? { - val doc = context.getDocumentation(descriptor!!).extractText() + val doc = context.getDocumentation(descriptor!!) val node = DocumentationNode(descriptor.getName().asString(), doc, DocumentationNodeKind.Unknown) data?.addReferenceTo(node, DocumentationReferenceKind.Member) return node } override fun visitValueParameterDescriptor(descriptor: ValueParameterDescriptor?, data: DocumentationNode?): DocumentationNode? { - val doc = context.getDocumentation(descriptor!!).extractText() + val doc = context.getDocumentation(descriptor!!) val node = DocumentationNode(descriptor.getName().asString(), doc, DocumentationNodeKind.Parameter) data?.addReferenceTo(node, DocumentationReferenceKind.Detail) return node } override fun visitClassDescriptor(descriptor: ClassDescriptor?, data: DocumentationNode?): DocumentationNode? { - val doc = context.getDocumentation(descriptor!!).extractText() + val doc = context.getDocumentation(descriptor!!) val node = DocumentationNode(descriptor.getName().asString(), doc, when (descriptor.getKind()) { ClassKind.OBJECT -> DocumentationNodeKind.Object @@ -45,21 +45,21 @@ class DocumentationBuilderVisitor(val context: BindingContext) : DeclarationDesc } override fun visitFunctionDescriptor(descriptor: FunctionDescriptor?, data: DocumentationNode?): DocumentationNode? { - val doc = context.getDocumentation(descriptor!!).extractText() + val doc = context.getDocumentation(descriptor!!) val node = DocumentationNode(descriptor.getName().asString(), doc, DocumentationNodeKind.Function) data?.addReferenceTo(node, DocumentationReferenceKind.Member) return node } override fun visitPropertyDescriptor(descriptor: PropertyDescriptor?, data: DocumentationNode?): DocumentationNode? { - val doc = context.getDocumentation(descriptor!!).extractText() + val doc = context.getDocumentation(descriptor!!) val node = DocumentationNode(descriptor.getName().asString(), doc, DocumentationNodeKind.Property) data?.addReferenceTo(node, DocumentationReferenceKind.Member) return node } override fun visitConstructorDescriptor(descriptor: ConstructorDescriptor?, data: DocumentationNode?): DocumentationNode? { - val doc = context.getDocumentation(descriptor!!).extractText() + val doc = context.getDocumentation(descriptor!!) val node = DocumentationNode(descriptor.getName().asString(), doc, DocumentationNodeKind.Constructor) data?.addReferenceTo(node, DocumentationReferenceKind.Member) return node diff --git a/src/main.kt b/src/main.kt index e385da3f..79a8bfcb 100644 --- a/src/main.kt +++ b/src/main.kt @@ -3,15 +3,23 @@ package org.jetbrains.dokka import com.sampullara.cli.* import com.intellij.openapi.util.* import org.jetbrains.jet.cli.common.messages.* -import org.jetbrains.jet.utils.* -import org.jetbrains.jet.lang.resolve.BindingContext -import org.jetbrains.jet.lang.psi.JetFile -import org.jetbrains.jet.cli.common.arguments.K2JVMCompilerArguments +import org.jetbrains.jet.cli.common.arguments.* + +class DokkaArguments { + Argument(value = "src", description = "Source file or directory (allows many paths separated by the system path separator)") + ValueDescription("<path>") + public var src: String? = null + + Argument(value = "output", description = "Output directory path for .md files") + ValueDescription("<path>") + public var outputDir: String? = null +} public fun main(args: Array<String>) { - val compilerArguments = K2JVMCompilerArguments() - val sources: List<String> = Args.parse(compilerArguments, args) ?: listOf() + val arguments = DokkaArguments() + val sourceFiles = Args.parse(arguments, args) + val sources: List<String> = sourceFiles ?: listOf() val environment = AnalysisEnvironment(MessageCollectorPlainTextToStream.PLAIN_TEXT_TO_SYSTEM_ERR) { /* @@ -32,6 +40,7 @@ public fun main(args: Array<String>) { context.createDocumentation(file) }.fold(DocumentationModel()) {(aggregate, item) -> aggregate.merge(item) } - println(model) + ConsoleGenerator().generate(model) + Disposer.dispose(environment) }
\ No newline at end of file diff --git a/test/data/comments/emptyDoc.kt b/test/data/comments/emptyDoc.kt new file mode 100644 index 00000000..b87cce57 --- /dev/null +++ b/test/data/comments/emptyDoc.kt @@ -0,0 +1 @@ +val property = "test"
\ No newline at end of file diff --git a/test/data/comments/emptyDocButComment.kt b/test/data/comments/emptyDocButComment.kt new file mode 100644 index 00000000..ceb24753 --- /dev/null +++ b/test/data/comments/emptyDocButComment.kt @@ -0,0 +1,2 @@ +/* comment */ +val property = "test"
\ No newline at end of file diff --git a/test/data/comments/multilineDoc.kt b/test/data/comments/multilineDoc.kt new file mode 100644 index 00000000..960c78bd --- /dev/null +++ b/test/data/comments/multilineDoc.kt @@ -0,0 +1,6 @@ +/** + * doc1 + * doc2 + * doc3 + */ +val property = "test"
\ No newline at end of file diff --git a/test/data/comments/multilineDocWithComment.kt b/test/data/comments/multilineDocWithComment.kt new file mode 100644 index 00000000..d3c1084c --- /dev/null +++ b/test/data/comments/multilineDocWithComment.kt @@ -0,0 +1,7 @@ +/** + * doc1 + * doc2 + * doc3 + */ +// comment +val property = "test"
\ No newline at end of file diff --git a/test/data/comments/multipleDocs.kt b/test/data/comments/multipleDocs.kt new file mode 100644 index 00000000..654ea935 --- /dev/null +++ b/test/data/comments/multipleDocs.kt @@ -0,0 +1,8 @@ +/** + * doc1 + */ +/** + * doc2 + */ +/** doc3 */ +val property = "test"
\ No newline at end of file diff --git a/test/data/comments/oneLineDoc.kt b/test/data/comments/oneLineDoc.kt new file mode 100644 index 00000000..92a40c67 --- /dev/null +++ b/test/data/comments/oneLineDoc.kt @@ -0,0 +1,2 @@ +/** doc */ +val property = "test"
\ No newline at end of file diff --git a/test/data/comments/oneLineDocWithComment.kt b/test/data/comments/oneLineDocWithComment.kt new file mode 100644 index 00000000..c8467933 --- /dev/null +++ b/test/data/comments/oneLineDocWithComment.kt @@ -0,0 +1,3 @@ +/** doc */ +// comment +val property = "test"
\ No newline at end of file diff --git a/test/data/comments/oneLineDocWithEmptyLine.kt b/test/data/comments/oneLineDocWithEmptyLine.kt new file mode 100644 index 00000000..e364c416 --- /dev/null +++ b/test/data/comments/oneLineDocWithEmptyLine.kt @@ -0,0 +1,3 @@ +/** doc */ + +val property = "test"
\ No newline at end of file diff --git a/test/playground.kt b/test/playground.kt index 5bc5207a..50a43dfd 100644 --- a/test/playground.kt +++ b/test/playground.kt @@ -21,6 +21,7 @@ class Class { fun memberFunction() { } + val memberValue = "Member" } /** @@ -38,6 +39,11 @@ data class DataClass(val name: String, val age: Int) {} object Object { fun objectFunction() { } + + val objectValue: String + /** one line getter doc */ + get() = "Member" + } class OuterClass { diff --git a/test/src/model/CommentTest.kt b/test/src/model/CommentTest.kt new file mode 100644 index 00000000..7da50c1a --- /dev/null +++ b/test/src/model/CommentTest.kt @@ -0,0 +1,76 @@ +package org.jetbrains.dokka.tests + +import org.junit.Test +import kotlin.test.* + +public class CommentTest { + Test fun emptyDoc() { + verifyModel("test/data/comments/emptyDoc.kt") { model -> + with(model.nodes.single().members.single()) { + assertEquals("", doc) + } + } + } + + Test fun emptyDocButComment() { + verifyModel("test/data/comments/emptyDocButComment.kt") { model -> + with(model.nodes.single().members.single()) { + assertEquals("", doc) + } + } + } + + Test fun multilineDoc() { + verifyModel("test/data/comments/multilineDoc.kt") { model -> + with(model.nodes.single().members.single()) { + assertEquals("""doc1 +doc2 +doc3""", doc) + } + } + } + + Test fun multipleDocs() { + verifyModel("test/data/comments/multipleDocs.kt") { model -> + with(model.nodes.single().members.single()) { + assertEquals("""doc1 +doc2 +doc3""", doc) + } + } + } + + Test fun multilineDocWithComment() { + verifyModel("test/data/comments/multilineDocWithComment.kt") { model -> + with(model.nodes.single().members.single()) { + assertEquals("""doc1 +doc2 +doc3""", doc) + } + } + } + + Test fun oneLineDoc() { + verifyModel("test/data/comments/oneLineDoc.kt") { model -> + with(model.nodes.single().members.single()) { + assertEquals("doc", doc) + } + } + } + + Test fun oneLineDocWithComment() { + verifyModel("test/data/comments/oneLineDocWithComment.kt") { model -> + with(model.nodes.single().members.single()) { + assertEquals("doc", doc) + } + } + } + + Test fun oneLineDocWithEmptyLine() { + verifyModel("test/data/comments/oneLineDocWithEmptyLine.kt") { model -> + with(model.nodes.single().members.single()) { + assertEquals("doc", doc) + } + } + } +} |