aboutsummaryrefslogtreecommitdiff
path: root/plugins/kotlin-as-java/src/main/kotlin/KotlinAsJavaPageBuilder.kt
blob: 67a3ee86d63864eca3ecc2c0fba04d6a503a98ee (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
package org.jetbrains.dokka.kotlinAsJava

import org.jetbrains.dokka.kotlinAsJava.conversions.asJava
import org.jetbrains.dokka.kotlinAsJava.conversions.asStatic
import org.jetbrains.dokka.kotlinAsJava.conversions.withClass
import org.jetbrains.dokka.links.withClass
import org.jetbrains.dokka.model.*
import org.jetbrains.dokka.model.Function
import org.jetbrains.dokka.model.Enum
import org.jetbrains.dokka.model.doc.TagWrapper
import org.jetbrains.dokka.pages.*
import org.jetbrains.dokka.transformers.descriptors.KotlinClassKindTypes
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi

fun DeclarationDescriptor.sourceLocation(): String? = this.findPsi()?.containingFile?.virtualFile?.path
fun <T : Documentable> List<T>.groupedByLocation(): Map<String, List<T>> =
    this.map { DescriptorCache[it.dri]?.sourceLocation() to it }
        .filter { it.first != null }.groupBy({ (location, _) ->
            location!!.let { it.split("/").last().split(".").first() + "Kt" }
        }) { it.second }

class KotlinAsJavaPageBuilder(rootContentGroup: RootContentBuilder) : DefaultPageBuilder(rootContentGroup) {

    data class FunsAndProps(val key: String, val funs: List<Function>, val props: List<Property>)

    override fun pageForPackage(p: Package): PackagePageNode {

        val funs = p.functions.groupedByLocation()

        val props = p.properties.groupedByLocation()

        val zipped = (funs.keys + props.keys)
            .map { k -> FunsAndProps(k, funs[k].orEmpty(), props[k].orEmpty()) }

        val classes = (p.classlikes + zipped.map { (key, funs, props) ->
            val dri = p.dri.withClass(key)
            Class(
                dri = dri,
                name = key,
                kind = KotlinClassKindTypes.CLASS,
                constructors = emptyList(),
                functions = funs.map { it.withClass(key, dri).asStatic() },
                properties = props.map { it.withClass(key, dri) },
                classlikes = emptyList(),
                actual = emptyList(),
                expected = null,
                visibility = p.platformData.map { it to Visibilities.PUBLIC }.toMap()
            )
        }).map { it.asJava() }

        return PackagePageNode(
            p.name, contentForPackage(p, classes), setOf(p.dri), p,
            classes.map(::pageForClasslike)
        )
    }

    private fun contentForPackage(p: Package, nClasses: List<Classlike>) = group(p) {
        header(1) { text("Package ${p.name}") }
        block("Types", 2, ContentKind.Properties, nClasses, p.platformData) {
            link(it.name, it.dri)
            text(it.briefDocTagString)
        }
    }

    private fun TagWrapper.toHeaderString() = this.javaClass.toGenericString().split('.').last()
}