aboutsummaryrefslogtreecommitdiff
path: root/core/src/main/kotlin/Languages/CommonLanguageService.kt
blob: c6e3cd37f2b4b33dbcc05626319ddc5f5a5ccd7c (plain)
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
109
110
111
112
113
114
115
116
117
118
package org.jetbrains.dokka

import org.jetbrains.dokka.Formats.nameWithOuterClass


abstract class CommonLanguageService : LanguageService {

    protected fun ContentBlock.renderPackage(node: DocumentationNode) {
        keyword("package")
        nbsp()
        identifier(node.name)
    }

    override fun renderName(node: DocumentationNode): String {
        return when (node.kind) {
            NodeKind.Constructor -> node.owner!!.name
            else -> node.name
        }
    }

    override fun renderNameWithOuterClass(node: DocumentationNode): String {
        return when (node.kind) {
            NodeKind.Constructor -> node.owner!!.nameWithOuterClass()
            else -> node.nameWithOuterClass()
        }
    }

    open fun renderModifier(
        block: ContentBlock,
        node: DocumentationNode,
        renderMode: LanguageService.RenderMode,
        nowrap: Boolean = false
    ) = with(block) {
        keyword(node.name)
        if (nowrap) {
            nbsp()
        } else {
            text(" ")
        }
    }

    protected fun renderLinked(
        block: ContentBlock,
        node: DocumentationNode,
        body: ContentBlock.(DocumentationNode) -> Unit
    ) = with(block) {
        val to = node.links.firstOrNull()
        if (to == null)
            body(node)
        else
            link(to) {
                this.body(node)
            }
    }

    protected fun <T> ContentBlock.renderHardWrappingList(
        nodes: List<T>, separator: String = ", ",
        renderItem: (T) -> Unit
    ) {
        if (nodes.none())
            return

        if (nodes.count() > 1) {
            hardLineBreak()
            repeat(4) {
                nbsp()
            }
        }

        renderItem(nodes.first())
        nodes.drop(1).forEach {
            symbol(separator)
            hardLineBreak()
            repeat(4) {
                nbsp()
            }
            renderItem(it)
        }
    }

    protected fun <T> ContentBlock.renderList(
        nodes: List<T>, separator: String = ", ",
        noWrap: Boolean = false, renderItem: (T) -> Unit
    ) {
        if (nodes.none())
            return
        renderItem(nodes.first())
        nodes.drop(1).forEach {
            if (noWrap) {
                symbol(separator.removeSuffix(" "))
                nbsp()
            } else {
                symbol(separator)
            }
            renderItem(it)
        }
    }

    abstract fun showModifierInSummary(node: DocumentationNode): Boolean

    protected fun ContentBlock.renderModifiersForNode(
        node: DocumentationNode,
        renderMode: LanguageService.RenderMode,
        nowrap: Boolean = false
    ) {
        val modifiers = node.details(NodeKind.Modifier)
        for (it in modifiers) {
            if (node.kind == NodeKind.Interface && it.name == "abstract")
                continue
            if (renderMode == LanguageService.RenderMode.SUMMARY && !showModifierInSummary(it)) {
                continue
            }
            renderModifier(this, it, renderMode, nowrap)
        }
    }


}