aboutsummaryrefslogtreecommitdiff
path: root/core/src/main/kotlin/Languages
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 /core/src/main/kotlin/Languages
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 'core/src/main/kotlin/Languages')
-rw-r--r--core/src/main/kotlin/Languages/JavaLanguageService.kt162
-rw-r--r--core/src/main/kotlin/Languages/LanguageService.kt41
2 files changed, 203 insertions, 0 deletions
diff --git a/core/src/main/kotlin/Languages/JavaLanguageService.kt b/core/src/main/kotlin/Languages/JavaLanguageService.kt
new file mode 100644
index 00000000..7e40beff
--- /dev/null
+++ b/core/src/main/kotlin/Languages/JavaLanguageService.kt
@@ -0,0 +1,162 @@
+package org.jetbrains.dokka
+
+import org.jetbrains.dokka.DocumentationNode.Kind
+import org.jetbrains.dokka.LanguageService.RenderMode
+
+/**
+ * Implements [LanguageService] and provides rendering of symbols in Java language
+ */
+public class JavaLanguageService : LanguageService {
+ override fun render(node: DocumentationNode, renderMode: RenderMode): ContentNode {
+ return ContentText(when (node.kind) {
+ Kind.Package -> renderPackage(node)
+ in Kind.classLike -> 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 renderName(node: DocumentationNode): String {
+ return when (node.kind) {
+ Kind.Constructor -> node.owner!!.name
+ else -> node.name
+ }
+ }
+
+ override fun summarizeSignatures(nodes: List<DocumentationNode>): ContentNode? = null
+
+ private fun renderPackage(node: DocumentationNode): String {
+ return "package ${node.name}"
+ }
+
+ private fun renderModifier(node: DocumentationNode): String {
+ return when (node.name) {
+ "open" -> ""
+ "internal" -> ""
+ else -> node.name
+ }
+ }
+
+ public fun getArrayElementType(node: DocumentationNode): DocumentationNode? = when (node.name) {
+ "Array" -> node.details(Kind.Type).singleOrNull()?.let { et -> getArrayElementType(et) ?: et } ?: DocumentationNode("Object", node.content, DocumentationNode.Kind.ExternalClass)
+ "IntArray", "LongArray", "ShortArray", "ByteArray", "CharArray", "DoubleArray", "FloatArray", "BooleanArray" -> DocumentationNode(node.name.removeSuffix("Array").toLowerCase(), node.content, DocumentationNode.Kind.Type)
+ else -> null
+ }
+
+ public fun getArrayDimension(node: DocumentationNode): Int = when (node.name) {
+ "Array" -> 1 + (node.details(DocumentationNode.Kind.Type).singleOrNull()?.let { getArrayDimension(it) } ?: 0)
+ "IntArray", "LongArray", "ShortArray", "ByteArray", "CharArray", "DoubleArray", "FloatArray", "BooleanArray" -> 1
+ else -> 0
+ }
+
+ public fun renderType(node: DocumentationNode): String {
+ return when (node.name) {
+ "Unit" -> "void"
+ "Int" -> "int"
+ "Long" -> "long"
+ "Double" -> "double"
+ "Float" -> "float"
+ "Char" -> "char"
+ "Boolean" -> "bool"
+ // TODO: render arrays
+ else -> node.name
+ }
+ }
+
+ private fun renderTypeParameter(node: DocumentationNode): String {
+ val constraints = node.details(Kind.UpperBound)
+ return if (constraints.none())
+ node.name
+ else {
+ node.name + " extends " + constraints.map { renderType(node) }.joinToString()
+ }
+ }
+
+ private fun renderParameter(node: DocumentationNode): String {
+ return "${renderType(node.detail(Kind.Type))} ${node.name}"
+ }
+
+ private fun renderTypeParametersForNode(node: DocumentationNode): String {
+ return StringBuilder().apply {
+ val typeParameters = node.details(Kind.TypeParameter)
+ if (typeParameters.any()) {
+ append("<")
+ append(typeParameters.map { renderTypeParameter(it) }.joinToString())
+ append("> ")
+ }
+ }.toString()
+ }
+
+ private fun renderModifiersForNode(node: DocumentationNode): String {
+ val modifiers = node.details(Kind.Modifier).map { renderModifier(it) }.filter { it != "" }
+ if (modifiers.none())
+ return ""
+ return modifiers.joinToString(" ", postfix = " ")
+ }
+
+ private fun renderClass(node: DocumentationNode): String {
+ return StringBuilder().apply {
+ when (node.kind) {
+ Kind.Class -> append("class ")
+ Kind.Interface -> append("interface ")
+ Kind.Enum -> append("enum ")
+ Kind.EnumItem -> append("enum value ")
+ Kind.Object -> append("class ")
+ else -> throw IllegalArgumentException("Node $node is not a class-like object")
+ }
+
+ append(node.name)
+ append(renderTypeParametersForNode(node))
+ }.toString()
+ }
+
+ private fun renderFunction(node: DocumentationNode): String {
+ return StringBuilder().apply {
+ when (node.kind) {
+ Kind.Constructor -> append(node.owner?.name)
+ Kind.Function -> {
+ append(renderTypeParametersForNode(node))
+ append(renderType(node.detail(Kind.Type)))
+ append(" ")
+ append(node.name)
+ }
+ else -> throw IllegalArgumentException("Node $node is not a function-like object")
+ }
+
+ val receiver = node.details(Kind.Receiver).singleOrNull()
+ append("(")
+ if (receiver != null)
+ (listOf(receiver) + node.details(Kind.Parameter)).map { renderParameter(it) }.joinTo(this)
+ else
+ node.details(Kind.Parameter).map { renderParameter(it) }.joinTo(this)
+
+ append(")")
+ }.toString()
+ }
+
+ private fun renderProperty(node: DocumentationNode): String {
+ return StringBuilder().apply {
+ 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).singleOrNull()
+ 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/core/src/main/kotlin/Languages/LanguageService.kt b/core/src/main/kotlin/Languages/LanguageService.kt
new file mode 100644
index 00000000..b0f4bbc9
--- /dev/null
+++ b/core/src/main/kotlin/Languages/LanguageService.kt
@@ -0,0 +1,41 @@
+package org.jetbrains.dokka
+
+/**
+ * Provides facility for rendering [DocumentationNode] as a language-dependent declaration
+ */
+interface LanguageService {
+ enum class RenderMode {
+ /** Brief signature (used in a list of all members of the class). */
+ SUMMARY,
+ /** Full signature (used in the page describing the member itself */
+ FULL
+ }
+
+ /**
+ * Renders a [node] as a class, function, property or other signature in a target language.
+ * @param node A [DocumentationNode] to render
+ * @return [ContentNode] which is a root for a rich content tree suitable for formatting with [FormatService]
+ */
+ fun render(node: DocumentationNode, renderMode: RenderMode = RenderMode.FULL): ContentNode
+
+ /**
+ * Tries to summarize the signatures of the specified documentation nodes in a compact representation.
+ * Returns the representation if successful, or null if the signatures could not be summarized.
+ */
+ fun summarizeSignatures(nodes: List<DocumentationNode>): ContentNode?
+
+ /**
+ * Renders [node] as a named representation in the target language
+ *
+ * For example:
+ * ${code org.jetbrains.dokka.example}
+ *
+ * $node: A [DocumentationNode] to render
+ * $returns: [String] which is a string representation of the node's name
+ */
+ fun renderName(node: DocumentationNode): String
+}
+
+fun example(service: LanguageService, node: DocumentationNode) {
+ println("Node name: ${service.renderName(node)}")
+} \ No newline at end of file