All Downloads are FREE. Search and download functionalities are using the official Maven repository.

pages.PageNodes.kt Maven / Gradle / Ivy

Go to download

Dokka is an API documentation engine for Kotlin and Java, performing the same function as Javadoc for Java

There is a newer version: 2.0.0
Show newest version
package org.jetbrains.dokka.pages

import org.jetbrains.dokka.links.DRI
import org.jetbrains.dokka.model.Documentable
import org.jetbrains.dokka.model.WithChildren
import java.util.*

interface PageNode : WithChildren {
    val name: String
    override val children: List

    fun modified(
        name: String = this.name,
        children: List = this.children
    ): PageNode
}

interface ContentPage : PageNode {
    val content: ContentNode
    val dri: Set
    val embeddedResources: List

    @Deprecated("Deprecated. Remove its usages from your code.",
        ReplaceWith("this.documentables.firstOrNull()")
    )
    val documentable: Documentable?
        get() = if (this is WithDocumentables) this.documentables.firstOrNull() else null

    fun modified(
        name: String = this.name,
        content: ContentNode = this.content,
        dri: Set = this.dri,
        embeddedResources: List = this.embeddedResources,
        children: List = this.children
    ): ContentPage
}

interface WithDocumentables {
    val documentables: List
}

abstract class RootPageNode(val forceTopLevelName: Boolean = false) : PageNode {
    val parentMap: Map by lazy {
        IdentityHashMap().apply {
            fun process(parent: PageNode) {
                parent.children.forEach { child ->
                    put(child, parent)
                    process(child)
                }
            }
            process(this@RootPageNode)
        }
    }

    fun transformPageNodeTree(operation: (PageNode) -> PageNode) =
        this.transformNode(operation) as RootPageNode

    fun transformContentPagesTree(operation: (ContentPage) -> ContentPage) = transformPageNodeTree {
        if (it is ContentPage) operation(it) else it
    }

    private fun PageNode.transformNode(operation: (PageNode) -> PageNode): PageNode =
        operation(this).let { newNode ->
            newNode.modified(children = newNode.children.map { it.transformNode(operation) })
        }

    abstract override fun modified(
        name: String,
        children: List
    ): RootPageNode
}

class ModulePageNode(
    override val name: String,
    override val content: ContentNode,
    override val documentables: List = listOf(),
    override val children: List,
    override val embeddedResources: List = listOf()
) : RootPageNode(), ModulePage {
    override val dri: Set = setOf(DRI.topLevel)

    override fun modified(name: String, children: List): ModulePageNode =
        modified(name = name, content = this.content, dri = dri, children = children)

    override fun modified(
        name: String,
        content: ContentNode,
        dri: Set,
        embeddedResources: List,
        children: List
    ): ModulePageNode =
        if (name == this.name && content === this.content && embeddedResources === this.embeddedResources && children shallowEq this.children) this
        else ModulePageNode(name, content, documentables, children, embeddedResources)
}

class PackagePageNode(
    override val name: String,
    override val content: ContentNode,
    override val dri: Set,
    override val documentables: List = listOf(),
    override val children: List,
    override val embeddedResources: List = listOf()
) : PackagePage {

    init {
        require(name.isNotBlank()) { "PackagePageNode.name cannot be blank" }
    }

    override fun modified(name: String, children: List): PackagePageNode =
        modified(name = name, content = this.content, children = children)

    override fun modified(
        name: String,
        content: ContentNode,
        dri: Set,
        embeddedResources: List,
        children: List
    ): PackagePageNode =
        if (name == this.name && content === this.content && embeddedResources === this.embeddedResources && children shallowEq this.children) this
        else PackagePageNode(name, content, dri, documentables, children, embeddedResources)
}

class ClasslikePageNode(
    override val name: String,
    override val content: ContentNode,
    override val dri: Set,
    override val documentables: List = listOf(),
    override val children: List,
    override val embeddedResources: List = listOf()
) : ClasslikePage {
    override fun modified(name: String, children: List): ClasslikePageNode =
        modified(name = name, content = this.content, children = children)

    override fun modified(
        name: String,
        content: ContentNode,
        dri: Set,
        embeddedResources: List,
        children: List
    ): ClasslikePageNode =
        if (name == this.name && content === this.content && embeddedResources === this.embeddedResources && children shallowEq this.children) this
        else ClasslikePageNode(name, content, dri, documentables, children, embeddedResources)
}

class MemberPageNode(
    override val name: String,
    override val content: ContentNode,
    override val dri: Set,
    override val documentables: List = listOf(),
    override val children: List = emptyList(),
    override val embeddedResources: List = listOf()
) : MemberPage {
    override fun modified(name: String, children: List): MemberPageNode =
        modified(name = name, content = this.content, children = children)

    override fun modified(
        name: String,
        content: ContentNode,
        dri: Set,
        embeddedResources: List,
        children: List
    ): MemberPageNode =
        if (name == this.name && content === this.content && embeddedResources === this.embeddedResources && children shallowEq this.children) this
        else MemberPageNode(name, content, dri, documentables, children, embeddedResources)
}


class MultimoduleRootPageNode(
    override val dri: Set,
    override val content: ContentNode,
    override val embeddedResources: List = emptyList()
) : RootPageNode(forceTopLevelName = true), MultimoduleRootPage {
    override val name = "All modules"

    override val children: List = emptyList()

    override fun modified(name: String, children: List): RootPageNode =
        MultimoduleRootPageNode(dri, content, embeddedResources)

    override fun modified(
        name: String,
        content: ContentNode,
        dri: Set,
        embeddedResources: List,
        children: List
    ) =
        if (name == this.name && content === this.content && embeddedResources === this.embeddedResources && children shallowEq this.children) this
        else MultimoduleRootPageNode(dri, content, embeddedResources)
}

inline fun  PageNode.children() = children.filterIsInstance()

private infix fun  List.shallowEq(other: List) =
    this === other || (this.size == other.size && (this zip other).all { (a, b) -> a === b })




© 2015 - 2025 Weber Informatics LLC | Privacy Policy