From 0e35a9d3b2a24b50d6016e82e9889d9fdc3dbbf0 Mon Sep 17 00:00:00 2001 From: Błażej Kardyś Date: Thu, 25 Jun 2020 20:41:28 +0200 Subject: Adding external url handling --- .../main/kotlin/javadoc/JavadocLocationProvider.kt | 104 --------------------- .../src/main/kotlin/javadoc/JavadocPageCreator.kt | 67 +++++++------ .../src/main/kotlin/javadoc/JavadocPlugin.kt | 16 +++- .../javadoc/location/JavadocLocationProvider.kt | 91 ++++++++++++++++++ .../location/JavadocLocationProviderFactory.kt | 11 +++ .../main/kotlin/javadoc/pages/JavadocPageNodes.kt | 25 +---- .../renderer/JavadocContentToHtmlTranslator.kt | 34 ++----- .../JavadocContentToTemplateMapTranslator.kt | 22 ++--- .../javadoc/renderer/KorteJavadocRenderer.kt | 55 ++++++----- 9 files changed, 207 insertions(+), 218 deletions(-) delete mode 100644 plugins/javadoc/src/main/kotlin/javadoc/JavadocLocationProvider.kt create mode 100644 plugins/javadoc/src/main/kotlin/javadoc/location/JavadocLocationProvider.kt create mode 100644 plugins/javadoc/src/main/kotlin/javadoc/location/JavadocLocationProviderFactory.kt (limited to 'plugins/javadoc/src/main/kotlin') diff --git a/plugins/javadoc/src/main/kotlin/javadoc/JavadocLocationProvider.kt b/plugins/javadoc/src/main/kotlin/javadoc/JavadocLocationProvider.kt deleted file mode 100644 index d731ec5f..00000000 --- a/plugins/javadoc/src/main/kotlin/javadoc/JavadocLocationProvider.kt +++ /dev/null @@ -1,104 +0,0 @@ -package javadoc - -import javadoc.pages.* -import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet -import org.jetbrains.dokka.Platform -import org.jetbrains.dokka.base.DokkaBase -import org.jetbrains.dokka.base.resolvers.local.LocationProvider -import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.pages.ContentPage -import org.jetbrains.dokka.pages.PageNode -import org.jetbrains.dokka.pages.RootPageNode -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.plugability.plugin -import org.jetbrains.dokka.plugability.query -import java.nio.file.Paths -import java.util.* - -class JavadocLocationProvider(pageRoot: RootPageNode, private val context: DokkaContext) : LocationProvider { - private val externalLocationProviderFactories = - context.plugin().query { externalLocationProviderFactory } - private val externalLocationProvider = - externalLocationProviderFactories.asSequence().map { it.getExternalLocationProvider("javadoc10") } - .filterNotNull().take(1).firstOrNull() - private val externalDocumentationLinks by lazy { - context.configuration.sourceSets - .filter { sourceSet -> sourceSet.analysisPlatform == Platform.jvm } - .flatMap { it.externalDocumentationLinks } - .distinct() - } - - private val pathIndex = IdentityHashMap>().apply { - fun registerPath(page: PageNode, prefix: List = emptyList()) { - val newPrefix = prefix + page.takeIf { it is JavadocPackagePageNode }?.name.orEmpty() - val path = (prefix + when (page) { - is AllClassesPage -> listOf("allclasses") - is TreeViewPage -> if (page.classes == null) - listOf("overview-tree") - else - listOf("package-tree") - is ContentPage -> if (page.dri.isNotEmpty() && page.dri.first().classNames != null) - listOfNotNull(page.dri.first().classNames) - else if (page is JavadocPackagePageNode) - listOf(page.name, "package-summary") - else - listOf("index") - else -> emptyList() - }).filterNot { it.isEmpty() } - - put(page, path) - page.children.forEach { registerPath(it, newPrefix) } - - } - put(pageRoot, listOf("index")) - pageRoot.children.forEach { registerPath(it) } - } - - private val nodeIndex = IdentityHashMap().apply { - fun registerNode(node: PageNode) { - if (node is ContentPage) put(node.dri.first(), node) - - node.children.forEach(::registerNode) - } - registerNode(pageRoot) - } - - private operator fun IdentityHashMap>.get(dri: DRI) = this[nodeIndex[dri]] - - override fun resolve(dri: DRI, sourceSets: Set, context: PageNode?): String = - context?.let { resolve(it, skipExtension = false) } ?: nodeIndex[dri]?.let { - resolve(it, skipExtension = true) - } ?: with(externalLocationProvider!!) { - dri.toLocation() - } - - override fun resolve(node: PageNode, context: PageNode?, skipExtension: Boolean): String = - pathIndex[node]?.joinToString("/")?.let { - if (skipExtension) it.removeSuffix(".html") else it - } ?: run { - throw IllegalStateException("Path for ${node::class.java.canonicalName}:${node.name} not found") - } - - fun resolve(link: LinkJavadocListEntry, dir: String = "", skipExtension: Boolean = true) = - pathIndex[link.dri.first()]?.let { - when (link.kind) { - JavadocContentKind.Class -> it - JavadocContentKind.OverviewSummary -> it.dropLast(1) + "index" - JavadocContentKind.PackageSummary -> it.dropLast(1) + "package-summary" - JavadocContentKind.AllClasses -> it.dropLast(1) + "allclasses" - JavadocContentKind.OverviewTree -> it.dropLast(1) + "overview-tree" - JavadocContentKind.PackageTree -> it.dropLast(1) + "package-tree" - else -> it - } - }?.joinToString("/")?.let { if (skipExtension) "$it.html" else it }?.let { - Paths.get(dir).relativize(Paths.get(it)).toString() - } ?: run { "" } //TODO just a glue to compile it on HMPP - - override fun resolveRoot(node: PageNode): String { - TODO("Not yet implemented") - } - - override fun ancestors(node: PageNode): List { - TODO("Not yet implemented") - } -} \ No newline at end of file diff --git a/plugins/javadoc/src/main/kotlin/javadoc/JavadocPageCreator.kt b/plugins/javadoc/src/main/kotlin/javadoc/JavadocPageCreator.kt index 12c53ab7..767e0c68 100644 --- a/plugins/javadoc/src/main/kotlin/javadoc/JavadocPageCreator.kt +++ b/plugins/javadoc/src/main/kotlin/javadoc/JavadocPageCreator.kt @@ -17,7 +17,6 @@ import org.jetbrains.dokka.pages.ContentNode import org.jetbrains.dokka.pages.ContentText import org.jetbrains.dokka.pages.DCI import org.jetbrains.dokka.utilities.DokkaLogger -import org.jetbrains.kotlin.utils.addToStdlib.safeAs open class JavadocPageCreator( commentsToContentConverter: CommentsToContentConverter, @@ -47,13 +46,22 @@ open class JavadocPageCreator( modifiers = listOfNotNull(c.visibility[jvm]?.name), signature = signatureProvider.signature(c).nodeForJvm(jvm), description = c.descriptionToContentNodes(), - constructors = c.safeAs()?.constructors?.map { it.toJavadocFunction(jvm) }.orEmpty(), - methods = c.functions.map { it.toJavadocFunction(jvm) }, - entries = c.safeAs()?.entries?.map { JavadocEntryNode(signatureProvider.signature(it).nodeForJvm(jvm), it.descriptionToContentNodes(jvm)) }.orEmpty(), + constructors = (c as? WithConstructors)?.constructors?.mapNotNull { it.toJavadocFunction() }.orEmpty(), + methods = c.functions.mapNotNull { it.toJavadocFunction() }, + entries = (c as? DEnum)?.entries?.map { + JavadocEntryNode( + signatureProvider.signature(it).nodeForJvm(jvm), it.descriptionToContentNodes(jvm) + ) + }.orEmpty(), classlikes = c.classlikes.mapNotNull { pageForClasslike(it) }, - properties = c.properties.map { JavadocPropertyNode(signatureProvider.signature(it).nodeForJvm(jvm), it.descriptionToContentNodes(jvm)) }, + properties = c.properties.map { + JavadocPropertyNode( + signatureProvider.signature(it).nodeForJvm(jvm), + it.descriptionToContentNodes(jvm) + ) + }, documentable = c, - extras = c.safeAs>()?.extra ?: PropertyContainer.empty() + extras = (c as? WithExtraProperties)?.extra ?: PropertyContainer.empty() ) } @@ -61,7 +69,7 @@ open class JavadocPageCreator( JavadocContentGroup( setOf(m.dri), JavadocContentKind.OverviewSummary, - m.jvmSource.toSet() + m.jvmSourceSets.toSet() ) { title(m.name, m.brief(),"0.0.1", dri = setOf(m.dri), kind = ContentKind.Main) list("Packages", "Package", setOf(m.dri), ContentKind.Packages, m.packages.sortedBy { it.name }.map { p -> @@ -76,9 +84,9 @@ open class JavadocPageCreator( JavadocContentGroup( setOf(p.dri), JavadocContentKind.PackageSummary, - p.jvmSource.toSet() + p.jvmSourceSets.toSet() ) { - title(p.name, p.brief(),"0.0.1", dri = setOf(p.dri), kind = ContentKind.Packages) + title(p.name, p.brief(), "0.0.1", dri = setOf(p.dri), kind = ContentKind.Packages) list("Packages", "Package", setOf(p.dri), ContentKind.Packages, p.classlikes.sortedBy { it.name }.map { c -> RowJavadocListEntry( LinkJavadocListEntry(c.name.orEmpty(), setOf(c.dri), JavadocContentKind.Class, sourceSets), @@ -91,7 +99,7 @@ open class JavadocPageCreator( JavadocContentGroup( setOf(c.dri), JavadocContentKind.Class, - c.jvmSource.toSet() + c.jvmSourceSets.toSet() ) { title( c.name.orEmpty(), @@ -127,31 +135,34 @@ open class JavadocPageCreator( is UnresolvedBound -> p.name } - private fun DFunction.toJavadocFunction(sourceSetData: DokkaSourceSet) = JavadocFunctionNode( - name = name, - signature = signatureProvider.signature(this).nodeForJvm(sourceSetData), - brief = brief(sourceSetData), - parameters = parameters.map { - JavadocParameterNode( - name = it.name.orEmpty(), - type = signatureForProjection(it.type), - description = it.brief() - ) - }, - extras = extra - ) + private fun DFunction.toJavadocFunction() = highestJvmSourceSet?.let { jvm -> + JavadocFunctionNode( + name = name, + dri = dri, + signature = signatureProvider.signature(this).nodeForJvm(jvm), + brief = brief(jvm), + parameters = parameters.map { + JavadocParameterNode( + name = it.name.orEmpty(), + type = signatureForProjection(it.type), + description = it.brief() + ) + }, + extras = extra + ) + } - private val Documentable.jvmSource + private val Documentable.jvmSourceSets get() = sourceSets.filter { it.analysisPlatform == Platform.jvm } private val Documentable.highestJvmSourceSet - get() = jvmSource.let { sources -> - sources.firstOrNull { it != expectPresentInSet } ?: sources.firstOrNull() + get() = jvmSourceSets.let { sources -> + sources.firstOrNull { it != expectPresentInSet } ?: sources.firstOrNull() } private val firstSentenceRegex = Regex("^((?:[^.?!]|[.!?](?!\\s))*[.!?])") - private inline fun Documentable.findNodeInDocumentation(sourceSetData: DokkaSourceSet?): T? = + private inline fun Documentable.findNodeInDocumentation(sourceSetData: DokkaSourceSet?): T? = documentation[sourceSetData]?.firstChildOfType() private fun Documentable.descriptionToContentNodes(sourceSet: DokkaSourceSet? = highestJvmSourceSet) = findNodeInDocumentation(sourceSet)?.let { @@ -169,7 +180,7 @@ open class JavadocPageCreator( val description = descriptionToContentNodes(sourceSet) val contents = mutableListOf() for (node in description) { - if ( node is ContentText && firstSentenceRegex.containsMatchIn(node.text) ) { + if (node is ContentText && firstSentenceRegex.containsMatchIn(node.text)) { contents.add(node.copy(text = firstSentenceRegex.find(node.text)?.value.orEmpty())) break } else { diff --git a/plugins/javadoc/src/main/kotlin/javadoc/JavadocPlugin.kt b/plugins/javadoc/src/main/kotlin/javadoc/JavadocPlugin.kt index 504eecfd..2d24bbf1 100644 --- a/plugins/javadoc/src/main/kotlin/javadoc/JavadocPlugin.kt +++ b/plugins/javadoc/src/main/kotlin/javadoc/JavadocPlugin.kt @@ -1,16 +1,21 @@ package org.jetbrains.dokka.javadoc import javadoc.JavadocDocumentableToPageTranslator +import javadoc.location.JavadocLocationProviderFactory import javadoc.renderer.KorteJavadocRenderer import org.jetbrains.dokka.CoreExtensions import org.jetbrains.dokka.base.DokkaBase +import org.jetbrains.dokka.base.resolvers.external.JavadocExternalLocationProviderFactory import org.jetbrains.dokka.plugability.DokkaPlugin import org.jetbrains.dokka.plugability.querySingle -import org.jetbrains.dokka.kotlinAsJava.signatures.JavaSignatureProvider class JavadocPlugin : DokkaPlugin() { + + val dokkaBasePlugin by lazy { plugin() } + + val locationProviderFactory by extensionPoint() + val dokkaJavadocPlugin by extending { - val dokkaBasePlugin = plugin() CoreExtensions.renderer providing { ctx -> KorteJavadocRenderer( dokkaBasePlugin.querySingle { outputWriter }, @@ -21,7 +26,6 @@ class JavadocPlugin : DokkaPlugin() { } val pageTranslator by extending { - val dokkaBasePlugin = plugin() CoreExtensions.documentableToPageTranslator providing { context -> JavadocDocumentableToPageTranslator( dokkaBasePlugin.querySingle { commentsToContentConverter }, @@ -30,5 +34,11 @@ class JavadocPlugin : DokkaPlugin() { ) } } + + val javadocLocationProviderFactory by extending { + locationProviderFactory providing { context -> + JavadocLocationProviderFactory(context) + } + } } diff --git a/plugins/javadoc/src/main/kotlin/javadoc/location/JavadocLocationProvider.kt b/plugins/javadoc/src/main/kotlin/javadoc/location/JavadocLocationProvider.kt new file mode 100644 index 00000000..56a9015a --- /dev/null +++ b/plugins/javadoc/src/main/kotlin/javadoc/location/JavadocLocationProvider.kt @@ -0,0 +1,91 @@ +package javadoc.location + +import javadoc.pages.* +import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet +import org.jetbrains.dokka.Platform +import org.jetbrains.dokka.base.DokkaBase +import org.jetbrains.dokka.base.resolvers.local.LocationProvider +import org.jetbrains.dokka.base.resolvers.local.BaseLocationProvider +import org.jetbrains.dokka.links.DRI +import org.jetbrains.dokka.pages.ContentPage +import org.jetbrains.dokka.pages.PageNode +import org.jetbrains.dokka.pages.RootPageNode +import org.jetbrains.dokka.plugability.DokkaContext +import java.util.* + +class JavadocLocationProvider(pageRoot: RootPageNode, private val context: DokkaContext) : BaseLocationProvider(context) { + + private val pathIndex = IdentityHashMap>().apply { + fun registerPath(page: PageNode, prefix: List = emptyList()) { + val newPrefix = prefix + page.takeIf { it is JavadocPackagePageNode }?.name.orEmpty() + val path = (prefix + when (page) { + is AllClassesPage -> listOf("allclasses") + is TreeViewPage -> if (page.classes == null) + listOf("overview-tree") + else + listOf("package-tree") + is ContentPage -> if (page.dri.isNotEmpty() && page.dri.first().classNames != null) + listOfNotNull(page.dri.first().classNames) + else if (page is JavadocPackagePageNode) + listOf(page.name, "package-summary") + else + listOf("index") + else -> emptyList() + }).filterNot { it.isEmpty() } + + put(page, path) + page.children.forEach { registerPath(it, newPrefix) } + + } + put(pageRoot, listOf("index")) + pageRoot.children.forEach { registerPath(it) } + } + + private val nodeIndex = HashMap().apply { + fun registerNode(node: PageNode) { + if (node is ContentPage) put(node.dri.first(), node) + node.children.forEach(::registerNode) + } + registerNode(pageRoot) + } + + private operator fun IdentityHashMap>.get(dri: DRI) = this[nodeIndex[dri]] + + private fun List.relativeTo(context: List): String { + val contextPath = context.dropLast(1) + val commonPathElements = zip(contextPath).takeWhile { (a,b) -> a == b }.count() + return (List(contextPath.size - commonPathElements ) { ".." } + this.drop(commonPathElements)).joinToString("/") + } + + override fun resolve(dri: DRI, sourceSets: Set, context: PageNode?): String = + nodeIndex[dri]?.let { resolve(it, context) } + ?: getExternalLocation(dri, sourceSets) + + override fun resolve(node: PageNode, context: PageNode?, skipExtension: Boolean): String = + pathIndex[node]?.relativeTo(pathIndex[context].orEmpty())?.let { + if (skipExtension) it.removeSuffix(".html") else it + } ?: run { + throw IllegalStateException("Path for ${node::class.java.canonicalName}:${node.name} not found") + } + + fun resolve(link: LinkJavadocListEntry, contextRoot: PageNode? = null, skipExtension: Boolean = true) = + pathIndex[link.dri.first()]?.let { + when (link.kind) { + JavadocContentKind.Class -> it + JavadocContentKind.OverviewSummary -> it.dropLast(1) + "index" + JavadocContentKind.PackageSummary -> it.dropLast(1) + "package-summary" + JavadocContentKind.AllClasses -> it.dropLast(1) + "allclasses" + JavadocContentKind.OverviewTree -> it.dropLast(1) + "overview-tree" + JavadocContentKind.PackageTree -> it.dropLast(1) + "package-tree" + else -> it + } + }?.relativeTo(pathIndex[contextRoot].orEmpty())?.let { if (skipExtension) "$it.html" else it }.orEmpty() + + override fun resolveRoot(node: PageNode): String { + TODO("Not yet implemented") + } + + override fun ancestors(node: PageNode): List { + TODO("Not yet implemented") + } +} \ No newline at end of file diff --git a/plugins/javadoc/src/main/kotlin/javadoc/location/JavadocLocationProviderFactory.kt b/plugins/javadoc/src/main/kotlin/javadoc/location/JavadocLocationProviderFactory.kt new file mode 100644 index 00000000..b6bfb48d --- /dev/null +++ b/plugins/javadoc/src/main/kotlin/javadoc/location/JavadocLocationProviderFactory.kt @@ -0,0 +1,11 @@ +package javadoc.location + +import org.jetbrains.dokka.base.resolvers.local.LocationProviderFactory +import org.jetbrains.dokka.pages.RootPageNode +import org.jetbrains.dokka.plugability.DokkaContext + +class JavadocLocationProviderFactory(private val context: DokkaContext) : LocationProviderFactory { + + override fun getLocationProvider(pageNode: RootPageNode) = + JavadocLocationProvider(pageNode, context) +} \ No newline at end of file diff --git a/plugins/javadoc/src/main/kotlin/javadoc/pages/JavadocPageNodes.kt b/plugins/javadoc/src/main/kotlin/javadoc/pages/JavadocPageNodes.kt index 5ac232d4..24e481e8 100644 --- a/plugins/javadoc/src/main/kotlin/javadoc/pages/JavadocPageNodes.kt +++ b/plugins/javadoc/src/main/kotlin/javadoc/pages/JavadocPageNodes.kt @@ -104,28 +104,10 @@ data class JavadocFunctionNode( val signature: ContentNode, val brief: List, val parameters: List, - override val name: String, - override val dri: Set = emptySet(), - override val children: List = emptyList(), - override val documentable: Documentable? = null, - override val embeddedResources: List = emptyList(), + val name: String, + val dri: DRI, val extras: PropertyContainer = PropertyContainer.empty() -) : JavadocPageNode { - - override val content: ContentNode = EmptyNode(DRI.topLevel, ContentKind.Classlikes, emptySet()) - - override fun modified( - name: String, - children: List - ): PageNode = TODO() - - override fun modified( - name: String, - content: ContentNode, - dri: Set, - embeddedResources: List, - children: List - ): ContentPage = TODO() +) { val modifiersAndSignature: Pair get() = (signature as ContentGroup).splitSignatureIntoModifiersAndName() @@ -340,7 +322,6 @@ class TreeViewPage( listOf(psi to l) + l.flatMap { gatherPsiClasses(it) } } - val psiInheritanceTree = documentables.flatMap { (_, v) -> (v as? WithExpectActual)?.sources?.values.orEmpty() } .filterIsInstance().mapNotNull { it.psi as? PsiClass }.flatMap(::gatherPsiClasses) .flatMap { entry -> entry.second.map { it to entry.first } } diff --git a/plugins/javadoc/src/main/kotlin/javadoc/renderer/JavadocContentToHtmlTranslator.kt b/plugins/javadoc/src/main/kotlin/javadoc/renderer/JavadocContentToHtmlTranslator.kt index 5f628626..7d6f37c0 100644 --- a/plugins/javadoc/src/main/kotlin/javadoc/renderer/JavadocContentToHtmlTranslator.kt +++ b/plugins/javadoc/src/main/kotlin/javadoc/renderer/JavadocContentToHtmlTranslator.kt @@ -1,41 +1,31 @@ package javadoc.renderer import javadoc.pages.TextNode -import org.jetbrains.dokka.DokkaConfiguration import org.jetbrains.dokka.base.resolvers.local.LocationProvider -import org.jetbrains.dokka.links.DRI import org.jetbrains.dokka.pages.* import org.jetbrains.dokka.plugability.DokkaContext -import java.nio.file.Path -import java.nio.file.Paths internal class JavadocContentToHtmlTranslator( private val locationProvider: LocationProvider, private val context: DokkaContext ) { - fun htmlForContentNode(node: ContentNode, relative: T?, locate: ContentDRILink.(T?) -> String): String = + fun htmlForContentNode(node: ContentNode, relative: PageNode?): String = when (node) { - is ContentGroup -> htmlForContentNodes(node.children, relative, locate) + is ContentGroup -> htmlForContentNodes(node.children, relative) is ContentText -> node.text is TextNode -> node.text is ContentDRILink -> buildLink( - node.locate(relative), - htmlForContentNodes(node.children, relative, locate) + locationProvider.resolve(node.address, node.sourceSets, relative), + htmlForContentNodes(node.children, relative) ) - is ContentResolvedLink -> buildLink(node.address, htmlForContentNodes(node.children, relative, locate)) + is ContentResolvedLink -> buildLink(node.address, htmlForContentNodes(node.children, relative)) is ContentCode -> htmlForCode(node.children) else -> "" } - fun htmlForContentNodes(list: List, relative: T?, locate: ContentDRILink.(T?) -> String) = - list.joinToString(separator = "") { htmlForContentNode(it, relative, locate) } - - private fun locate(link: ContentDRILink, relativePath: String?) = - resolveLink(link.address, link.sourceSets, relativePath) - - fun htmlForContentNodes(list: List, relative: String?) = - htmlForContentNodes(list, relative, ::locate) + fun htmlForContentNodes(list: List, relative: PageNode?) = + list.joinToString(separator = "") { htmlForContentNode(it, relative) } private fun htmlForCode(code: List): String = code.map { element -> when (element) { @@ -45,16 +35,6 @@ internal class JavadocContentToHtmlTranslator( } }.joinToString("
", """""", "") { it } - private fun resolveLink(address: DRI, sourceSets: Set, relativePath: String?) = - locationProvider.resolve(address, sourceSets).let { - val afterFormattingToHtml = it.formatToEndWithHtml() - if (relativePath != null) afterFormattingToHtml.relativizePath(relativePath) - else afterFormattingToHtml - } - - private fun String.relativizePath(parent: String) = - Paths.get(parent).relativize(Paths.get(this)).normalize().toFile().toString() - companion object { fun buildLink(address: String, content: String) = diff --git a/plugins/javadoc/src/main/kotlin/javadoc/renderer/JavadocContentToTemplateMapTranslator.kt b/plugins/javadoc/src/main/kotlin/javadoc/renderer/JavadocContentToTemplateMapTranslator.kt index 4d1ccca5..50a971ea 100644 --- a/plugins/javadoc/src/main/kotlin/javadoc/renderer/JavadocContentToTemplateMapTranslator.kt +++ b/plugins/javadoc/src/main/kotlin/javadoc/renderer/JavadocContentToTemplateMapTranslator.kt @@ -19,6 +19,7 @@ internal class JavadocContentToTemplateMapTranslator( mapOf( "docName" to "docName", // todo docname "pathToRoot" to pathToRoot, + "contextRoot" to node, "kind" to "main", ) + templateMapForNode(node) @@ -27,7 +28,6 @@ internal class JavadocContentToTemplateMapTranslator( when (node) { is JavadocModulePageNode -> InnerTranslator(node).templateMapForJavadocContentNode(node.content) is JavadocClasslikePageNode -> InnerTranslator(node).templateMapForClasslikeNode(node) - is JavadocFunctionNode -> InnerTranslator(node).templateMapForFunctionNode(node) is JavadocPackagePageNode -> InnerTranslator(node).templateMapForPackagePageNode(node) is TreeViewPage -> InnerTranslator(node).templateMapForTreeViewPage(node) is AllClassesPage -> InnerTranslator(node).templateMapForAllClassesPage(node) @@ -65,19 +65,19 @@ internal class JavadocContentToTemplateMapTranslator( internal fun templateMapForFunctionNode(node: JavadocFunctionNode): TemplateMap { val (modifiers, signature) = node.modifiersAndSignature return mapOf( - "signature" to htmlForContentNode(node.signature, node), - "brief" to htmlForContentNodes(node.brief, node), + "signature" to htmlForContentNode(node.signature, contextNode), + "brief" to htmlForContentNodes(node.brief, contextNode), "parameters" to node.parameters.map { templateMapForParameterNode(it) }, "inlineParameters" to node.parameters.joinToString { "${it.type} ${it.name}" }, - "modifiers" to htmlForContentNode(modifiers, node), - "signatureWithoutModifiers" to htmlForContentNode(signature, node), + "modifiers" to htmlForContentNode(modifiers, contextNode), + "signatureWithoutModifiers" to htmlForContentNode(signature, contextNode), "name" to node.name ) } internal fun templateMapForClasslikeNode(node: JavadocClasslikePageNode): TemplateMap = mapOf( - "constructors" to node.constructors.map { templateMapForNode(it) }, + "constructors" to node.constructors.map { templateMapForFunctionNode(it) }, "signature" to htmlForContentNode(node.signature, node), "methods" to templateMapForClasslikeMethods(node.methods), "classlikeDocumentation" to htmlForContentNodes(node.description, node), @@ -113,12 +113,12 @@ internal class JavadocContentToTemplateMapTranslator( private fun templateMapForClasslikeMethods(nodes: List): TemplateMap { val (inherited, own) = nodes.partition { val extra = it.extras[InheritedFunction] - extra?.inheritedFrom?.keys?.first { it.analysisPlatform == Platform.jvm }?.let { jvm -> + extra?.inheritedFrom?.keys?.firstOrNull { it.analysisPlatform == Platform.jvm }?.let { jvm -> extra.isInherited(jvm) } ?: false } return mapOf( - "own" to own.map { templateMapForNode(it) }, + "own" to own.map { templateMapForFunctionNode(it) }, "inherited" to inherited.map { templateMapForInheritedMethod(it) } .groupBy { it["inheritedFrom"] as String }.entries.map { mapOf( @@ -188,14 +188,12 @@ internal class JavadocContentToTemplateMapTranslator( "list" to node.children ) } - fun locate(link: ContentDRILink, relativeNode: PageNode?) = - locationProvider.resolve(link.address, link.sourceSets, relativeNode) private fun htmlForContentNode(node: ContentNode, relativeNode: PageNode) = - htmlTranslator.htmlForContentNode(node, relativeNode, ::locate) + htmlTranslator.htmlForContentNode(node, relativeNode) private fun htmlForContentNodes(nodes: List, relativeNode: PageNode) = - htmlTranslator.htmlForContentNodes(nodes, relativeNode, ::locate) + htmlTranslator.htmlForContentNodes(nodes, relativeNode) } private fun DRI.displayable(): String = "${packageName}.${sureClassNames}" diff --git a/plugins/javadoc/src/main/kotlin/javadoc/renderer/KorteJavadocRenderer.kt b/plugins/javadoc/src/main/kotlin/javadoc/renderer/KorteJavadocRenderer.kt index 7b122b7d..a7d18100 100644 --- a/plugins/javadoc/src/main/kotlin/javadoc/renderer/KorteJavadocRenderer.kt +++ b/plugins/javadoc/src/main/kotlin/javadoc/renderer/KorteJavadocRenderer.kt @@ -1,7 +1,7 @@ package javadoc.renderer import com.soywiz.korte.* -import javadoc.JavadocLocationProvider +import javadoc.location.JavadocLocationProvider import javadoc.pages.* import javadoc.renderer.JavadocContentToHtmlTranslator.Companion.buildLink import kotlinx.coroutines.CoroutineScope @@ -9,9 +9,12 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import org.jetbrains.dokka.base.renderers.OutputWriter +import org.jetbrains.dokka.javadoc.JavadocPlugin import org.jetbrains.dokka.links.DRI import org.jetbrains.dokka.pages.* import org.jetbrains.dokka.plugability.DokkaContext +import org.jetbrains.dokka.plugability.plugin +import org.jetbrains.dokka.plugability.querySingle import org.jetbrains.dokka.renderers.Renderer import org.jetbrains.kotlin.utils.addToStdlib.safeAs import java.nio.file.Path @@ -20,14 +23,22 @@ import java.time.LocalDate typealias TemplateMap = Map -class KorteJavadocRenderer(val outputWriter: OutputWriter, val context: DokkaContext, val resourceDir: String) : +class KorteJavadocRenderer(private val outputWriter: OutputWriter, val context: DokkaContext, resourceDir: String) : Renderer { private lateinit var locationProvider: JavadocLocationProvider - override fun render(root: RootPageNode) = root.let { preprocessors.fold(root) { r, t -> t.invoke(r) } }.let { r -> - locationProvider = JavadocLocationProvider(r, context) + private val contentToHtmlTranslator by lazy { + JavadocContentToHtmlTranslator(locationProvider, context) + } + + private val contentToTemplateMapTranslator by lazy { + JavadocContentToTemplateMapTranslator(locationProvider, context) + } + + override fun render(root: RootPageNode) = root.let { preprocessors.fold(root) { r, t -> t.invoke(r) } }.let { newRoot -> + locationProvider = context.plugin().querySingle { locationProviderFactory }.getLocationProvider(newRoot) runBlocking(Dispatchers.IO) { - renderModulePageNode(r as JavadocModulePageNode) + renderModulePageNode(newRoot as JavadocModulePageNode) } } @@ -53,7 +64,7 @@ class KorteJavadocRenderer(val outputWriter: OutputWriter, val context: DokkaCon val name = "index" val pathToRoot = "" - val contentMap = JavadocContentToTemplateMapTranslator(locationProvider, context).templateMapForPageNode(node, pathToRoot) + val contentMap = contentToTemplateMapTranslator.templateMapForPageNode(node, pathToRoot) writeFromTemplate(outputWriter, "$link/$name".toNormalized(), "tabPage.korte", contentMap.toList()) node.children.forEach { renderNode(it, link) } @@ -66,12 +77,12 @@ class KorteJavadocRenderer(val outputWriter: OutputWriter, val context: DokkaCon if (it.isNotEmpty()) "$it/" else it } - val contentMap = JavadocContentToTemplateMapTranslator(locationProvider, context).templateMapForPageNode(node, pathToRoot) + val contentMap = contentToTemplateMapTranslator.templateMapForPageNode(node, pathToRoot) writeFromTemplate(outputWriter, link, templateForNode(node), contentMap.toList()) node.children.forEach { renderNode(it, link.toNormalized()) } } - fun CoroutineScope.renderSpecificPage(node: RendererSpecificPage, path: String) = launch { + private fun CoroutineScope.renderSpecificPage(node: RendererSpecificPage, path: String) = launch { when (val strategy = node.strategy) { is RenderingStrategy.Copy -> outputWriter.writeResources(strategy.from, "") is RenderingStrategy.Write -> outputWriter.writeHtml(path, strategy.text) @@ -83,10 +94,10 @@ class KorteJavadocRenderer(val outputWriter: OutputWriter, val context: DokkaCon } } - fun Pair.pairToTag() = - """${first}\n${second}""" + private fun Pair.pairToTag() = + """${first}${second}""" - fun DRI.toLink(context: PageNode? = null) = locationProvider.resolve(this, emptySet(), context) + private fun DRI.toLink(context: PageNode? = null) = locationProvider.resolve(this, emptySet(), context) private fun Path.toNormalized() = this.normalize().toFile().toString() private fun String.toNormalized() = Paths.get(this).toNormalized() @@ -102,7 +113,7 @@ class KorteJavadocRenderer(val outputWriter: OutputWriter, val context: DokkaCon writer.writeHtml(path, tmp) } - fun getTemplateConfig() = TemplateConfig().also { config -> + private fun getTemplateConfig() = TemplateConfig().also { config -> listOf( TeFunction("curDate") { LocalDate.now() }, TeFunction("jQueryVersion") { "3.1" }, @@ -111,18 +122,17 @@ class KorteJavadocRenderer(val outputWriter: OutputWriter, val context: DokkaCon TeFunction("h1Title") { args -> if ((args.first() as? String) == "package") "title=\"Package\" " else "" }, TeFunction("createTabRow") { args -> val (link, doc) = args.first() as RowJavadocListEntry - val dir = args[1] as String? - val translator = JavadocContentToHtmlTranslator(locationProvider, context) + val contextRoot = args[1] as PageNode? (buildLink( - locationProvider.resolve(link, dir.orEmpty()), + locationProvider.resolve(link, contextRoot), link.name - ) to translator.htmlForContentNodes(doc, dir)).pairToTag().trim() + ) to contentToHtmlTranslator.htmlForContentNodes(doc, contextRoot)).pairToTag().trim() }, TeFunction("createListRow") { args -> val link = args.first() as LinkJavadocListEntry - val dir = args[1] as String? + val contextRoot = args[1] as PageNode? buildLink( - locationProvider.resolve(link, dir.orEmpty()), + locationProvider.resolve(link, contextRoot), link.name ) }, @@ -171,13 +181,14 @@ class KorteJavadocRenderer(val outputWriter: OutputWriter, val context: DokkaCon } } - val config = getTemplateConfig() - val templateRenderer = Templates( + private val config = getTemplateConfig() + private val templateRenderer = Templates( ResourceTemplateProvider( resourceDir - ), config = config, cache = true) + ), config = config, cache = true + ) - class ResourceTemplateProvider(val basePath: String) : TemplateProvider { + private class ResourceTemplateProvider(val basePath: String) : TemplateProvider { override suspend fun get(template: String): String = javaClass.classLoader.getResourceAsStream("$basePath/$template")?.bufferedReader()?.lines()?.toArray() ?.joinToString("\n") ?: throw IllegalStateException("Template not found: $basePath/$template") -- cgit