diff options
-rw-r--r-- | src/Generation/ConsoleGenerator.kt | 17 | ||||
-rw-r--r-- | src/Generation/KotlinSignatureGenerator.kt | 114 | ||||
-rw-r--r-- | src/Generation/SignatureGenerator.kt | 10 | ||||
-rw-r--r-- | src/Model/DocumentationModule.kt | 2 | ||||
-rw-r--r-- | src/Model/DocumentationNode.kt | 13 | ||||
-rw-r--r-- | test/data/packages/simpleNamePackage2.kt | 1 | ||||
-rw-r--r-- | test/playground.kt | 18 | ||||
-rw-r--r-- | test/src/model/PackageTest.kt | 24 |
8 files changed, 179 insertions, 20 deletions
diff --git a/src/Generation/ConsoleGenerator.kt b/src/Generation/ConsoleGenerator.kt index 3ba42099..af22a622 100644 --- a/src/Generation/ConsoleGenerator.kt +++ b/src/Generation/ConsoleGenerator.kt @@ -1,34 +1,33 @@ package org.jetbrains.dokka public class ConsoleGenerator() { - val IndentStep = " |" + val signatureGenerator = KotlinSignatureGenerator() + + val IndentStep = " " public fun generate(node: DocumentationNode, indent: String = "") { generateHeader(node, indent) - generateDetails(node, indent) + //generateDetails(node, indent) generateMembers(node, indent) generateLinks(node, indent) } public fun generateHeader(node: DocumentationNode, indent: String = "") { - println("$indent${node.kind}: ${node.name}") - println("$indent\"${node.doc.summary.replace("\n", "\n$indent")}\"") + println(indent + signatureGenerator.render(node)) + val docString = node.doc.toString() + if (!docString.isEmpty()) + println("$indent\"${docString.replace("\n", "\n$indent")}\"") println() } public fun generateMembers(node: DocumentationNode, indent: String = "") { val items = node.members - if (items.isEmpty()) - return - println("$indent Members") for (child in items) generate(child, indent + IndentStep) } public fun generateDetails(node: DocumentationNode, indent: String = "") { val items = node.details - if (items.isEmpty()) - return for (child in items) generate(child, indent + " ") } diff --git a/src/Generation/KotlinSignatureGenerator.kt b/src/Generation/KotlinSignatureGenerator.kt index fad655b0..ee66d37a 100644 --- a/src/Generation/KotlinSignatureGenerator.kt +++ b/src/Generation/KotlinSignatureGenerator.kt @@ -1,7 +1,119 @@ package org.jetbrains.dokka +import org.jetbrains.dokka.DocumentationNode.* + class KotlinSignatureGenerator : SignatureGenerator { - override fun getFunctionSignature(node: DocumentationNode): String { + override fun render(node: DocumentationNode): String { + return when (node.kind) { + Kind.Package -> renderPackage(node) + Kind.Class, + Kind.Trait, + Kind.Object -> renderClass(node) + + Kind.TypeParameter -> renderTypeParameter(node) + Kind.Type, + Kind.UpperBound -> renderType(node) + + Kind.Constructor, + Kind.Function -> renderFunction(node) + Kind.Property -> renderProperty(node) + else -> "${node.kind}: ${node.name}" + } + } + + override fun renderPackage(node: DocumentationNode): String { + return "package ${node.name}" + } + + override fun renderType(node: DocumentationNode): String { return node.name } + + override fun renderTypeParameter(node: DocumentationNode): String { + val constraints = node.details(Kind.UpperBound) + return if (constraints.none()) + node.name + else { + node.name + " : " + constraints.map { renderType(node) }.join() + } + } + + override fun renderParameter(node: DocumentationNode): String { + return node.name + ": " + renderType(node.detail(Kind.Type)) + } + + override fun renderTypeParametersForNode(node: DocumentationNode): String { + return StringBuilder { + val typeParameters = node.details(Kind.TypeParameter) + if (typeParameters.any()) { + append("<") + append(typeParameters.map { renderTypeParameter(it) }.join()) + append("> ") + } + }.toString() + } + + override fun renderClass(node: DocumentationNode): String { + return StringBuilder { + when (node.kind) { + Kind.Class -> append("class ") + Kind.Trait -> append("trait ") + Kind.Object -> append("object ") + else -> throw IllegalArgumentException("Node $node is not a class-like object") + } + + append(node.name) + append(renderTypeParametersForNode(node)) + + append("(") + append(node.details(Kind.Parameter).map { renderParameter(it) }.join()) + append(")") + }.toString() + } + + override fun renderFunction(node: DocumentationNode): String { + return StringBuilder { + when (node.kind) { + Kind.Constructor -> append("init") + Kind.Function -> append("fun ") + else -> throw IllegalArgumentException("Node $node is not a function-like object") + } + append(renderTypeParametersForNode(node)) + val receiver = node.details(Kind.Receiver).firstOrNull() // TODO: replace with singleOrNull when fixed + if (receiver != null) { + append(renderType(receiver.detail(Kind.Type))) + append(".") + } + + if (node.kind != Kind.Constructor) + append(node.name) + + append("(") + append(node.details(Kind.Parameter).map { renderParameter(it) }.join()) + append(")") + if (node.kind != Kind.Constructor) { + append(": ") + append(renderType(node.detail(Kind.Type))) + } + }.toString() + } + + override fun renderProperty(node: DocumentationNode): String { + return StringBuilder { + when (node.kind) { + Kind.Property -> append("val ") + else -> throw IllegalArgumentException("Node $node is not a property") + } + append(renderTypeParametersForNode(node)) + val receiver = node.details(Kind.Receiver).firstOrNull() // TODO: replace with singleOrNull when fixed + if (receiver != null) { + append(renderType(receiver.detail(Kind.Type))) + append(".") + } + + append(node.name) + append(": ") + append(renderType(node.detail(Kind.Type))) + }.toString() + } }
\ No newline at end of file diff --git a/src/Generation/SignatureGenerator.kt b/src/Generation/SignatureGenerator.kt index 2f603327..8ddeddc8 100644 --- a/src/Generation/SignatureGenerator.kt +++ b/src/Generation/SignatureGenerator.kt @@ -1,6 +1,14 @@ package org.jetbrains.dokka trait SignatureGenerator { - fun getFunctionSignature(node: DocumentationNode): String + fun render(node: DocumentationNode): String + fun renderFunction(node: DocumentationNode): String + fun renderClass(node: DocumentationNode): String + fun renderTypeParametersForNode(node: DocumentationNode): String + fun renderTypeParameter(node: DocumentationNode): String + fun renderParameter(node: DocumentationNode): String + fun renderType(node: DocumentationNode): String + fun renderPackage(node: DocumentationNode): String + fun renderProperty(node: DocumentationNode): String } diff --git a/src/Model/DocumentationModule.kt b/src/Model/DocumentationModule.kt index 25cbb600..1f30268e 100644 --- a/src/Model/DocumentationModule.kt +++ b/src/Model/DocumentationModule.kt @@ -4,7 +4,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext import org.jetbrains.jet.lang.psi.JetFile import org.jetbrains.jet.lang.descriptors.* -public class DocumentationModule(val module: ModuleDescriptor) : DocumentationNode(module, "model", DocumentationContent.Empty, DocumentationNode.Kind.Module) { +public class DocumentationModule(val module: ModuleDescriptor) : DocumentationNode(module, "module", DocumentationContent.Empty, DocumentationNode.Kind.Module) { fun merge(other: DocumentationModule): DocumentationModule { val model = DocumentationModule(module) model.addAllReferencesFrom(other) diff --git a/src/Model/DocumentationNode.kt b/src/Model/DocumentationNode.kt index f095e8b0..da0f27e5 100644 --- a/src/Model/DocumentationNode.kt +++ b/src/Model/DocumentationNode.kt @@ -1,6 +1,7 @@ package org.jetbrains.dokka import org.jetbrains.jet.lang.descriptors.* +import java.util.LinkedHashSet public open class DocumentationNode(val descriptor: DeclarationDescriptor, @@ -8,7 +9,7 @@ public open class DocumentationNode(val descriptor: DeclarationDescriptor, val doc: DocumentationContent, val kind: DocumentationNode.Kind) { - private val references = arrayListOf<DocumentationReference>() + private val references = LinkedHashSet<DocumentationReference>() public val owner: DocumentationNode? get() = references(DocumentationReference.Kind.Owner).firstOrNull()?.to // TODO: should be singleOrNull, but bugz! @@ -28,8 +29,16 @@ public open class DocumentationNode(val descriptor: DeclarationDescriptor, references.addAll(other.references) } + public fun details(kind: DocumentationNode.Kind): List<DocumentationNode> = details.filter { it.kind == kind } + public fun members(kind: DocumentationNode.Kind): List<DocumentationNode> = members.filter { it.kind == kind } + public fun links(kind: DocumentationNode.Kind): List<DocumentationNode> = links.filter { it.kind == kind } + + public fun detail(kind: DocumentationNode.Kind): DocumentationNode = details.filter { it.kind == kind }.single() + public fun member(kind: DocumentationNode.Kind): DocumentationNode = members.filter { it.kind == kind }.single() + public fun link(kind: DocumentationNode.Kind): DocumentationNode = links.filter { it.kind == kind }.single() + public fun references(kind: DocumentationReference.Kind): List<DocumentationReference> = references.filter { it.kind == kind } - public fun allReferences(): List<DocumentationReference> = references + public fun allReferences(): Set<DocumentationReference> = references public override fun toString(): String { return "$kind:$name" diff --git a/test/data/packages/simpleNamePackage2.kt b/test/data/packages/simpleNamePackage2.kt new file mode 100644 index 00000000..2c29f4c7 --- /dev/null +++ b/test/data/packages/simpleNamePackage2.kt @@ -0,0 +1 @@ +package simple diff --git a/test/playground.kt b/test/playground.kt index dc2713c7..ca503791 100644 --- a/test/playground.kt +++ b/test/playground.kt @@ -29,10 +29,11 @@ class Class { * This is a class with constructor and space after doc */ -class ClassWithConstructor(/** Doc at parameter */ val name: Class) +class ClassWithConstructor( + /** Doc at parameter */ val name: Class) /** - * This is data class $Person with constructor and two properties + * This is data class with constructor and two properties * * $name Person's name * $age Person's age @@ -46,7 +47,7 @@ object Object { } val objectValue: String - /** one line getter doc */ + /** one line getter doc */ get() = "Member" } @@ -54,15 +55,20 @@ object Object { class OuterClass { /** - * $T: type of the item + * $T type of the item */ class NestedClass<T> { - fun nestedClassFunction() { + fun nestedClassFunction(item: T) { } } inner class InnerClass { - fun innerClassFunction() { + fun innerClassFunction< + /** doc for R1 type param */ + R1, + /** doc for R2 type param */ + R2, + >() { } } diff --git a/test/src/model/PackageTest.kt b/test/src/model/PackageTest.kt index 8fda37ea..aa4bd088 100644 --- a/test/src/model/PackageTest.kt +++ b/test/src/model/PackageTest.kt @@ -65,4 +65,28 @@ public class PackageTest { } } } + + Test fun multipleFilesSamePackage() { + verifyModel("test/data/packages/simpleNamePackage.kt", "test/data/packages/simpleNamePackage2.kt") { model -> + assertEquals(2, model.members.count()) + with(model.members.elementAt(0)) { + assertEquals(DocumentationNode.Kind.Package, kind) + assertEquals("simple", name) + assertEquals(DocumentationContent.Empty, doc) + assertTrue(details.none()) + assertTrue(members.none()) + assertTrue(links.none()) + } + // TODO: Looks like package fragments should be merged into package view in the model + // and here should be single member + with(model.members.elementAt(1)) { + assertEquals(DocumentationNode.Kind.Package, kind) + assertEquals("simple", name) + assertEquals(DocumentationContent.Empty, doc) + assertTrue(details.none()) + assertTrue(members.none()) + assertTrue(links.none()) + } + } + } }
\ No newline at end of file |