aboutsummaryrefslogtreecommitdiff
path: root/core/src
diff options
context:
space:
mode:
authorBłażej Kardyś <bkardys@virtuslab.com>2019-11-29 03:28:17 +0100
committerBłażej Kardyś <bkardys@virtuslab.com>2019-12-05 16:15:47 +0100
commitac521e75eadb384e005d73ec5818e01b742cbe19 (patch)
treeef147f96b8fa550fa763d972b5534edbf2417ee7 /core/src
parentcf97771a0805b62532cda2cdf3bfebeed21652ab (diff)
downloaddokka-ac521e75eadb384e005d73ec5818e01b742cbe19.tar.gz
dokka-ac521e75eadb384e005d73ec5818e01b742cbe19.tar.bz2
dokka-ac521e75eadb384e005d73ec5818e01b742cbe19.zip
Parentless page navigation
Diffstat (limited to 'core/src')
-rw-r--r--core/src/main/kotlin/pages/PageNodes.kt50
-rw-r--r--core/src/main/kotlin/renderers/DefaultRenderer.kt13
-rw-r--r--core/src/main/kotlin/resolvers/DefaultLocationProvider.kt44
-rw-r--r--core/src/main/kotlin/resolvers/LocationProvider.kt1
4 files changed, 56 insertions, 52 deletions
diff --git a/core/src/main/kotlin/pages/PageNodes.kt b/core/src/main/kotlin/pages/PageNodes.kt
index e8b66f4a..f1ad430f 100644
--- a/core/src/main/kotlin/pages/PageNodes.kt
+++ b/core/src/main/kotlin/pages/PageNodes.kt
@@ -3,11 +3,11 @@ package org.jetbrains.dokka.pages
import org.jetbrains.dokka.model.DocumentationNode
import org.jetbrains.dokka.Platform
import org.jetbrains.dokka.links.DRI
+import java.util.*
interface PageNode {
val name: String
val content: ContentNode
- val parent: PageNode?
val dri: DRI
val documentationNode: DocumentationNode?
val embeddedResources: List<String>
@@ -21,33 +21,13 @@ interface PageNode {
): PageNode
}
-abstract class BasicPageNode(children: List<PageNode>) : PageNode {
-
- private lateinit var _parent: PageNode
- override val parent: PageNode? by lazy { _parent }
- override val children = children
-
- override fun equals(other: Any?): Boolean =
- if (other is PageNode) {
- dri == other.dri && name == other.name
- } else false
-
- override fun hashCode(): Int =
- (name + dri).hashCode()
-
- init {
- children.forEach { if (it is BasicPageNode) it._parent = this }
- }
-}
-
class ModulePageNode(
override val name: String,
override val content: ContentNode,
override val documentationNode: DocumentationNode?,
- children: List<PageNode>,
+ override val children: List<PageNode>,
override val embeddedResources: List<String> = listOf()
-) : BasicPageNode(children) {
- override val parent: Nothing? = null
+) : PageNode {
override val dri: DRI = DRI.topLevel
override fun modified(
@@ -66,6 +46,18 @@ class ModulePageNode(
fun transformPageNodeTree(operation: (PageNode) -> PageNode) =
this.transformNode(operation) as ModulePageNode
+
+ val parentMap: IdentityHashMap<PageNode, PageNode> by lazy {
+ IdentityHashMap<PageNode, PageNode>().apply {
+ fun addParent(parent: PageNode) {
+ parent.children.forEach { child ->
+ put(child, parent)
+ addParent(child)
+ }
+ }
+ addParent(this@ModulePageNode)
+ }
+ }
}
class PackagePageNode(
@@ -73,9 +65,9 @@ class PackagePageNode(
override val content: ContentNode,
override val dri: DRI,
override val documentationNode: DocumentationNode?,
- children: List<PageNode>,
+ override val children: List<PageNode>,
override val embeddedResources: List<String> = listOf()
-) : BasicPageNode(children) {
+) : PageNode {
override fun modified(
name: String,
@@ -92,9 +84,9 @@ class ClassPageNode(
override val content: ContentNode,
override val dri: DRI,
override val documentationNode: DocumentationNode?,
- children: List<PageNode>,
+ override val children: List<PageNode>,
override val embeddedResources: List<String> = listOf()
-) : BasicPageNode(children) {
+) : PageNode {
override fun modified(
name: String,
@@ -111,9 +103,9 @@ class MemberPageNode(
override val content: ContentNode,
override val dri: DRI,
override val documentationNode: DocumentationNode?,
- children: List<PageNode> = emptyList(),
+ override val children: List<PageNode> = emptyList(),
override val embeddedResources: List<String> = listOf()
-) : BasicPageNode(children) {
+) : PageNode {
override fun modified(
name: String,
diff --git a/core/src/main/kotlin/renderers/DefaultRenderer.kt b/core/src/main/kotlin/renderers/DefaultRenderer.kt
index 3f851849..72fc222a 100644
--- a/core/src/main/kotlin/renderers/DefaultRenderer.kt
+++ b/core/src/main/kotlin/renderers/DefaultRenderer.kt
@@ -30,14 +30,11 @@ abstract class DefaultRenderer(
protected open fun buildHeader(node: ContentHeader, pageContext: PageNode): String =
buildHeader(node.level, node.children.joinToString { it.build(pageContext) })
- protected open fun buildNavigation(page: PageNode): String {
- fun buildNavigationWithContext(page: PageNode, context: PageNode): String =
- page.parent?.let { buildNavigationWithContext(it, context) }.orEmpty() + "/" + buildLink(
- page.name,
- locationProvider.resolve(page, context)
- )
- return buildNavigationWithContext(page, page)
- }
+ protected open fun buildNavigation(page: PageNode): String =
+ locationProvider.ancestors(page).fold("") { acc, node -> "$acc/${buildLink(
+ node.name,
+ locationProvider.resolve(node, page)
+ )}" }
protected open fun ContentNode.build(pageContext: PageNode): String = buildContentNode(this, pageContext)
diff --git a/core/src/main/kotlin/resolvers/DefaultLocationProvider.kt b/core/src/main/kotlin/resolvers/DefaultLocationProvider.kt
index 5139b3c1..fb9ac6cd 100644
--- a/core/src/main/kotlin/resolvers/DefaultLocationProvider.kt
+++ b/core/src/main/kotlin/resolvers/DefaultLocationProvider.kt
@@ -9,10 +9,10 @@ import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.dokka.plugability.single
open class DefaultLocationProvider(
- private val pageGraphRoot: PageNode,
+ private val pageGraphRoot: ModulePageNode,
private val configuration: DokkaConfiguration,
context: DokkaContext
-): LocationProvider { // TODO: cache
+) : LocationProvider { // TODO: cache
private val extension = context.single(CoreExtensions.fileExtension)
override fun resolve(node: PageNode, context: PageNode?): String = pathTo(node, context) + extension
@@ -22,14 +22,25 @@ open class DefaultLocationProvider(
// Not found in PageGraph, that means it's an external link
ExternalLocationProvider.getLocation(dri,
configuration.passesConfigurations
- .filter { passConfig -> platforms.toSet().contains(PlatformData(passConfig.analysisPlatform, passConfig.targets)) } // TODO: change targets to something better?
- .flatMap { it.externalDocumentationLinks }.distinct()
+ .filter { passConfig ->
+ platforms.toSet().contains(PlatformData(passConfig.analysisPlatform, passConfig.targets))
+ } // TODO: change targets to something better?
+ .flatMap { it.externalDocumentationLinks }.distinct()
)
override fun resolveRoot(node: PageNode): String = "../${pathTo(pageGraphRoot, node).removeSuffix(
- PAGE_WITH_CHILDREN_SUFFIX)}"
+ PAGE_WITH_CHILDREN_SUFFIX
+ )}"
- protected open fun findInPageGraph(dri: DRI, platforms: List<PlatformData>): PageNode? = pageGraphRoot.dfs { it.dri == dri }
+ private fun PageNode.parent() = pageGraphRoot.parentMap[this]
+
+ override fun ancestors(node: PageNode?): List<PageNode> = when (node) {
+ null -> emptyList()
+ else -> ancestors(node.parent()) + node
+ }
+
+ protected open fun findInPageGraph(dri: DRI, platforms: List<PlatformData>): PageNode? =
+ pageGraphRoot.dfs { it.dri == dri }
protected open fun pathTo(node: PageNode, context: PageNode?): String {
@@ -37,20 +48,20 @@ open class DefaultLocationProvider(
if (this is PackagePageNode) name
else identifierToFilename(name)
- fun getPath(pathNode: PageNode?, path: List<String> = mutableListOf()): List<String> = when(pathNode) {
+ fun getPath(pathNode: PageNode?, path: List<String> = mutableListOf()): List<String> = when (pathNode) {
null -> path
pageGraphRoot -> path + "root"
- else -> getPath(pathNode.parent, path + pathNode.pathName())
+ else -> getPath(pathNode.parent(), path + pathNode.pathName())
}
- val contextNode = if (context?.children?.isEmpty() == true) context.parent else context
+ val contextNode = if (context?.children?.isEmpty() == true) context.parent() else context
val nodePath = getPath(node).reversed()
val contextPath = getPath(contextNode).reversed()
val commonPathElements = nodePath.zip(contextPath).takeWhile { (a, b) -> a == b }.size
- return ( List(contextPath.size - commonPathElements) { ".." } + nodePath.drop(commonPathElements) +
- if(node.children.isNotEmpty()) listOf(PAGE_WITH_CHILDREN_SUFFIX) else emptyList()).joinToString("/")
+ return (List(contextPath.size - commonPathElements) { ".." } + nodePath.drop(commonPathElements) +
+ if (node.children.isNotEmpty()) listOf(PAGE_WITH_CHILDREN_SUFFIX) else emptyList()).joinToString("/")
}
private companion object {
@@ -63,7 +74,7 @@ fun DRI.toJavadocLocation(jdkVersion: Int): String { // TODO: classes without pa
if (classNames == null) {
return "$packageLink/package-summary.html".htmlEscape()
}
- val classLink = if (packageLink == null) { "$classNames.html" } else { "$packageLink/$classNames.html" }
+ val classLink = if (packageLink == null) "$classNames.html" else "$packageLink/$classNames.html"
if (callable == null) {
return classLink.htmlEscape()
}
@@ -81,8 +92,11 @@ fun DRI.toDokkaLocation(extension: String): String { // TODO: classes without pa
if (classNames == null) {
return "$packageName/index$extension"
}
- val classLink = if (packageName == null) { "" } else { "$packageName/" } +
- classNames.split('.').joinToString("/", transform = ::identifierToFilename)
+ val classLink = if (packageName == null) {
+ ""
+ } else {
+ "$packageName/"
+ } + classNames.split('.').joinToString("/", transform = ::identifierToFilename)
if (callable == null) {
return "$classLink/index$extension"
@@ -98,4 +112,4 @@ private fun identifierToFilename(name: String): String {
val escaped = name.replace('<', '-').replace('>', '-')
val lowercase = escaped.replace("[A-Z]".toRegex()) { matchResult -> "-" + matchResult.value.toLowerCase() }
return if (lowercase in reservedFilenames) "--$lowercase--" else lowercase
-}
+} \ No newline at end of file
diff --git a/core/src/main/kotlin/resolvers/LocationProvider.kt b/core/src/main/kotlin/resolvers/LocationProvider.kt
index 9f02d347..2da2310d 100644
--- a/core/src/main/kotlin/resolvers/LocationProvider.kt
+++ b/core/src/main/kotlin/resolvers/LocationProvider.kt
@@ -8,4 +8,5 @@ interface LocationProvider {
fun resolve(dri: DRI, platforms: List<PlatformData>, context: PageNode? = null): String
fun resolve(node: PageNode, context: PageNode? = null): String
fun resolveRoot(node: PageNode): String
+ fun ancestors(node: PageNode?): List<PageNode>
}