From 2bfb7733dfef8da0271a01a7275ea42ecb69d93a Mon Sep 17 00:00:00 2001 From: Paweł Marks Date: Mon, 17 Feb 2020 10:55:44 +0100 Subject: Cleans up page mergers and moves them to base plugin --- core/src/main/kotlin/CoreExtensions.kt | 2 -- .../main/kotlin/plugability/DefaultExtensions.kt | 4 --- core/src/main/kotlin/plugability/DokkaContext.kt | 3 ++ core/src/main/kotlin/plugability/DokkaPlugin.kt | 6 +++- .../pages/DefaultPageMergerStrategy.kt | 11 ------- .../transformers/pages/DefaultPageNodeMerger.kt | 23 -------------- .../transformers/pages/PageMergerStrategy.kt | 9 ------ .../pages/SameMethodNamePageMergerStrategy.kt | 33 -------------------- plugins/base/src/main/kotlin/DokkaBase.kt | 22 +++++++++++++- .../pages/merger/FallbackPageMergerStrategy.kt | 12 ++++++++ .../pages/merger/PageMergerStrategy.kt | 9 ++++++ .../transformers/pages/merger/PageNodeMerger.kt | 29 ++++++++++++++++++ .../merger/SameMethodNamePageMergerStrategy.kt | 35 ++++++++++++++++++++++ .../test/kotlin/pageMerger/PageNodeMergerTest.kt | 16 +++++----- 14 files changed, 123 insertions(+), 91 deletions(-) delete mode 100644 core/src/main/kotlin/transformers/pages/DefaultPageMergerStrategy.kt delete mode 100644 core/src/main/kotlin/transformers/pages/DefaultPageNodeMerger.kt delete mode 100644 core/src/main/kotlin/transformers/pages/PageMergerStrategy.kt delete mode 100644 core/src/main/kotlin/transformers/pages/SameMethodNamePageMergerStrategy.kt create mode 100644 plugins/base/src/main/kotlin/transformers/pages/merger/FallbackPageMergerStrategy.kt create mode 100644 plugins/base/src/main/kotlin/transformers/pages/merger/PageMergerStrategy.kt create mode 100644 plugins/base/src/main/kotlin/transformers/pages/merger/PageNodeMerger.kt create mode 100644 plugins/base/src/main/kotlin/transformers/pages/merger/SameMethodNamePageMergerStrategy.kt diff --git a/core/src/main/kotlin/CoreExtensions.kt b/core/src/main/kotlin/CoreExtensions.kt index 2d705c1b..0f88b492 100644 --- a/core/src/main/kotlin/CoreExtensions.kt +++ b/core/src/main/kotlin/CoreExtensions.kt @@ -9,7 +9,6 @@ import org.jetbrains.dokka.transformers.descriptors.DescriptorToDocumentationTra import org.jetbrains.dokka.transformers.documentation.DocumentableMerger import org.jetbrains.dokka.transformers.documentation.DocumentationNodeTransformer import org.jetbrains.dokka.transformers.documentation.DocumentablesToPageTranslator -import org.jetbrains.dokka.transformers.pages.PageMergerStrategy import org.jetbrains.dokka.transformers.pages.PageNodeTransformer import org.jetbrains.dokka.transformers.psi.PsiToDocumentationTranslator import kotlin.reflect.KProperty @@ -31,7 +30,6 @@ object CoreExtensions { val commentsToContentConverter by coreExtension() val locationProviderFactory by coreExtension() val outputWriter by coreExtension() - val pageMergerStrategy by coreExtension() private fun coreExtension() = object { operator fun provideDelegate(thisRef: CoreExtensions, property: KProperty<*>): Lazy> = diff --git a/core/src/main/kotlin/plugability/DefaultExtensions.kt b/core/src/main/kotlin/plugability/DefaultExtensions.kt index 828d1bf1..1a367d30 100644 --- a/core/src/main/kotlin/plugability/DefaultExtensions.kt +++ b/core/src/main/kotlin/plugability/DefaultExtensions.kt @@ -5,8 +5,6 @@ import org.jetbrains.dokka.pages.DocTagToContentConverter import org.jetbrains.dokka.renderers.FileWriter import org.jetbrains.dokka.renderers.OutputWriter import org.jetbrains.dokka.resolvers.DefaultLocationProviderFactory -import org.jetbrains.dokka.transformers.pages.DefaultPageMergerStrategy -import org.jetbrains.dokka.transformers.pages.DefaultPageNodeMerger internal object DefaultExtensions { @@ -18,10 +16,8 @@ internal object DefaultExtensions { internal fun > get(point: E, fullContext: DokkaContext): List = when (point) { CoreExtensions.commentsToContentConverter -> converter.get(fullContext) - CoreExtensions.pageTransformer -> DefaultPageNodeMerger(fullContext) CoreExtensions.locationProviderFactory -> providerFactory.get(fullContext) CoreExtensions.outputWriter -> outputWriter.get(fullContext) - CoreExtensions.pageMergerStrategy -> DefaultPageMergerStrategy(fullContext.logger) else -> null }.let { listOfNotNull( it ) as List } } \ No newline at end of file diff --git a/core/src/main/kotlin/plugability/DokkaContext.kt b/core/src/main/kotlin/plugability/DokkaContext.kt index b4be5862..bcf6e1e0 100644 --- a/core/src/main/kotlin/plugability/DokkaContext.kt +++ b/core/src/main/kotlin/plugability/DokkaContext.kt @@ -43,6 +43,9 @@ interface DokkaContext { } } +inline fun DokkaContext.plugin(): T = plugin(T::class) + ?: throw java.lang.IllegalStateException("Plugin ${T::class.qualifiedName} is not present in context.") + interface DokkaContextConfiguration { fun addExtensionDependencies(extension: Extension<*>) } diff --git a/core/src/main/kotlin/plugability/DokkaPlugin.kt b/core/src/main/kotlin/plugability/DokkaPlugin.kt index cdc92ca5..c00b0af3 100644 --- a/core/src/main/kotlin/plugability/DokkaPlugin.kt +++ b/core/src/main/kotlin/plugability/DokkaPlugin.kt @@ -48,4 +48,8 @@ abstract class DokkaPlugin { .map { it.get(this) } .forEach { if (it.condition.invoke(configuration)) ctx.addExtensionDependencies(it) } } -} \ No newline at end of file +} + +inline fun P.query(extension: P.() -> ExtensionPoint): List = + context?.let { it[extension()] } + ?: throw IllegalStateException("Querying about plugins is only possible with dokka context initialised") \ No newline at end of file diff --git a/core/src/main/kotlin/transformers/pages/DefaultPageMergerStrategy.kt b/core/src/main/kotlin/transformers/pages/DefaultPageMergerStrategy.kt deleted file mode 100644 index 66562d8b..00000000 --- a/core/src/main/kotlin/transformers/pages/DefaultPageMergerStrategy.kt +++ /dev/null @@ -1,11 +0,0 @@ -package org.jetbrains.dokka.transformers.pages - -import org.jetbrains.dokka.pages.PageNode -import org.jetbrains.dokka.utilities.DokkaLogger - -class DefaultPageMergerStrategy(val logger: DokkaLogger) : PageMergerStrategy { - override fun tryMerge(pages: List): List { - if (pages.size != 1) logger.warn("Expected 1 page, but got ${pages.size}") - return listOf(pages.first()) - } -} \ No newline at end of file diff --git a/core/src/main/kotlin/transformers/pages/DefaultPageNodeMerger.kt b/core/src/main/kotlin/transformers/pages/DefaultPageNodeMerger.kt deleted file mode 100644 index bdfe393e..00000000 --- a/core/src/main/kotlin/transformers/pages/DefaultPageNodeMerger.kt +++ /dev/null @@ -1,23 +0,0 @@ -package org.jetbrains.dokka.transformers.pages - -import org.jetbrains.dokka.CoreExtensions -import org.jetbrains.dokka.pages.PageNode -import org.jetbrains.dokka.pages.RootPageNode -import org.jetbrains.dokka.plugability.DokkaContext - -class DefaultPageNodeMerger(val context: DokkaContext) : PageNodeTransformer { - override fun invoke(input: RootPageNode): RootPageNode = - input.modified(children = input.children.map { it.mergeChildren() }) - - fun PageNode.mergeChildren(): PageNode = children.groupBy { it.name } - .map { (_, v) -> v.mergePageNodes() } - .let { pages -> modified(children = pages.map { it.first().mergeChildren() }) } - - private fun List.mergePageNodes(): List = - context[CoreExtensions.pageMergerStrategy].fold(this) { pages, strategy -> tryMerge(strategy, pages) } - - private fun tryMerge(strategy: PageMergerStrategy, pages: List) = if (pages.size > 1) - strategy.tryMerge(pages) - else - pages -} \ No newline at end of file diff --git a/core/src/main/kotlin/transformers/pages/PageMergerStrategy.kt b/core/src/main/kotlin/transformers/pages/PageMergerStrategy.kt deleted file mode 100644 index 8eb526b3..00000000 --- a/core/src/main/kotlin/transformers/pages/PageMergerStrategy.kt +++ /dev/null @@ -1,9 +0,0 @@ -package org.jetbrains.dokka.transformers.pages - -import org.jetbrains.dokka.pages.PageNode - -interface PageMergerStrategy { - - fun tryMerge(pages: List): List - -} \ No newline at end of file diff --git a/core/src/main/kotlin/transformers/pages/SameMethodNamePageMergerStrategy.kt b/core/src/main/kotlin/transformers/pages/SameMethodNamePageMergerStrategy.kt deleted file mode 100644 index 3835506b..00000000 --- a/core/src/main/kotlin/transformers/pages/SameMethodNamePageMergerStrategy.kt +++ /dev/null @@ -1,33 +0,0 @@ -package org.jetbrains.dokka.transformers.pages - -import org.jetbrains.dokka.pages.* - -object SameMethodNamePageMergerStrategy : PageMergerStrategy { - override fun tryMerge(pages: List): List { - val name = pages.first().name - val members = pages.filterIsInstance() - val others = pages.filterNot { it is MemberPageNode } - - val resChildren = members.flatMap { it.children }.distinct() - val dri = members.flatMap { it.dri }.toSet() - val dci = DCI( - dri = dri, - kind = members.first().content.dci.kind - ) - - val merged = MemberPageNode( - dri = dri, - name = name, - children = resChildren, - content = asGroup(dci, members.map { it.content }), - documentable = null - ) - - return others + listOf(merged) - } - - fun asGroup(dci: DCI, nodes: List): ContentGroup { - val n = nodes.first() - return ContentGroup(nodes, dci, n.platforms, n.style, n.extras) - } -} \ No newline at end of file diff --git a/plugins/base/src/main/kotlin/DokkaBase.kt b/plugins/base/src/main/kotlin/DokkaBase.kt index bafd30ff..ed23d77e 100644 --- a/plugins/base/src/main/kotlin/DokkaBase.kt +++ b/plugins/base/src/main/kotlin/DokkaBase.kt @@ -4,11 +4,17 @@ import org.jetbrains.dokka.CoreExtensions import org.jetbrains.dokka.base.transformers.descriptors.DefaultDescriptorToDocumentationTranslator import org.jetbrains.dokka.base.transformers.documentables.DefaultDocumentableMerger import org.jetbrains.dokka.base.transformers.documentables.DefaultDocumentablesToPageTranslator +import org.jetbrains.dokka.base.transformers.pages.merger.FallbackPageMergerStrategy +import org.jetbrains.dokka.base.transformers.pages.merger.PageMergerStrategy +import org.jetbrains.dokka.base.transformers.pages.merger.PageNodeMerger +import org.jetbrains.dokka.base.transformers.pages.merger.SameMethodNamePageMergerStrategy import org.jetbrains.dokka.base.transformers.psi.DefaultPsiToDocumentationTranslator import org.jetbrains.dokka.plugability.DokkaPlugin import org.jetbrains.dokka.renderers.html.HtmlRenderer class DokkaBase: DokkaPlugin() { + val pageMergerStrategy by extensionPoint() + val descriptorToDocumentationTranslator by extending(isFallback = true) { CoreExtensions.descriptorToDocumentationTranslator providing ::DefaultDescriptorToDocumentationTranslator } @@ -25,7 +31,21 @@ class DokkaBase: DokkaPlugin() { CoreExtensions.documentablesToPageTranslator with DefaultDocumentablesToPageTranslator } + val pageMerger by extending { + CoreExtensions.pageTransformer providing { ctx -> PageNodeMerger(ctx[pageMergerStrategy]) } + } + + val fallbackMerger by extending { + pageMergerStrategy providing { ctx -> FallbackPageMergerStrategy(ctx.logger) } + } + + val sameMethodNameMerger by extending { + pageMergerStrategy with SameMethodNamePageMergerStrategy order { + before(fallbackMerger) + } + } + val htmlRenderer by extending { - CoreExtensions.renderer providing ::HtmlRenderer + CoreExtensions.renderer providing ::HtmlRenderer applyIf { format == "html" } } } \ No newline at end of file diff --git a/plugins/base/src/main/kotlin/transformers/pages/merger/FallbackPageMergerStrategy.kt b/plugins/base/src/main/kotlin/transformers/pages/merger/FallbackPageMergerStrategy.kt new file mode 100644 index 00000000..df0c27ee --- /dev/null +++ b/plugins/base/src/main/kotlin/transformers/pages/merger/FallbackPageMergerStrategy.kt @@ -0,0 +1,12 @@ +package org.jetbrains.dokka.base.transformers.pages.merger + +import org.jetbrains.dokka.pages.PageNode +import org.jetbrains.dokka.utilities.DokkaLogger + +class FallbackPageMergerStrategy(private val logger: DokkaLogger) : PageMergerStrategy { + override fun tryMerge(pages: List, path: List): List { + val renderedPath = path.joinToString(separator = "/") + if (pages.size != 1) logger.warn("For $renderedPath: expected 1 page, but got ${pages.size}") + return listOf(pages.first()) + } +} \ No newline at end of file diff --git a/plugins/base/src/main/kotlin/transformers/pages/merger/PageMergerStrategy.kt b/plugins/base/src/main/kotlin/transformers/pages/merger/PageMergerStrategy.kt new file mode 100644 index 00000000..b73b17e0 --- /dev/null +++ b/plugins/base/src/main/kotlin/transformers/pages/merger/PageMergerStrategy.kt @@ -0,0 +1,9 @@ +package org.jetbrains.dokka.base.transformers.pages.merger + +import org.jetbrains.dokka.pages.PageNode + +interface PageMergerStrategy { + + fun tryMerge(pages: List, path: List): List + +} \ No newline at end of file diff --git a/plugins/base/src/main/kotlin/transformers/pages/merger/PageNodeMerger.kt b/plugins/base/src/main/kotlin/transformers/pages/merger/PageNodeMerger.kt new file mode 100644 index 00000000..5ecf8d9b --- /dev/null +++ b/plugins/base/src/main/kotlin/transformers/pages/merger/PageNodeMerger.kt @@ -0,0 +1,29 @@ +package org.jetbrains.dokka.base.transformers.pages.merger + +import org.jetbrains.dokka.pages.PageNode +import org.jetbrains.dokka.pages.RootPageNode +import org.jetbrains.dokka.transformers.pages.PageNodeTransformer + +class PageNodeMerger(private val strategies: Iterable) : PageNodeTransformer { + override fun invoke(input: RootPageNode): RootPageNode = + input.modified(children = input.children.map { it.mergeChildren(emptyList()) }) + + private fun PageNode.mergeChildren(path: List): PageNode = children.groupBy { it.name } + .map { (n, v) -> mergePageNodes(v, path + n) } + .let { pages -> + modified(children = pages.map { it.assertSingle(path) }.map { it.mergeChildren(path + it.name) }) + } + + private fun mergePageNodes(pages: List, path: List): List = + strategies.fold(pages) { acc, strategy -> tryMerge(strategy, acc, path) } + + private fun tryMerge(strategy: PageMergerStrategy, pages: List, path: List) = + if (pages.size > 1) strategy.tryMerge(pages, path) else pages +} + +private fun Iterable.assertSingle(path: List): T = try { + single() + } catch (e: Exception) { + val renderedPath = path.joinToString(separator = "/") + throw IllegalStateException("Page merger is missconfigured. Error for $renderedPath: ${e.message}") + } \ No newline at end of file diff --git a/plugins/base/src/main/kotlin/transformers/pages/merger/SameMethodNamePageMergerStrategy.kt b/plugins/base/src/main/kotlin/transformers/pages/merger/SameMethodNamePageMergerStrategy.kt new file mode 100644 index 00000000..fef55dd2 --- /dev/null +++ b/plugins/base/src/main/kotlin/transformers/pages/merger/SameMethodNamePageMergerStrategy.kt @@ -0,0 +1,35 @@ +package org.jetbrains.dokka.base.transformers.pages.merger + +import org.jetbrains.dokka.pages.* + +object SameMethodNamePageMergerStrategy : PageMergerStrategy { + override fun tryMerge(pages: List, path: List): List { + val name = pages.first().name + val members = pages.filterIsInstance() + val others = pages.filterNot { it is MemberPageNode } + + val resChildren = members.flatMap { it.children }.distinct() + val dri = members.flatMap { it.dri }.toSet() + val dci = DCI( + dri = dri, + kind = members.first().content.dci.kind + ) + + val merged = MemberPageNode( + dri = dri, + name = name, + children = resChildren, + content = asGroup( + dci, + members.map { it.content }), + documentable = null + ) + + return others + listOf(merged) + } + + fun asGroup(dci: DCI, nodes: List): ContentGroup { + val n = nodes.first() + return ContentGroup(nodes, dci, n.platforms, n.style, n.extras) + } +} \ No newline at end of file diff --git a/plugins/base/src/test/kotlin/pageMerger/PageNodeMergerTest.kt b/plugins/base/src/test/kotlin/pageMerger/PageNodeMergerTest.kt index 88e57ddb..c6076d54 100644 --- a/plugins/base/src/test/kotlin/pageMerger/PageNodeMergerTest.kt +++ b/plugins/base/src/test/kotlin/pageMerger/PageNodeMergerTest.kt @@ -4,15 +4,15 @@ import org.jetbrains.dokka.CoreExtensions import org.jetbrains.dokka.pages.ContentPage import org.jetbrains.dokka.pages.PageNode import org.jetbrains.dokka.plugability.DokkaPlugin -import org.jetbrains.dokka.transformers.pages.DefaultPageMergerStrategy -import org.jetbrains.dokka.transformers.pages.SameMethodNamePageMergerStrategy +import org.jetbrains.dokka.base.transformers.pages.merger.SameMethodNamePageMergerStrategy import org.jetbrains.dokka.utilities.DokkaLogger +import org.junit.Ignore import org.junit.Test import testApi.testRunner.AbstractCoreTest class PageNodeMergerTest : AbstractCoreTest() { - object SameNameStrategy : DokkaPlugin() { + /* object SameNameStrategy : DokkaPlugin() { val strategy by extending { CoreExtensions.pageMergerStrategy with SameMethodNamePageMergerStrategy } } @@ -36,6 +36,7 @@ class PageNodeMergerTest : AbstractCoreTest() { override fun report() = TODO() } + */ @Test fun sameNameStrategyTest() { @@ -61,8 +62,8 @@ class PageNodeMergerTest : AbstractCoreTest() { | fun test(str: String): String = str |} """.trimMargin(), - configuration, - pluginOverrides = listOf(SameNameStrategy) + configuration/*, + pluginOverrides = listOf(SameNameStrategy)*/ ) { pagesTransformationStage = { val allChildren = it.childrenRec().filterIsInstance() @@ -78,6 +79,7 @@ class PageNodeMergerTest : AbstractCoreTest() { } } + @Ignore("TODO: reenable when we have infrastructure for turning off extensions") @Test fun defaultStrategyTest() { val strList: MutableList = mutableListOf() @@ -103,8 +105,8 @@ class PageNodeMergerTest : AbstractCoreTest() { | fun test(str: String): String = str |} """.trimMargin(), - configuration, - pluginOverrides = listOf(DefaultStrategy(strList)) + configuration/*, + pluginOverrides = listOf(DefaultStrategy(strList)) */ ) { pagesTransformationStage = { root -> val allChildren = root.childrenRec().filterIsInstance() -- cgit