aboutsummaryrefslogtreecommitdiff
path: root/core/src/main/kotlin/model
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/main/kotlin/model')
-rw-r--r--core/src/main/kotlin/model/DocumentationNode.kt162
1 files changed, 162 insertions, 0 deletions
diff --git a/core/src/main/kotlin/model/DocumentationNode.kt b/core/src/main/kotlin/model/DocumentationNode.kt
new file mode 100644
index 00000000..77225eca
--- /dev/null
+++ b/core/src/main/kotlin/model/DocumentationNode.kt
@@ -0,0 +1,162 @@
+package org.jetbrains.dokka.model
+
+import org.jetbrains.dokka.transformers.descriptors.KotlinTypeWrapper
+import org.jetbrains.dokka.links.DRI
+import org.jetbrains.dokka.pages.PlatformData
+import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag
+
+class Module(val packages: List<Package>) : DocumentationNode() {
+ override val dri: DRI = DRI.topLevel
+ override val children: List<Package> = packages
+ override val extra: MutableSet<Extra> = mutableSetOf()
+}
+
+class Package(
+ override val dri: DRI,
+ override val functions: List<Function>,
+ override val properties: List<Property>,
+ override val classes: List<Class>,
+ override val extra: MutableSet<Extra> = mutableSetOf()
+) : ScopeNode() {
+ override val name = dri.packageName.orEmpty()
+}
+
+class Class(
+ override val dri: DRI,
+ override val name: String,
+ val kind: ClassKind,
+ val constructors: List<Function>,
+ override val functions: List<Function>,
+ override val properties: List<Property>,
+ override val classes: List<Class>,
+ override val expected: ClassPlatformInfo?,
+ override val actual: List<ClassPlatformInfo>,
+ override val extra: MutableSet<Extra> = mutableSetOf()
+) : ScopeNode() {
+ val inherited by lazy { platformInfo.mapNotNull { (it as? ClassPlatformInfo)?.inherited }.flatten() }
+}
+
+class Function(
+ override val dri: DRI,
+ override val name: String,
+ val returnType: TypeWrapper?,
+ val isConstructor: Boolean,
+ override val receiver: Parameter?,
+ val parameters: List<Parameter>,
+ override val expected: PlatformInfo?,
+ override val actual: List<PlatformInfo>,
+ override val extra: MutableSet<Extra> = mutableSetOf()
+) : CallableNode() {
+ override val children: List<Parameter>
+ get() = listOfNotNull(receiver) + parameters
+}
+
+class Property(
+ override val dri: DRI,
+ override val name: String,
+ override val receiver: Parameter?,
+ override val expected: PlatformInfo?,
+ override val actual: List<PlatformInfo>,
+ override val extra: MutableSet<Extra> = mutableSetOf()
+) : CallableNode() {
+ override val children: List<Parameter>
+ get() = listOfNotNull(receiver)
+}
+
+// TODO: treat named Parameters and receivers differently
+class Parameter(
+ override val dri: DRI,
+ override val name: String?,
+ val type: TypeWrapper,
+ override val actual: List<PlatformInfo>,
+ override val extra: MutableSet<Extra> = mutableSetOf()
+) : DocumentationNode() {
+ override val children: List<DocumentationNode>
+ get() = emptyList()
+}
+
+interface PlatformInfo {
+ val docTag: KDocTag?
+ val links: Map<String, DRI>
+ val platformData: List<PlatformData>
+}
+
+class BasePlatformInfo(
+ override val docTag: KDocTag?,
+ override val links: Map<String, DRI>,
+ override val platformData: List<PlatformData>) : PlatformInfo {
+
+ override fun equals(other: Any?): Boolean =
+ other is PlatformInfo && (
+ docTag?.text == other.docTag?.text &&
+ links == other.links)
+
+ override fun hashCode(): Int =
+ listOf(docTag?.text, links).hashCode()
+}
+
+class ClassPlatformInfo(
+ val info: PlatformInfo,
+ val inherited: List<DRI>) : PlatformInfo by info
+
+abstract class DocumentationNode {
+ open val expected: PlatformInfo? = null
+ open val actual: List<PlatformInfo> = emptyList()
+ open val name: String? = null
+ val platformInfo by lazy { listOfNotNull(expected) + actual }
+ val platformData by lazy { platformInfo.flatMap { it.platformData }.toSet() }
+
+ abstract val dri: DRI
+
+ abstract val children: List<DocumentationNode>
+
+ override fun toString(): String {
+ return "${javaClass.simpleName}($dri)" + briefDocstring.takeIf { it.isNotBlank() }?.let { " [$it]" }.orEmpty()
+ }
+
+ override fun equals(other: Any?) = other is DocumentationNode && this.dri == other.dri
+
+ override fun hashCode() = dri.hashCode()
+
+ val commentsData: List<Pair<String, Map<String, DRI>>>
+ get() = platformInfo.mapNotNull { it.docTag?.let { tag -> Pair(tag.getContent(), it.links) } }
+
+ val briefDocstring: String
+ get() = platformInfo.firstOrNull()?.docTag?.getContent().orEmpty().shorten(40)
+
+ open val extra: MutableSet<Extra> = mutableSetOf()
+}
+
+abstract class ScopeNode : DocumentationNode() {
+ abstract val functions: List<Function>
+ abstract val properties: List<Property>
+ abstract val classes: List<Class>
+
+ override val children: List<DocumentationNode>
+ get() = functions + properties + classes
+}
+
+abstract class CallableNode : DocumentationNode() {
+ abstract val receiver: Parameter?
+}
+
+private fun String.shorten(maxLength: Int) = lineSequence().first().let {
+ if (it.length != length || it.length > maxLength) it.take(maxLength - 3) + "..." else it
+}
+
+interface TypeWrapper {
+ val constructorFqName: String?
+ val constructorNamePathSegments: List<String>
+ val arguments: List<KotlinTypeWrapper>
+ val dri: DRI?
+}
+interface ClassKind
+
+fun DocumentationNode.dfs(predicate: (DocumentationNode) -> Boolean): DocumentationNode? =
+ if (predicate(this)) {
+ this
+ } else {
+ this.children.asSequence().mapNotNull { it.dfs(predicate) }.firstOrNull()
+ }
+
+interface Extra \ No newline at end of file