diff options
author | Paweł Marks <pmarks@virtuslab.com> | 2020-01-27 09:34:16 +0100 |
---|---|---|
committer | Paweł Marks <Kordyjan@users.noreply.github.com> | 2020-01-31 15:07:06 +0100 |
commit | 885ecd28153b484277c9ddcbf4a7f9d761a59545 (patch) | |
tree | db453e66762ebebb3ee05c0301b38c4465ea20a3 /core/src/main/kotlin/resolvers/DefaultLocationProvider.kt | |
parent | c29605d92d1999434ecc79e774281a8280ae2823 (diff) | |
download | dokka-885ecd28153b484277c9ddcbf4a7f9d761a59545.tar.gz dokka-885ecd28153b484277c9ddcbf4a7f9d761a59545.tar.bz2 dokka-885ecd28153b484277c9ddcbf4a7f9d761a59545.zip |
Unifing model for pages with content ant technical renderer specific pages
Diffstat (limited to 'core/src/main/kotlin/resolvers/DefaultLocationProvider.kt')
-rw-r--r-- | core/src/main/kotlin/resolvers/DefaultLocationProvider.kt | 81 |
1 files changed, 38 insertions, 43 deletions
diff --git a/core/src/main/kotlin/resolvers/DefaultLocationProvider.kt b/core/src/main/kotlin/resolvers/DefaultLocationProvider.kt index 8e848b63..48ea5316 100644 --- a/core/src/main/kotlin/resolvers/DefaultLocationProvider.kt +++ b/core/src/main/kotlin/resolvers/DefaultLocationProvider.kt @@ -8,19 +8,35 @@ import org.jetbrains.dokka.plugability.single import org.jetbrains.dokka.utilities.htmlEscape import java.util.* +private const val PAGE_WITH_CHILDREN_SUFFIX = "index" + open class DefaultLocationProvider( - private val pageGraphRoot: ModulePageNode, - private val dokkaContext: DokkaContext -) : LocationProvider { // TODO: cache - private val extension = dokkaContext.single(CoreExtensions.fileExtension) + protected val pageGraphRoot: RootPageNode, + protected val dokkaContext: DokkaContext +) : LocationProvider { + protected val extension = dokkaContext.single(CoreExtensions.fileExtension) + + protected val pagesIndex: Map<DRI, ContentPage> = pageGraphRoot.asSequence().filterIsInstance<ContentPage>() + .groupingBy { it.dri } + .aggregate { dri, _, page, first -> + if (first) page else throw AssertionError("Multiple pages associated with dri: $dri") + } - private val pagesCache = mutableMapOf<DRI, Maybe<PageNode>>() - private val pathCache: MutableMap<PageNode, List<String>> = IdentityHashMap<PageNode, List<String>>() + protected val pathsIndex: Map<PageNode, List<String>> = IdentityHashMap<PageNode, List<String>>().apply { + fun registerPath(page: PageNode, prefix: List<String>) { + val newPrefix = prefix + page.pathName + put(page, newPrefix) + page.children.forEach { registerPath(it, newPrefix) } + } + put(pageGraphRoot, emptyList()) + pageGraphRoot.children.forEach { registerPath(it, emptyList()) } + } - override fun resolve(node: PageNode, context: PageNode?): String = pathTo(node, context) + extension + override fun resolve(node: PageNode, context: PageNode?, skipExtension: Boolean): String = + pathTo(node, context) + if (!skipExtension) extension else "" override fun resolve(dri: DRI, platforms: List<PlatformData>, context: PageNode?): String = - findInPageGraph(dri, platforms)?.let { resolve(it, context) } ?: + pagesIndex[dri]?.let { resolve(it, context) } ?: // Not found in PageGraph, that means it's an external link ExternalLocationProvider.getLocation(dri, this.dokkaContext.configuration.passesConfigurations @@ -31,50 +47,30 @@ open class DefaultLocationProvider( .flatMap { it.externalDocumentationLinks }.distinct() ) - override fun resolveRoot(node: PageNode): String = "../${pathTo(pageGraphRoot, node).removeSuffix( - PAGE_WITH_CHILDREN_SUFFIX - )}" - - private fun PageNode.parent() = pageGraphRoot.parentMap[this] - - override fun ancestors(node: PageNode?): List<PageNode> = when (node) { - null -> emptyList() - else -> ancestors(node.parent()) + node - } - - override fun top(): PageNode = pageGraphRoot - - protected open fun findInPageGraph(dri: DRI, platforms: List<PlatformData>): PageNode? = - pagesCache.getOrPut(dri) { pageGraphRoot.dfs { it.dri == dri }.wrapped }.unwrapped + override fun resolveRoot(node: PageNode): String = + pathTo(pageGraphRoot, node).removeSuffix(PAGE_WITH_CHILDREN_SUFFIX) + override fun ancestors(node: PageNode): List<PageNode> = + generateSequence(node) { it.parent() }.toList() protected open fun pathTo(node: PageNode, context: PageNode?): String { - - fun PageNode.pathName(): String = - if (this is PackagePageNode) name - else identifierToFilename(name) - - fun getPathInternal(pathNode: PageNode?, path: List<String>): List<String> = when (pathNode) { - null -> path - else -> getPathInternal(pathNode.parent(), path + pathNode.pathName().ifEmpty { "root" }) - } - - fun getPath(pathNode: PageNode) = pathCache.getOrPut(pathNode) { getPathInternal(pathNode, emptyList()) } + fun pathFor(page: PageNode) = pathsIndex[page] ?: throw AssertionError( + "${page::class.simpleName}(${page.name}) does not belong to current page graph so it is impossible to compute its path" + ) val contextNode = if (context?.children?.isEmpty() == true && context.parent() != null) context.parent() else context - val nodePath = getPath(node).reversed() - val contextPath = contextNode?.let(::getPath).orEmpty().reversed() + val nodePath = pathFor(node) + val contextPath = contextNode?.let { pathFor(it) }.orEmpty() - val commonPathElements = nodePath.zip(contextPath).takeWhile { (a, b) -> a == b }.size + val commonPathElements = nodePath.asSequence().zip(contextPath.asSequence()) + .takeWhile { (a, b) -> a == b }.count() return (List(contextPath.size - commonPathElements) { ".." } + nodePath.drop(commonPathElements) + if (node.children.isNotEmpty()) listOf(PAGE_WITH_CHILDREN_SUFFIX) else emptyList()).joinToString("/") } - private companion object { - const val PAGE_WITH_CHILDREN_SUFFIX = "index" - } + private fun PageNode.parent() = pageGraphRoot.parentMap[this] } fun DRI.toJavadocLocation(jdkVersion: Int): String { // TODO: classes without packages? @@ -122,6 +118,5 @@ private fun identifierToFilename(name: String): String { return if (lowercase in reservedFilenames) "--$lowercase--" else lowercase } -private class Maybe<T : Any>(val unwrapped: T?) - -private val <T : Any> T?.wrapped: Maybe<T> get() = Maybe(this)
\ No newline at end of file +private val PageNode.pathName: String + get() = if (this is PackagePageNode) name else identifierToFilename(name) |