diff options
author | Kamil Doległo <kamilok1965@interia.pl> | 2020-05-05 11:53:16 +0200 |
---|---|---|
committer | Paweł Marks <Kordyjan@users.noreply.github.com> | 2020-05-19 09:56:32 +0200 |
commit | 430d7d6453a0b63dcabecd54aea915410cd35103 (patch) | |
tree | b9e40e3eaa9f1948590141d7d46491e2f34f2ef9 /plugins/base/src/main/kotlin | |
parent | c1b4669ee227a479516f37ce1b9dff5f2d2bef38 (diff) | |
download | dokka-430d7d6453a0b63dcabecd54aea915410cd35103.tar.gz dokka-430d7d6453a0b63dcabecd54aea915410cd35103.tar.bz2 dokka-430d7d6453a0b63dcabecd54aea915410cd35103.zip |
Add a draft version of divergent rendering
Diffstat (limited to 'plugins/base/src/main/kotlin')
8 files changed, 319 insertions, 85 deletions
diff --git a/plugins/base/src/main/kotlin/DokkaBase.kt b/plugins/base/src/main/kotlin/DokkaBase.kt index ab7d089d..5368207e 100644 --- a/plugins/base/src/main/kotlin/DokkaBase.kt +++ b/plugins/base/src/main/kotlin/DokkaBase.kt @@ -27,6 +27,7 @@ import org.jetbrains.dokka.base.translators.descriptors.DefaultDescriptorToDocum import org.jetbrains.dokka.base.translators.documentables.DefaultDocumentableToPageTranslator import org.jetbrains.dokka.base.translators.documentables.PageContentBuilder import org.jetbrains.dokka.base.translators.psi.DefaultPsiToDocumentableTranslator +import org.jetbrains.dokka.pages.ContentDivergentGroup import org.jetbrains.dokka.plugability.DokkaPlugin import org.jetbrains.dokka.transformers.pages.PageTransformer import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor diff --git a/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt b/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt index 1340529c..e229f3a6 100644 --- a/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt +++ b/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt @@ -1,6 +1,7 @@ package org.jetbrains.dokka.base.renderers import kotlinx.coroutines.* +import kotlinx.html.FlowContent import org.jetbrains.dokka.base.DokkaBase import org.jetbrains.dokka.base.resolvers.local.LocationProvider import org.jetbrains.dokka.model.SourceSetData @@ -27,7 +28,7 @@ abstract class DefaultRenderer<T>( abstract fun T.buildList( node: ContentList, pageContext: ContentPage, - platformRestriction: SourceSetData? = null + platformRestriction: Set<SourceSetData>? = null ) abstract fun T.buildNewLine() @@ -35,7 +36,7 @@ abstract class DefaultRenderer<T>( abstract fun T.buildTable( node: ContentTable, pageContext: ContentPage, - platformRestriction: SourceSetData? = null + platformRestriction: Set<SourceSetData>? = null ) abstract fun T.buildText(textNode: ContentText) @@ -50,17 +51,20 @@ abstract class DefaultRenderer<T>( open fun T.buildGroup( node: ContentGroup, pageContext: ContentPage, - platformRestriction: SourceSetData? = null + platformRestriction: Set<SourceSetData>? = null ) = wrapGroup(node, pageContext) { node.children.forEach { it.build(this, pageContext, platformRestriction) } } + 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) = childrenCallback() open fun T.buildLinkText( nodes: List<ContentNode>, pageContext: ContentPage, - platformRestriction: SourceSetData? = null + platformRestriction: Set<SourceSetData>? = null ) { nodes.forEach { it.build(this, pageContext, platformRestriction) } } @@ -72,7 +76,7 @@ abstract class DefaultRenderer<T>( open fun T.buildHeader( node: ContentHeader, pageContext: ContentPage, - platformRestriction: SourceSetData? = null + platformRestriction: Set<SourceSetData>? = null ) { buildHeader(node.level) { node.children.forEach { it.build(this, pageContext, platformRestriction) } } } @@ -80,16 +84,16 @@ abstract class DefaultRenderer<T>( open fun ContentNode.build( builder: T, pageContext: ContentPage, - platformRestriction: SourceSetData? = null + platformRestriction: Set<SourceSetData>? = null ) = builder.buildContentNode(this, pageContext, platformRestriction) open fun T.buildContentNode( node: ContentNode, pageContext: ContentPage, - platformRestriction: SourceSetData? = null + platformRestriction: Set<SourceSetData>? = null ) { - if (platformRestriction == null || platformRestriction in node.sourceSets) { + if (platformRestriction == null || node.sourceSets.any { it in platformRestriction } ) { when (node) { is ContentText -> buildText(node) is ContentHeader -> buildHeader(node, pageContext, platformRestriction) @@ -107,6 +111,7 @@ abstract class DefaultRenderer<T>( is ContentGroup -> buildGroup(node, pageContext, platformRestriction) is ContentBreakLine -> buildNewLine() is PlatformHintedContent -> buildPlatformDependent(node, pageContext) + is ContentDivergentGroup -> buildDivergent(node, pageContext) else -> buildError(node) } } diff --git a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt index caabcda7..97f0bdbd 100644 --- a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt +++ b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt @@ -40,14 +40,40 @@ open class HtmlRenderer( } } - override fun FlowContent.buildPlatformDependent(content: PlatformHintedContent, pageContext: ContentPage) { + private fun FlowContent.wrapPlatformTagged( + node: ContentGroup, + pageContext: ContentPage, + childrenCallback: FlowContent.() -> Unit + ) { + div("platform-tagged") { + node.sourceSets.forEach { + div("platform-tag") { + if (it.sourceSetName.equals("common", ignoreCase = true)) classes = classes + "common" + text(it.sourceSetName) + } + } + div("content") { + childrenCallback() + } + } + } + + override fun FlowContent.buildPlatformDependent(content: PlatformHintedContent, pageContext: ContentPage) = + buildPlatformDependent(content.sourceSets.map { it to setOf(content.inner) }.toMap(), pageContext) + + private fun FlowContent.buildPlatformDependent( + nodes: Map<SourceSetData, Collection<ContentNode>>, + pageContext: ContentPage + ) { div("platform-hinted") { attributes["data-platform-hinted"] = "data-platform-hinted" - val contents = content.sourceSets.mapIndexed { index, platform -> - platform to createHTML(prettyPrint = false).div(classes = "content") { + val contents = nodes.toList().mapIndexed { index, (sourceSet, elements) -> + sourceSet to createHTML(prettyPrint = false).div(classes = "content") { if (index == 0) attributes["data-active"] = "" - attributes["data-togglable"] = platform.sourceSetName - buildContentNode(content.inner, pageContext, platform) + attributes["data-togglable"] = sourceSet.sourceSetName + elements.forEach { + buildContentNode(it, pageContext, setOf(sourceSet)) + } } } @@ -69,17 +95,61 @@ open class HtmlRenderer( } } + override fun FlowContent.buildDivergent(node: ContentDivergentGroup, pageContext: ContentPage) { + val distinct = + node.children.map { instance -> + instance to Pair( + createHTML(prettyPrint = false).div { + instance.before?.let { before -> + buildContentNode(before, pageContext, instance.sourceSets) + } + }.drop(5).dropLast(6), + createHTML(prettyPrint = false).div { + instance.after?.let { after -> + buildContentNode(after, pageContext, instance.sourceSets) + } + }.drop(5).dropLast(6) // TODO: Find a way to do it without arbitrary trims + ) + + }.groupBy( + Pair<ContentDivergentInstance, Pair<String, String>>::second, + Pair<ContentDivergentInstance, Pair<String, String>>::first + ) + + distinct.forEach { + consumer.onTagContentUnsafe { +it.key.first } + consumer.onTagContentUnsafe { + +createHTML(prettyPrint = false).div { + if (node.implicitlySourceSetHinted) { + buildPlatformDependent( + it.value.groupBy { it.sourceSets } + .flatMap { (sourceSets, elements) -> + sourceSets.map { sourceSet -> sourceSet to elements.map { e -> e.divergent } } + }.toMap(), + pageContext + ) + } else { + it.value.forEach { + buildContentNode(it.divergent, pageContext, null) + } + } + }.drop(5).dropLast(6) + } + consumer.onTagContentUnsafe { +it.key.second } + } + } + override fun FlowContent.buildList( node: ContentList, pageContext: ContentPage, - sourceSetRestriction: SourceSetData? + sourceSetRestriction: Set<SourceSetData>? ) = if (node.ordered) ol { buildListItems(node.children, pageContext, sourceSetRestriction) } else ul { buildListItems(node.children, pageContext, sourceSetRestriction) } open fun OL.buildListItems( items: List<ContentNode>, pageContext: ContentPage, - sourceSetRestriction: SourceSetData? = null + sourceSetRestriction: Set<SourceSetData>? = null ) { items.forEach { if (it is ContentList) @@ -92,7 +162,7 @@ open class HtmlRenderer( open fun UL.buildListItems( items: List<ContentNode>, pageContext: ContentPage, - sourceSetRestriction: SourceSetData? = null + sourceSetRestriction: Set<SourceSetData>? = null ) { items.forEach { if (it is ContentList) @@ -119,18 +189,18 @@ open class HtmlRenderer( private fun FlowContent.buildRow( node: ContentGroup, pageContext: ContentPage, - sourceSetRestriction: SourceSetData? + sourceSetRestriction: Set<SourceSetData>? ) { node.children .filter { - sourceSetRestriction == null || sourceSetRestriction in it.sourceSets + sourceSetRestriction == null || it.sourceSets.any { s -> s in sourceSetRestriction } } .takeIf { it.isNotEmpty() } ?.let { div(classes = "table-row") { it.filter { it.dci.kind != ContentKind.Symbol }.takeIf { it.isNotEmpty() }?.let { div("main-subrow ${node.style.joinToString { it.toString().decapitalize() }}") { - it.filter { sourceSetRestriction == null || sourceSetRestriction in it.sourceSets } + it.filter { sourceSetRestriction == null || it.sourceSets.any { s -> s in sourceSetRestriction } } .forEach { when(it.dci.kind){ ContentKind.SourceSetDependantHint -> { @@ -170,6 +240,7 @@ open class HtmlRenderer( } } + private fun FlowContent.createPlatformTags(node: ContentNode) { div("platform-tags") { node.sourceSets.forEach { @@ -184,7 +255,7 @@ open class HtmlRenderer( override fun FlowContent.buildTable( node: ContentTable, pageContext: ContentPage, - sourceSetRestriction: SourceSetData? + sourceSetRestriction: Set<SourceSetData>? ) { div(classes = "table") { node.children.forEach { diff --git a/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt b/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt index 241103bf..3836f45d 100644 --- a/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt +++ b/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt @@ -169,7 +169,7 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog is OtherParameter -> text(p.name) is TypeConstructor -> if (p.function) - +funType(this.mainDRI, this.mainPlatformData, p) + +funType(mainDRI.single(), mainPlatformData, p) else group { link(p.dri.classNames.orEmpty(), p.dri) diff --git a/plugins/base/src/main/kotlin/transformers/pages/merger/SameMethodNamePageMergerStrategy.kt b/plugins/base/src/main/kotlin/transformers/pages/merger/SameMethodNamePageMergerStrategy.kt index 31e79555..77226310 100644 --- a/plugins/base/src/main/kotlin/transformers/pages/merger/SameMethodNamePageMergerStrategy.kt +++ b/plugins/base/src/main/kotlin/transformers/pages/merger/SameMethodNamePageMergerStrategy.kt @@ -4,34 +4,34 @@ import org.jetbrains.dokka.pages.* object SameMethodNamePageMergerStrategy : PageMergerStrategy { override fun tryMerge(pages: List<PageNode>, path: List<String>): List<PageNode> { - val name = pages.first().name - val members = pages.filterIsInstance<MemberPageNode>() - - if (members.isEmpty()) return pages - - val others = pages.filterNot { it is MemberPageNode } - - val resChildren = members.flatMap { it.children }.distinct() + val members = pages.filterIsInstance<MemberPageNode>().takeIf { it.isNotEmpty() } ?: return pages + val name = pages.first().name.also { + if (pages.any { page -> page.name != it }) { // Is this even possible? + println("Page names for $it do not match!") // TODO pass logger here somehow + } + } 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 }), + children = members.flatMap { it.children }.distinct(), + content = squashDivergentInstances(members), documentable = null ) - return others + listOf(merged) + return (pages - members) + listOf(merged) } - fun asGroup(dci: DCI, nodes: List<ContentNode>): ContentGroup = - nodes.first().let { ContentGroup(nodes, dci, it.sourceSets, it.style, it.extra) } - + private fun squashDivergentInstances(nodes: List<MemberPageNode>): ContentNode = + nodes.map { it.content } + .reduce { acc, node -> + acc.mapTransform<ContentDivergentGroup, ContentNode> { g -> + g.copy(children = (g.children + + (node.dfs { it is ContentDivergentGroup && it.groupID == g.groupID } as? ContentDivergentGroup) + ?.children?.single() + ).filterNotNull() + ) + } + } }
\ No newline at end of file diff --git a/plugins/base/src/main/kotlin/transformers/pages/sourcelinks/SourceLinksTransformer.kt b/plugins/base/src/main/kotlin/transformers/pages/sourcelinks/SourceLinksTransformer.kt index 876326d1..c7b65aa9 100644 --- a/plugins/base/src/main/kotlin/transformers/pages/sourcelinks/SourceLinksTransformer.kt +++ b/plugins/base/src/main/kotlin/transformers/pages/sourcelinks/SourceLinksTransformer.kt @@ -64,7 +64,7 @@ class SourceLinksTransformer(val context: DokkaContext, val builder: PageContent +ContentTable( emptyList(), sources.map { - buildGroup(node.dri.first(), setOf(it.first)) { + buildGroup(node.dri, setOf(it.first)) { +link("(source)", it.second) } }, diff --git a/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt b/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt index 232f6721..51e95160 100644 --- a/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt +++ b/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt @@ -95,20 +95,8 @@ open class DefaultPageCreator( dri: DRI, sourceSets: List<SourceSetData> ) = contentBuilder.contentFor(s as Documentable) { - block("Types", 2, ContentKind.Classlikes, s.classlikes, sourceSets.toSet()) { - link(it.name ?: "", it.dri, kind = ContentKind.Main) - sourceSetDependentHint(it.dri, it.sourceSets.toSet(), kind = ContentKind.SourceSetDependantHint) { - +buildSignature(it) - contentForBrief(it) - } - } - block("Functions", 2, ContentKind.Functions, s.functions, sourceSets.toSet()) { - link(it.name, it.dri, kind = ContentKind.Main) - sourceSetDependentHint(it.dri, it.sourceSets.toSet(), kind = ContentKind.SourceSetDependantHint) { - +buildSignature(it) - contentForBrief(it) - } - } + divergentBlock("Types", s.classlikes, ContentKind.Classlikes) + divergentBlock("Functions", s.functions, ContentKind.Functions) block("Properties", 2, ContentKind.Properties, s.properties, sourceSets.toSet()) { link(it.name, it.dri, kind = ContentKind.Main) sourceSetDependentHint(it.dri, it.sourceSets.toSet(), kind = ContentKind.SourceSetDependantHint) { @@ -125,7 +113,7 @@ open class DefaultPageCreator( emptyList(), map.entries.flatMap { entry -> entry.value.map { Pair(entry.key, it) } } .groupBy({ it.second }, { it.first }).map { (classlike, platforms) -> - buildGroup(dri, platforms.toSet(), ContentKind.Inheritors) { + buildGroup(setOf(dri), platforms.toSet(), ContentKind.Inheritors) { link( classlike.classNames?.substringBeforeLast(".") ?: classlike.toString() .also { logger.warn("No class name found for DRI $classlike") }, classlike @@ -219,6 +207,7 @@ open class DefaultPageCreator( } } } + } } @@ -334,23 +323,59 @@ open class DefaultPageCreator( } } - protected open fun contentForFunction(f: DFunction) = contentBuilder.contentFor(f) { - group(kind = ContentKind.Cover) { - header(1) { text(f.name) } - sourceSetDependentHint(f.dri, f.sourceSets.toSet()) { - +buildSignature(f) + protected open fun contentForFunction(f: DFunction) = contentForMember(f) + protected open fun contentForTypeAlias(t: DTypeAlias) = contentForMember(t) + protected open fun contentForMember(d: Documentable) = contentBuilder.contentFor(d) { + header(1) { text(d.name.orEmpty()) } + divergentGroup(ContentDivergentGroup.GroupID("member")) { + instance(setOf(d.dri), d.sourceSets.toSet()) { + divergent(kind = ContentKind.Symbol) { + +buildSignature(d) + } + after { + +contentForComments(d) + } } } - +contentForComments(f) } - protected open fun contentForTypeAlias(t: DTypeAlias) = contentBuilder.contentFor(t) { - group(kind = ContentKind.Cover) { - header(1) { text(t.name) } - +buildSignature(t) + protected open fun DocumentableContentBuilder.divergentBlock( + name: String, + collection: Collection<Documentable>, + kind: ContentKind + ) { + if (collection.any()) { + header(2) { text(name) } + table(kind) { + collection.groupBy { it.name }.map { (elementName, elements) -> // This groupBy should probably use LocationProvider + buildGroup(elements.map { it.dri }.toSet(), elements.flatMap { it.sourceSets }.toSet()) { + link(elementName.orEmpty(), elements.first().dri) + divergentGroup( + ContentDivergentGroup.GroupID(name), + elements.map { it.dri }.toSet(), + kind = ContentKind.Symbol + ) { + elements.map { + instance(setOf(it.dri), it.sourceSets.toSet()) { + divergent { + group(kind = ContentKind.Symbol) { + +buildSignature(it) + } + } + after { + group(kind = ContentKind.BriefComment) { + contentForBrief(it) + } + } + } + } + } + } + } + } } - +contentForComments(t) } + protected open fun TagWrapper.toHeaderString() = this.javaClass.toGenericString().split('.').last() } diff --git a/plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt b/plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt index 3ed19afa..2f04e2a0 100644 --- a/plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt +++ b/plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt @@ -25,6 +25,18 @@ open class PageContentBuilder( extra: PropertyContainer<ContentNode> = PropertyContainer.empty(), block: DocumentableContentBuilder.() -> Unit ): ContentGroup = + DocumentableContentBuilder(setOf(dri), sourceSets, styles, extra) + .apply(block) + .build(sourceSets, kind, styles, extra) + + fun contentFor( + dri: Set<DRI>, + sourceSets: Set<SourceSetData>, + kind: Kind = ContentKind.Main, + styles: Set<Style> = emptySet(), + extra: PropertyContainer<ContentNode> = PropertyContainer.empty(), + block: DocumentableContentBuilder.() -> Unit + ): ContentGroup = DocumentableContentBuilder(dri, sourceSets, styles, extra) .apply(block) .build(sourceSets, kind, styles, extra) @@ -37,13 +49,13 @@ open class PageContentBuilder( sourceSets: Set<SourceSetData> = d.sourceSets.toSet(), block: DocumentableContentBuilder.() -> Unit = {} ): ContentGroup = - DocumentableContentBuilder(d.dri, sourceSets, styles, extra) + DocumentableContentBuilder(setOf(d.dri), sourceSets, styles, extra) .apply(block) .build(sourceSets, kind, styles, extra) @ContentBuilderMarker open inner class DocumentableContentBuilder( - val mainDRI: DRI, + val mainDRI: Set<DRI>, val mainPlatformData: Set<SourceSetData>, val mainStyles: Set<Style>, val mainExtra: PropertyContainer<ContentNode> @@ -57,7 +69,7 @@ open class PageContentBuilder( extra: PropertyContainer<ContentNode> ) = ContentGroup( contents.toList(), - DCI(setOf(mainDRI), kind), + DCI(mainDRI, kind), sourceSets, styles, extra @@ -111,13 +123,12 @@ open class PageContentBuilder( link(it.classNames ?: "", it) } }, - DCI(setOf(mainDRI), kind), + DCI(mainDRI, kind), sourceSets, styles, extra ) } fun table( - dri: DRI = mainDRI, kind: Kind = ContentKind.Main, sourceSets: Set<SourceSetData> = mainPlatformData, styles: Set<Style> = mainStyles, @@ -127,7 +138,7 @@ open class PageContentBuilder( contents += ContentTable( emptyList(), operation(), - DCI(setOf(mainDRI), kind), + DCI(mainDRI, kind), sourceSets, styles, extra ) } @@ -148,11 +159,11 @@ open class PageContentBuilder( contents += ContentTable( emptyList(), elements.map { - buildGroup(it.dri, it.sourceSets.toSet(), kind, styles, extra) { + buildGroup(setOf(it.dri), it.sourceSets.toSet(), kind, styles, extra) { operation(it) } }, - DCI(setOf(mainDRI), kind), + DCI(mainDRI, kind), sourceSets, styles, extra ) } @@ -188,7 +199,7 @@ open class PageContentBuilder( contents += ContentDRILink( listOf(createText(text, kind, sourceSets, styles, extra)), address, - DCI(setOf(mainDRI), kind), + DCI(mainDRI, kind), sourceSets ) } @@ -205,7 +216,7 @@ open class PageContentBuilder( children = listOf(createText(text, kind, sourceSets, styles, extra)), address = address, extra = PropertyContainer.empty(), - dci = DCI(setOf(mainDRI), kind), + dci = DCI(mainDRI, kind), sourceSets = sourceSets, style = emptySet() ) @@ -221,7 +232,7 @@ open class PageContentBuilder( contents += ContentDRILink( contentFor(mainDRI, sourceSets, kind, styles, extra, block).children, address, - DCI(setOf(mainDRI), kind), + DCI(mainDRI, kind), sourceSets ) } @@ -235,14 +246,14 @@ open class PageContentBuilder( ) { val content = commentsConverter.buildContent( docTag, - DCI(setOf(mainDRI), kind), + DCI(mainDRI, kind), sourceSets ) - contents += ContentGroup(content, DCI(setOf(mainDRI), kind), sourceSets, styles, extra) + contents += ContentGroup(content, DCI(mainDRI, kind), sourceSets, styles, extra) } fun group( - dri: DRI = mainDRI, + dri: Set<DRI> = mainDRI, sourceSets: Set<SourceSetData> = mainPlatformData, kind: Kind = ContentKind.Main, styles: Set<Style> = mainStyles, @@ -252,8 +263,23 @@ open class PageContentBuilder( contents += buildGroup(dri, sourceSets, kind, styles, extra, block) } + fun divergentGroup( + groupID: ContentDivergentGroup.GroupID, + dri: Set<DRI> = mainDRI, + kind: Kind = ContentKind.Main, + styles: Set<Style> = mainStyles, + extra: PropertyContainer<ContentNode> = mainExtra, + implicitlySourceSetHinted: Boolean = true, + block: DivergentBuilder.() -> Unit + ) { + contents += + DivergentBuilder(dri, kind, styles, extra) + .apply(block) + .build(groupID = groupID, implicitlySourceSetHinted = implicitlySourceSetHinted) + } + fun buildGroup( - dri: DRI = mainDRI, + dri: Set<DRI> = mainDRI, sourceSets: Set<SourceSetData> = mainPlatformData, kind: Kind = ContentKind.Main, styles: Set<Style> = mainStyles, @@ -262,7 +288,7 @@ open class PageContentBuilder( ): ContentGroup = contentFor(dri, sourceSets, kind, styles, extra, block) fun sourceSetDependentHint( - dri: DRI = mainDRI, + dri: Set<DRI> = mainDRI, sourceSets: Set<SourceSetData> = mainPlatformData, kind: Kind = ContentKind.Main, styles: Set<Style> = mainStyles, @@ -275,6 +301,20 @@ open class PageContentBuilder( ) } + fun sourceSetDependentHint( + dri: DRI, + platformData: Set<SourceSetData> = mainPlatformData, + kind: Kind = ContentKind.Main, + styles: Set<Style> = mainStyles, + extra: PropertyContainer<ContentNode> = mainExtra, + block: DocumentableContentBuilder.() -> Unit + ) { + contents += PlatformHintedContent( + buildGroup(setOf(dri), platformData, kind, styles, extra, block), + platformData + ) + } + protected fun createText( text: String, kind: Kind, @@ -282,7 +322,7 @@ open class PageContentBuilder( styles: Set<Style>, extra: PropertyContainer<ContentNode> ) = - ContentText(text, DCI(setOf(mainDRI), kind), sourceSets, styles, extra) + ContentText(text, DCI(mainDRI, kind), sourceSets, styles, extra) fun <T> platformText( value: SourceSetDependent<T>, @@ -292,4 +332,96 @@ open class PageContentBuilder( transform(v).takeIf { it.isNotBlank() }?.also { text(it, sourceSets = setOf(p)) } } } + + @ContentBuilderMarker + open inner class DivergentBuilder( + private val mainDRI: Set<DRI>, + private val mainKind: Kind, + private val mainStyles: Set<Style>, + private val mainExtra: PropertyContainer<ContentNode> + ) { + private val instances: MutableList<ContentDivergentInstance> = mutableListOf() + fun instance( + dri: Set<DRI>, + sourceSets: Set<SourceSetData>, // Having correct PlatformData is crucial here, that's why there's no default + kind: Kind = mainKind, + styles: Set<Style> = mainStyles, + extra: PropertyContainer<ContentNode> = mainExtra, + block: DivergentInstanceBuilder.() -> Unit + ) { + instances += DivergentInstanceBuilder(dri, sourceSets, styles, extra) + .apply(block) + .build(kind) + } + + fun build( + groupID: ContentDivergentGroup.GroupID, + implicitlySourceSetHinted: Boolean, + kind: Kind = mainKind, + styles: Set<Style> = mainStyles, + extra: PropertyContainer<ContentNode> = mainExtra + ) = ContentDivergentGroup(instances.toList(), DCI(mainDRI, kind), styles, extra, groupID, implicitlySourceSetHinted) + } + + @ContentBuilderMarker + open inner class DivergentInstanceBuilder( + private val mainDRI: Set<DRI>, + private val mainSourceSets: Set<SourceSetData>, + private val mainStyles: Set<Style>, + private val mainExtra: PropertyContainer<ContentNode> + ) { + private var before: ContentNode? = null + private var divergent: ContentNode? = null + private var after: ContentNode? = null + + fun before( + dri: Set<DRI> = mainDRI, + sourceSets: Set<SourceSetData> = mainSourceSets, + kind: Kind = ContentKind.Main, + styles: Set<Style> = mainStyles, + extra: PropertyContainer<ContentNode> = mainExtra, + block: DocumentableContentBuilder.() -> Unit + ) { + before = contentFor(dri, sourceSets, kind, styles, extra, block) + } + + fun divergent( + dri: Set<DRI> = mainDRI, + sourceSets: Set<SourceSetData> = mainSourceSets, + kind: Kind = ContentKind.Main, + styles: Set<Style> = mainStyles, + extra: PropertyContainer<ContentNode> = mainExtra, + block: DocumentableContentBuilder.() -> Unit + ) { + divergent = contentFor(dri, sourceSets, kind, styles, extra, block) + } + + fun after( + dri: Set<DRI> = mainDRI, + sourceSets: Set<SourceSetData> = mainSourceSets, + kind: Kind = ContentKind.Main, + styles: Set<Style> = mainStyles, + extra: PropertyContainer<ContentNode> = mainExtra, + block: DocumentableContentBuilder.() -> Unit + ) { + after = contentFor(dri, sourceSets, kind, styles, extra, block) + } + + + fun build( + kind: Kind, + sourceSets: Set<SourceSetData> = mainSourceSets, + styles: Set<Style> = mainStyles, + extra: PropertyContainer<ContentNode> = mainExtra + ) = + ContentDivergentInstance( + before, + divergent!!, + after, + DCI(mainDRI, kind), + sourceSets, + styles, + extra + ) + } }
\ No newline at end of file |