1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
package org.jetbrains.dokka.Model
import org.jetbrains.dokka.links.DRI
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag
class Module(val packages: List<Package>) : DocumentationNode<Nothing>() {
override val docTag: KDocTag? = null
override val dri: DRI = DRI.topLevel
override val children: List<Package> = packages
}
class Package(
override val dri: DRI,
override val functions: List<Function>,
override val properties: List<Property>,
override val classes: List<Class>
) : ScopeNode<Nothing>() {
val name = dri.packageName.orEmpty()
override val docTag: KDocTag? = null
}
class Class(
override val dri: DRI,
val name: String,
override val functions: List<Function>,
override val properties: List<Property>,
override val classes: List<Class>,
override val docTag: KDocTag?,
override val descriptor: ClassDescriptor
) : ScopeNode<ClassDescriptor>()
class Function(
override val dri: DRI,
val name: String,
override val receiver: Parameter?,
val parameters: List<Parameter>,
override val docTag: KDocTag?,
override val descriptor: FunctionDescriptor
) : CallableNode<FunctionDescriptor>() {
override val children: List<Parameter>
get() = listOfNotNull(receiver) + parameters
}
class Property(
override val dri: DRI,
val name: String,
override val receiver: Parameter?,
override val docTag: KDocTag?,
override val descriptor: PropertyDescriptor
) : CallableNode<PropertyDescriptor>() {
override val children: List<Parameter>
get() = listOfNotNull(receiver)
}
class Parameter(
override val dri: DRI,
val name: String?,
override val docTag: KDocTag?,
override val descriptor: ParameterDescriptor
) : DocumentationNode<ParameterDescriptor>() {
override val children: List<DocumentationNode<*>>
get() = emptyList()
}
abstract class DocumentationNode<out T : DeclarationDescriptor> {
open val descriptor: T? = null
abstract val docTag: KDocTag? // TODO: replace in the future with more robust doc-comment model
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 rawDocstring: String
get() = docTag?.getContent().orEmpty()
val briefDocstring: String
get() = rawDocstring.shorten(40)
}
abstract class ScopeNode<out T : ClassOrPackageFragmentDescriptor> : DocumentationNode<T>() {
abstract val functions: List<Function>
abstract val properties: List<Property>
abstract val classes: List<Class>
override val children: List<DocumentationNode<MemberDescriptor>>
get() = functions + properties + classes
}
abstract class CallableNode<out T : CallableDescriptor> : DocumentationNode<T>() {
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
}
|