From 02f30b142aa467d3a24cc52a1fe3f2fed7ea1e33 Mon Sep 17 00:00:00 2001 From: Ignat Beresnev Date: Thu, 31 Aug 2023 20:16:01 +0200 Subject: Enable explicit API mode (#3139) --- .../src/main/kotlin/renderers/DefaultRenderer.kt | 79 +++++++++------- .../base/src/main/kotlin/renderers/FileWriter.kt | 7 +- .../base/src/main/kotlin/renderers/OutputWriter.kt | 6 +- .../main/kotlin/renderers/PackageListService.kt | 23 ++++- .../main/kotlin/renderers/TabSortingStrategy.kt | 4 +- .../main/kotlin/renderers/contentTypeChecking.kt | 11 ++- .../src/main/kotlin/renderers/html/HtmlRenderer.kt | 103 +++++++++++++-------- .../renderers/html/NavigationDataProvider.kt | 6 +- .../main/kotlin/renderers/html/NavigationPage.kt | 24 ++--- .../renderers/html/SearchbarDataInstaller.kt | 25 +++-- .../base/src/main/kotlin/renderers/html/Tags.kt | 34 +++---- .../consumers/ImmediateResolutionTagConsumer.kt | 10 +- .../html/command/consumers/PathToRootConsumer.kt | 4 +- .../command/consumers/ReplaceVersionsConsumer.kt | 4 +- .../html/command/consumers/ResolveLinkConsumer.kt | 4 +- .../kotlin/renderers/html/htmlFormatingUtils.kt | 7 +- .../kotlin/renderers/html/htmlPreprocessors.kt | 20 ++-- .../innerTemplating/DefaultTemplateModelFactory.kt | 6 +- .../innerTemplating/DefaultTemplateModelMerger.kt | 2 +- .../html/innerTemplating/HtmlTemplater.kt | 12 ++- .../html/innerTemplating/TemplateModelFactory.kt | 6 +- .../html/innerTemplating/TemplateModelMerger.kt | 4 +- .../src/main/kotlin/renderers/preprocessors.kt | 16 ++-- 23 files changed, 244 insertions(+), 173 deletions(-) (limited to 'plugins/base/src/main/kotlin/renderers') diff --git a/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt b/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt index edbf1037..eed7794e 100644 --- a/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt +++ b/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt @@ -19,61 +19,68 @@ import org.jetbrains.dokka.plugability.querySingle import org.jetbrains.dokka.renderers.Renderer import org.jetbrains.dokka.transformers.pages.PageTransformer -abstract class DefaultRenderer( +public abstract class DefaultRenderer( protected val context: DokkaContext ) : Renderer { - protected val outputWriter = context.plugin().querySingle { outputWriter } + protected val outputWriter: OutputWriter = context.plugin().querySingle { outputWriter } protected lateinit var locationProvider: LocationProvider private set protected open val preprocessors: Iterable = emptyList() - abstract fun T.buildHeader(level: Int, node: ContentHeader, content: T.() -> Unit) - abstract fun T.buildLink(address: String, content: T.() -> Unit) - abstract fun T.buildList( + public abstract fun T.buildHeader(level: Int, node: ContentHeader, content: T.() -> Unit) + public abstract fun T.buildLink(address: String, content: T.() -> Unit) + public abstract fun T.buildList( node: ContentList, pageContext: ContentPage, sourceSetRestriction: Set? = null ) - abstract fun T.buildLineBreak() - open fun T.buildLineBreak(node: ContentBreakLine, pageContext: ContentPage) = buildLineBreak() + public abstract fun T.buildLineBreak() + public open fun T.buildLineBreak(node: ContentBreakLine, pageContext: ContentPage) { + buildLineBreak() + } - abstract fun T.buildResource(node: ContentEmbeddedResource, pageContext: ContentPage) - abstract fun T.buildTable( + public abstract fun T.buildResource(node: ContentEmbeddedResource, pageContext: ContentPage) + public abstract fun T.buildTable( node: ContentTable, pageContext: ContentPage, sourceSetRestriction: Set? = null ) - abstract fun T.buildText(textNode: ContentText) - abstract fun T.buildNavigation(page: PageNode) + public abstract fun T.buildText(textNode: ContentText) + public abstract fun T.buildNavigation(page: PageNode) - abstract fun buildPage(page: ContentPage, content: (T, ContentPage) -> Unit): String - abstract fun buildError(node: ContentNode) + public abstract fun buildPage(page: ContentPage, content: (T, ContentPage) -> Unit): String + public abstract fun buildError(node: ContentNode) - open fun T.buildPlatformDependent( + public open fun T.buildPlatformDependent( content: PlatformHintedContent, pageContext: ContentPage, sourceSetRestriction: Set? - ) = buildContentNode(content.inner, pageContext) + ) { + buildContentNode(content.inner, pageContext) + } - open fun T.buildGroup( + public open fun T.buildGroup( node: ContentGroup, pageContext: ContentPage, sourceSetRestriction: Set? = null - ) = + ) { wrapGroup(node, pageContext) { node.children.forEach { it.build(this, pageContext, sourceSetRestriction) } } + } - open fun T.buildDivergent(node: ContentDivergentGroup, pageContext: ContentPage) = + public open fun T.buildDivergent(node: ContentDivergentGroup, pageContext: ContentPage) { node.children.forEach { it.build(this, pageContext) } + } - open fun T.wrapGroup(node: ContentGroup, pageContext: ContentPage, childrenCallback: T.() -> Unit) = + public open fun T.wrapGroup(node: ContentGroup, pageContext: ContentPage, childrenCallback: T.() -> Unit) { childrenCallback() + } - open fun T.buildText( + public open fun T.buildText( nodes: List, pageContext: ContentPage, sourceSetRestriction: Set? = null @@ -81,15 +88,15 @@ abstract class DefaultRenderer( nodes.forEach { it.build(this, pageContext, sourceSetRestriction) } } - open fun T.buildCodeBlock(code: ContentCodeBlock, pageContext: ContentPage) { + public open fun T.buildCodeBlock(code: ContentCodeBlock, pageContext: ContentPage) { code.children.forEach { it.build(this, pageContext) } } - open fun T.buildCodeInline(code: ContentCodeInline, pageContext: ContentPage) { + public open fun T.buildCodeInline(code: ContentCodeInline, pageContext: ContentPage) { code.children.forEach { it.build(this, pageContext) } } - open fun T.buildHeader( + public open fun T.buildHeader( node: ContentHeader, pageContext: ContentPage, sourceSetRestriction: Set? = null @@ -97,19 +104,23 @@ abstract class DefaultRenderer( buildHeader(node.level, node) { node.children.forEach { it.build(this, pageContext, sourceSetRestriction) } } } - open fun ContentNode.build( + public open fun ContentNode.build( builder: T, pageContext: ContentPage, sourceSetRestriction: Set? = null - ) = builder.buildContentNode(this, pageContext, sourceSetRestriction) + ) { + builder.buildContentNode(this, pageContext, sourceSetRestriction) + } - fun T.buildContentNode( + public fun T.buildContentNode( node: ContentNode, pageContext: ContentPage, sourceSetRestriction: DisplaySourceSet - ) = buildContentNode(node, pageContext, setOf(sourceSetRestriction)) + ) { + buildContentNode(node, pageContext, setOf(sourceSetRestriction)) + } - open fun T.buildContentNode( + public open fun T.buildContentNode( node: ContentNode, pageContext: ContentPage, sourceSetRestriction: Set? = null @@ -135,7 +146,7 @@ abstract class DefaultRenderer( } } - open fun T.buildDRILink( + public open fun T.buildDRILink( node: ContentDRILink, pageContext: ContentPage, sourceSetRestriction: Set? @@ -147,7 +158,7 @@ abstract class DefaultRenderer( } ?: buildText(node.children, pageContext, sourceSetRestriction) } - open fun T.buildResolvedLink( + public open fun T.buildResolvedLink( node: ContentResolvedLink, pageContext: ContentPage, sourceSetRestriction: Set? @@ -157,18 +168,18 @@ abstract class DefaultRenderer( } } - open fun T.buildDivergentInstance(node: ContentDivergentInstance, pageContext: ContentPage) { + public open fun T.buildDivergentInstance(node: ContentDivergentInstance, pageContext: ContentPage) { node.before?.build(this, pageContext) node.divergent.build(this, pageContext) node.after?.build(this, pageContext) } - open fun buildPageContent(context: T, page: ContentPage) { + public open fun buildPageContent(context: T, page: ContentPage) { context.buildNavigation(page) page.content.build(context, page) } - open suspend fun renderPage(page: PageNode) { + public open suspend fun renderPage(page: PageNode) { val path by lazy { locationProvider.resolve(page, skipExtension = true) ?: throw DokkaException("Cannot resolve path for ${page.name}") @@ -243,4 +254,4 @@ abstract class DefaultRenderer( internal typealias SerializedBeforeAndAfter = Pair internal typealias InstanceWithSource = Pair -fun ContentPage.sourceSets() = this.content.sourceSets +public fun ContentPage.sourceSets(): Set = this.content.sourceSets diff --git a/plugins/base/src/main/kotlin/renderers/FileWriter.kt b/plugins/base/src/main/kotlin/renderers/FileWriter.kt index 0bca1591..1a1c3b42 100644 --- a/plugins/base/src/main/kotlin/renderers/FileWriter.kt +++ b/plugins/base/src/main/kotlin/renderers/FileWriter.kt @@ -14,7 +14,9 @@ import java.io.IOException import java.net.URI import java.nio.file.* -class FileWriter(val context: DokkaContext): OutputWriter { +public class FileWriter( + public val context: DokkaContext +): OutputWriter { private val createdFiles: MutableSet = mutableSetOf() private val createdFilesMutex = Mutex() private val jarUriPrefix = "jar:file:" @@ -44,12 +46,13 @@ class FileWriter(val context: DokkaContext): OutputWriter { return false } - override suspend fun writeResources(pathFrom: String, pathTo: String) = + override suspend fun writeResources(pathFrom: String, pathTo: String) { if (javaClass.getResource(pathFrom)?.toURI()?.toString()?.startsWith(jarUriPrefix) == true) { copyFromJar(pathFrom, pathTo) } else { copyFromDirectory(pathFrom, pathTo) } + } private suspend fun copyFromDirectory(pathFrom: String, pathTo: String) { diff --git a/plugins/base/src/main/kotlin/renderers/OutputWriter.kt b/plugins/base/src/main/kotlin/renderers/OutputWriter.kt index 9c5de394..3fdd1802 100644 --- a/plugins/base/src/main/kotlin/renderers/OutputWriter.kt +++ b/plugins/base/src/main/kotlin/renderers/OutputWriter.kt @@ -4,8 +4,8 @@ package org.jetbrains.dokka.base.renderers -interface OutputWriter { +public interface OutputWriter { - suspend fun write(path: String, text: String, ext: String) - suspend fun writeResources(pathFrom: String, pathTo: String) + public suspend fun write(path: String, text: String, ext: String) + public suspend fun writeResources(pathFrom: String, pathTo: String) } diff --git a/plugins/base/src/main/kotlin/renderers/PackageListService.kt b/plugins/base/src/main/kotlin/renderers/PackageListService.kt index 1d062542..3ed6cd21 100644 --- a/plugins/base/src/main/kotlin/renderers/PackageListService.kt +++ b/plugins/base/src/main/kotlin/renderers/PackageListService.kt @@ -15,9 +15,12 @@ import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.plugability.plugin import org.jetbrains.dokka.plugability.querySingle -class PackageListService(val context: DokkaContext, val rootPage: RootPageNode) { +public class PackageListService( + public val context: DokkaContext, + public val rootPage: RootPageNode +) { - fun createPackageList(module: ModulePage, format: LinkFormat): String { + public fun createPackageList(module: ModulePage, format: LinkFormat): String { val packages = mutableSetOf() val nonStandardLocations = mutableMapOf() @@ -46,11 +49,21 @@ class PackageListService(val context: DokkaContext, val rootPage: RootPageNode) } visit(module) - return renderPackageList(nonStandardLocations, mapOf(SINGLE_MODULE_NAME to packages), format.formatName, format.linkExtension) + return renderPackageList( + nonStandardLocations = nonStandardLocations, + modules = mapOf(SINGLE_MODULE_NAME to packages), + format = format.formatName, + linkExtension = format.linkExtension + ) } - companion object { - fun renderPackageList(nonStandardLocations: Map, modules: Map>, format: String, linkExtension: String): String = buildString { + public companion object { + public fun renderPackageList( + nonStandardLocations: Map, + modules: Map>, + format: String, + linkExtension: String + ): String = buildString { appendLine("$DOKKA_PARAM_PREFIX.format:${format}") appendLine("$DOKKA_PARAM_PREFIX.linkExtension:${linkExtension}") nonStandardLocations.map { (signature, location) -> diff --git a/plugins/base/src/main/kotlin/renderers/TabSortingStrategy.kt b/plugins/base/src/main/kotlin/renderers/TabSortingStrategy.kt index c76094f9..665b6717 100644 --- a/plugins/base/src/main/kotlin/renderers/TabSortingStrategy.kt +++ b/plugins/base/src/main/kotlin/renderers/TabSortingStrategy.kt @@ -6,6 +6,6 @@ package org.jetbrains.dokka.base.renderers import org.jetbrains.dokka.pages.ContentNode -interface TabSortingStrategy { - fun sort(tabs: Collection) : List +public interface TabSortingStrategy { + public fun sort(tabs: Collection) : List } diff --git a/plugins/base/src/main/kotlin/renderers/contentTypeChecking.kt b/plugins/base/src/main/kotlin/renderers/contentTypeChecking.kt index 8074dab6..0fcb0efb 100644 --- a/plugins/base/src/main/kotlin/renderers/contentTypeChecking.kt +++ b/plugins/base/src/main/kotlin/renderers/contentTypeChecking.kt @@ -8,16 +8,17 @@ import org.jetbrains.dokka.base.renderers.HtmlFileExtensions.imageExtensions import org.jetbrains.dokka.pages.ContentEmbeddedResource import java.io.File -fun ContentEmbeddedResource.isImage(): Boolean { +public fun ContentEmbeddedResource.isImage(): Boolean { return File(address).extension.toLowerCase() in imageExtensions } -val String.URIExtension: String +public val String.URIExtension: String get() = substringBefore('?').substringAfterLast('.') -fun String.isImage(): Boolean = +public fun String.isImage(): Boolean = URIExtension in imageExtensions -object HtmlFileExtensions { - val imageExtensions = setOf("png", "jpg", "jpeg", "gif", "bmp", "tif", "webp", "svg") +public object HtmlFileExtensions { + public val imageExtensions: Set = setOf("png", "jpg", "jpeg", "gif", "bmp", "tif", "webp", "svg") } + diff --git a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt index 9d361f70..083876d5 100644 --- a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt +++ b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt @@ -27,12 +27,13 @@ import org.jetbrains.dokka.model.properties.WithExtraProperties import org.jetbrains.dokka.pages.* import org.jetbrains.dokka.pages.HtmlContent import org.jetbrains.dokka.plugability.* +import org.jetbrains.dokka.transformers.pages.PageTransformer import org.jetbrains.dokka.utilities.htmlEscape internal const val TEMPLATE_REPLACEMENT: String = "###" internal const val TOGGLEABLE_CONTENT_TYPE_ATTR = "data-togglable" -open class HtmlRenderer( +public open class HtmlRenderer( context: DokkaContext ) : DefaultRenderer(context) { private val sourceSetDependencyMap: Map> = @@ -50,7 +51,7 @@ open class HtmlRenderer( private var shouldRenderSourceSetTabs: Boolean = false - override val preprocessors = context.plugin().query { htmlPreprocessors } + override val preprocessors: List = context.plugin().query { htmlPreprocessors } /** * Tabs themselves are created in HTML plugin since, currently, only HTML format supports them. @@ -253,7 +254,7 @@ open class HtmlRenderer( content: PlatformHintedContent, pageContext: ContentPage, sourceSetRestriction: Set? - ) = + ) { buildPlatformDependent( content.sourceSets.filter { sourceSetRestriction == null || it in sourceSetRestriction @@ -262,6 +263,7 @@ open class HtmlRenderer( content.extra, content.style ) + } private fun FlowContent.buildPlatformDependent( nodes: Map>, @@ -409,19 +411,21 @@ open class HtmlRenderer( node: ContentList, pageContext: ContentPage, sourceSetRestriction: Set? - ) = when { - node.ordered -> { - ol { buildListItems(node.children, pageContext, sourceSetRestriction) } - } - node.hasStyle(ListStyle.DescriptionList) -> { - dl { node.children.forEach { it.build(this, pageContext, sourceSetRestriction) } } - } - else -> { - ul { buildListItems(node.children, pageContext, sourceSetRestriction) } + ) { + return when { + node.ordered -> { + ol { buildListItems(node.children, pageContext, sourceSetRestriction) } + } + node.hasStyle(ListStyle.DescriptionList) -> { + dl { node.children.forEach { it.build(this, pageContext, sourceSetRestriction) } } + } + else -> { + ul { buildListItems(node.children, pageContext, sourceSetRestriction) } + } } } - open fun OL.buildListItems( + public open fun OL.buildListItems( items: List, pageContext: ContentPage, sourceSetRestriction: Set? = null @@ -434,7 +438,7 @@ open class HtmlRenderer( } } - open fun UL.buildListItems( + public open fun UL.buildListItems( items: List, pageContext: ContentPage, sourceSetRestriction: Set? = null @@ -450,12 +454,13 @@ open class HtmlRenderer( override fun FlowContent.buildResource( node: ContentEmbeddedResource, pageContext: ContentPage - ) = // TODO: extension point there + ) { // TODO: extension point there if (node.isImage()) { img(src = node.address, alt = node.altText) } else { println("Unrecognized resource type: $node") } + } private fun FlowContent.buildRow( node: ContentGroup, @@ -642,7 +647,7 @@ open class HtmlRenderer( } - fun FlowContent.buildDefaultTable( + public fun FlowContent.buildDefaultTable( node: ContentTable, pageContext: ContentPage, sourceSetRestriction: Set? @@ -709,7 +714,7 @@ open class HtmlRenderer( } - override fun FlowContent.buildNavigation(page: PageNode) = + override fun FlowContent.buildNavigation(page: PageNode) { div(classes = "breadcrumbs") { val path = locationProvider.ancestors(page).filterNot { it is RendererSpecificPage }.asReversed() if (path.size > 1) { @@ -722,6 +727,7 @@ open class HtmlRenderer( } } } + } private fun FlowContent.buildNavigationElement(node: PageNode, page: PageNode) = if (node.isNavigable) { @@ -747,7 +753,7 @@ open class HtmlRenderer( text(to.name) } - fun FlowContent.buildAnchorCopyButton(pointingTo: String) { + public fun FlowContent.buildAnchorCopyButton(pointingTo: String) { span(classes = "anchor-wrapper") { span(classes = "anchor-icon") { attributes["pointing-to"] = pointingTo @@ -756,17 +762,23 @@ open class HtmlRenderer( } } - fun FlowContent.buildLink( + public fun FlowContent.buildLink( to: DRI, platforms: List, from: PageNode? = null, block: FlowContent.() -> Unit - ) = locationProvider.resolve(to, platforms.toSet(), from)?.let { buildLink(it, block) } - ?: run { context.logger.error("Cannot resolve path for `$to` from `$from`"); block() } + ) { + locationProvider.resolve(to, platforms.toSet(), from)?.let { buildLink(it, block) } + ?: run { context.logger.error("Cannot resolve path for `$to` from `$from`"); block() } + } - override fun buildError(node: ContentNode) = context.logger.error("Unknown ContentNode type: $node") + override fun buildError(node: ContentNode) { + context.logger.error("Unknown ContentNode type: $node") + } - override fun FlowContent.buildLineBreak() = br() + override fun FlowContent.buildLineBreak() { + br() + } override fun FlowContent.buildLineBreak(node: ContentBreakLine, pageContext: ContentPage) { if (node.style.contains(HorizontalBreakLineStyle)) { hr() @@ -775,25 +787,28 @@ open class HtmlRenderer( } } - override fun FlowContent.buildLink(address: String, content: FlowContent.() -> Unit) = + override fun FlowContent.buildLink(address: String, content: FlowContent.() -> Unit) { a(href = address, block = content) + } override fun FlowContent.buildDRILink( node: ContentDRILink, pageContext: ContentPage, sourceSetRestriction: Set? - ) = locationProvider.resolve(node.address, node.sourceSets, pageContext)?.let { address -> - buildLink(address) { - buildText(node.children, pageContext, sourceSetRestriction) - } - } ?: if (isPartial) { - templateCommand(ResolveLinkCommand(node.address)) { - buildText(node.children, pageContext, sourceSetRestriction) - } - } else { - span { - attributes["data-unresolved-link"] = node.address.toString().htmlEscape() - buildText(node.children, pageContext, sourceSetRestriction) + ) { + locationProvider.resolve(node.address, node.sourceSets, pageContext)?.let { address -> + buildLink(address) { + buildText(node.children, pageContext, sourceSetRestriction) + } + } ?: if (isPartial) { + templateCommand(ResolveLinkCommand(node.address)) { + buildText(node.children, pageContext, sourceSetRestriction) + } + } else { + span { + attributes["data-unresolved-link"] = node.address.toString().htmlEscape() + buildText(node.children, pageContext, sourceSetRestriction) + } } } @@ -830,7 +845,9 @@ open class HtmlRenderer( } } - override fun FlowContent.buildText(textNode: ContentText) = buildText(textNode, textNode.style) + override fun FlowContent.buildText(textNode: ContentText) { + buildText(textNode, textNode.style) + } private fun FlowContent.buildText(textNode: ContentText, unappliedStyles: Set