diff options
author | Kamil Doległo <9080183+kamildoleglo@users.noreply.github.com> | 2021-01-04 12:59:03 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-04 12:59:03 +0100 |
commit | d3f0e03284999e6f7fac99a345ed91cb63503706 (patch) | |
tree | 0becbb39444fbf7ee9300adc1fb6b04861ec54f6 /plugins/base/src | |
parent | 6b0cdf3102b1f1dd213ca0c2e2c333f8756be6b4 (diff) | |
download | dokka-d3f0e03284999e6f7fac99a345ed91cb63503706.tar.gz dokka-d3f0e03284999e6f7fac99a345ed91cb63503706.tar.bz2 dokka-d3f0e03284999e6f7fac99a345ed91cb63503706.zip |
Refactor ContentTable builder and fix GFM table rendering (#1682)
Diffstat (limited to 'plugins/base/src')
-rw-r--r-- | plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt | 130 | ||||
-rw-r--r-- | plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt | 97 |
2 files changed, 149 insertions, 78 deletions
diff --git a/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt b/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt index fd64b6be..55c2837c 100644 --- a/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt +++ b/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt @@ -33,7 +33,8 @@ open class DefaultPageCreator( ) { protected open val contentBuilder = PageContentBuilder(commentsToContentConverter, signatureProvider, logger) - protected val separateInheritedMembers = configuration?.separateInheritedMembers ?: DokkaBaseConfiguration.separateInheritedMembersDefault + protected val separateInheritedMembers = + configuration?.separateInheritedMembers ?: DokkaBaseConfiguration.separateInheritedMembersDefault open fun pageForModule(m: DModule) = ModulePageNode(m.name.ifEmpty { "<root>" }, contentForModule(m), m, m.packages.map(::pageForPackage)) @@ -41,7 +42,8 @@ open class DefaultPageCreator( open fun pageForPackage(p: DPackage): PackagePageNode = PackagePageNode( p.name, contentForPackage(p), setOf(p.dri), p, p.classlikes.renameClashingDocumentable().map(::pageForClasslike) + - p.functions.renameClashingDocumentable().map(::pageForFunction) + p.properties.mapNotNull(::pageForProperty) + p.functions.renameClashingDocumentable() + .map(::pageForFunction) + p.properties.mapNotNull(::pageForProperty) ) open fun pageForEnumEntry(e: DEnumEntry): ClasslikePageNode = @@ -66,31 +68,32 @@ open class DefaultPageCreator( ) } - private fun <T> T.toClashedName() where T: Documentable, T: WithExtraProperties<T> = + private fun <T> T.toClashedName() where T : Documentable, T : WithExtraProperties<T> = (extra[ClashingDriIdentifier]?.value?.joinToString(", ", "[", "]") { it.displayName } ?: "") + name.orEmpty() - private fun <T> List<T>.renameClashingDocumentable(): List<T> where T: Documentable = + private fun <T> List<T>.renameClashingDocumentable(): List<T> where T : Documentable = groupBy { it.dri }.values.flatMap { elements -> - if (elements.size == 1) elements else elements.mapNotNull { element -> - when(element) { - is DClass -> element.copy(extra = element.extra + DriClashAwareName(element.toClashedName())) - is DObject -> element.copy(extra = element.extra + DriClashAwareName(element.toClashedName()) ) - is DAnnotation -> element.copy(extra = element.extra + DriClashAwareName(element.toClashedName()) ) - is DInterface -> element.copy(extra = element.extra + DriClashAwareName(element.toClashedName()) ) - is DEnum -> element.copy(extra = element.extra + DriClashAwareName(element.toClashedName()) ) - is DFunction -> element.copy(extra = element.extra + DriClashAwareName(element.toClashedName()) ) - is DProperty -> element.copy(extra = element.extra + DriClashAwareName(element.toClashedName()) ) - is DTypeAlias -> element.copy(extra = element.extra + DriClashAwareName(element.toClashedName()) ) - else -> null - } as? T? + if (elements.size == 1) elements else elements.mapNotNull { element -> + when (element) { + is DClass -> element.copy(extra = element.extra + DriClashAwareName(element.toClashedName())) + is DObject -> element.copy(extra = element.extra + DriClashAwareName(element.toClashedName())) + is DAnnotation -> element.copy(extra = element.extra + DriClashAwareName(element.toClashedName())) + is DInterface -> element.copy(extra = element.extra + DriClashAwareName(element.toClashedName())) + is DEnum -> element.copy(extra = element.extra + DriClashAwareName(element.toClashedName())) + is DFunction -> element.copy(extra = element.extra + DriClashAwareName(element.toClashedName())) + is DProperty -> element.copy(extra = element.extra + DriClashAwareName(element.toClashedName())) + is DTypeAlias -> element.copy(extra = element.extra + DriClashAwareName(element.toClashedName())) + else -> null + } as? T? + } } - } open fun pageForFunction(f: DFunction) = MemberPageNode(f.nameAfterClash(), contentForFunction(f), setOf(f.dri), f) - open fun pageForProperty(p: DProperty): MemberPageNode? = MemberPageNode(p.nameAfterClash(), contentForProperty(p), setOf(p.dri), p) + open fun pageForProperty(p: DProperty): MemberPageNode? = + MemberPageNode(p.nameAfterClash(), contentForProperty(p), setOf(p.dri), p) - private fun <T> T.isInherited(): Boolean where T: Documentable, T: WithExtraProperties<T> = + private fun <T> T.isInherited(): Boolean where T : Documentable, T : WithExtraProperties<T> = sourceSets.all { sourceSet -> extra[InheritedMember]?.isInherited(sourceSet) == true } private val WithScope.filteredFunctions: List<DFunction> @@ -99,7 +102,7 @@ open class DefaultPageCreator( private val WithScope.filteredProperties: List<DProperty> get() = properties.filterNot { it.isInherited() } - private fun <T> Collection<T>.splitInherited(): Pair<List<T>, List<T>> where T: Documentable, T: WithExtraProperties<T> = + private fun <T> Collection<T>.splitInherited(): Pair<List<T>, List<T>> where T : Documentable, T : WithExtraProperties<T> = partition { it.isInherited() } protected open fun contentForModule(m: DModule) = contentBuilder.contentFor(m) { @@ -185,7 +188,12 @@ open class DefaultPageCreator( .groupBy({ it.second }, { it.first }).map { (classlike, platforms) -> val label = classlike.classNames?.substringBeforeLast(".") ?: classlike.toString() .also { logger.warn("No class name found for DRI $classlike") } - buildGroup(setOf(classlike), platforms.toSet(), ContentKind.Inheritors, extra = mainExtra + SymbolAnchorHint(label, ContentKind.Inheritors)) { + buildGroup( + setOf(classlike), + platforms.toSet(), + ContentKind.Inheritors, + extra = mainExtra + SymbolAnchorHint(label, ContentKind.Inheritors) + ) { link(label, classlike) } }, @@ -268,7 +276,12 @@ open class DefaultPageCreator( styles = emptySet() ) { link(it.name, it.dri) - sourceSetDependentHint(it.dri, it.sourceSets.toSet(), kind = ContentKind.SourceSetDependentHint, extra = PropertyContainer.empty<ContentNode>()) { + sourceSetDependentHint( + it.dri, + it.sourceSets.toSet(), + kind = ContentKind.SourceSetDependentHint, + extra = PropertyContainer.empty<ContentNode>() + ) { +buildSignature(it) contentForBrief(it) } @@ -322,13 +335,12 @@ open class DefaultPageCreator( if (unnamedTags.isNotEmpty()) { platforms.forEach { platform -> unnamedTags[platform]?.let { tags -> - if(tags.isNotEmpty()){ - tags.groupBy { it::class }.forEach { - (_, sameCategoryTags) -> - group(sourceSets = setOf(platform), styles = emptySet()) { - header(4, sameCategoryTags.first().toHeaderString()) - sameCategoryTags.forEach { comment(it.root) } - } + if (tags.isNotEmpty()) { + tags.groupBy { it::class }.forEach { (_, sameCategoryTags) -> + group(sourceSets = setOf(platform), styles = emptySet()) { + header(4, sameCategoryTags.first().toHeaderString()) + sameCategoryTags.forEach { comment(it.root) } + } } } } @@ -362,18 +374,18 @@ open class DefaultPageCreator( val receiver = tags.withTypeUnnamed<Receiver>() val params = tags.withTypeNamed<Param>() table(kind = ContentKind.Parameters) { - platforms.flatMap { platform -> + platforms.forEach { platform -> val possibleFallbacks = d.getPossibleFallbackSourcesets(platform) - val receiverRow = (receiver[platform] ?: receiver.fallback(possibleFallbacks))?.let { - buildGroup(sourceSets = setOf(platform), kind = ContentKind.Parameters) { + (receiver[platform] ?: receiver.fallback(possibleFallbacks))?.let { + row(sourceSets = setOf(platform), kind = ContentKind.Parameters) { text("<receiver>", styles = mainStyles + ContentStyle.RowTitle) comment(it.root) } } - val paramRows = params.mapNotNull { (_, param) -> + params.mapNotNull { (_, param) -> (param[platform] ?: param.fallback(possibleFallbacks))?.let { - buildGroup(sourceSets = setOf(platform), kind = ContentKind.Parameters) { + row(sourceSets = setOf(platform), kind = ContentKind.Parameters) { text( it.name, kind = ContentKind.Parameters, @@ -383,8 +395,6 @@ open class DefaultPageCreator( } } } - - listOfNotNull(receiverRow) + paramRows } } } @@ -402,14 +412,14 @@ open class DefaultPageCreator( sourceSetDependentHint(sourceSets = platforms.toSet(), kind = ContentKind.SourceSetDependentHint) { val seeAlsoTags = tags.withTypeNamed<See>() table(kind = ContentKind.Sample) { - platforms.flatMap { platform -> + platforms.forEach { platform -> val possibleFallbacks = d.getPossibleFallbackSourcesets(platform) - seeAlsoTags.mapNotNull { (_, see) -> + seeAlsoTags.forEach { (_, see) -> (see[platform] ?: see.fallback(possibleFallbacks))?.let { - buildGroup( + row( sourceSets = setOf(platform), kind = ContentKind.Comment, - styles = mainStyles + ContentStyle.RowTitle, + styles = this@sourceSetDependentHint.mainStyles + ContentStyle.RowTitle, ) { if (it.address != null) link( it.name, @@ -427,6 +437,7 @@ open class DefaultPageCreator( } } } + fun DocumentableContentBuilder.contentForThrows() { val throws = tags.withTypeNamed<Throws>() if (throws.isNotEmpty()) { @@ -434,9 +445,9 @@ open class DefaultPageCreator( sourceSetDependentHint(sourceSets = platforms.toSet(), kind = ContentKind.SourceSetDependentHint) { platforms.forEach { sourceset -> table(kind = ContentKind.Main, sourceSets = setOf(sourceset)) { - throws.entries.mapNotNull { entry -> + throws.entries.forEach { entry -> entry.value[sourceset]?.let { throws -> - buildGroup(sourceSets = setOf(sourceset)) { + row(sourceSets = setOf(sourceset)) { group(styles = mainStyles + ContentStyle.RowTitle) { throws.exceptionAddress?.let { link(text = entry.key, address = it) @@ -492,7 +503,7 @@ open class DefaultPageCreator( documentable.sourceSets.forEach { sourceSet -> documentable.documentation[sourceSet]?.children?.firstOrNull()?.root?.let { group(sourceSets = setOf(sourceSet), kind = ContentKind.BriefComment) { - if(documentable.hasSeparatePage) firstSentenceComment(it) + if (documentable.hasSeparatePage) firstSentenceComment(it) else comment(it) } } @@ -541,7 +552,12 @@ open class DefaultPageCreator( ContentKind.Functions, extra = mainExtra + SimpleAttr.header(name) ) - private fun DocumentableContentBuilder.propertiesBlock(name: String, list: Collection<DProperty>, sourceSets: Set<DokkaSourceSet>) { + + private fun DocumentableContentBuilder.propertiesBlock( + name: String, + list: Collection<DProperty>, + sourceSets: Set<DokkaSourceSet> + ) { block( name, 2, @@ -573,23 +589,27 @@ open class DefaultPageCreator( // This hacks displaying actual typealias signatures along classlike ones .mapValues { if (it.value.any { it is DClasslike }) it.value.filter { it !is DTypeAlias } else it.value } .toSortedMap(compareBy(nullsLast(String.CASE_INSENSITIVE_ORDER)) { it }) - .map { (elementName, elements) -> // This groupBy should probably use LocationProvider - buildGroup( + .forEach { (elementName, elements) -> // This groupBy should probably use LocationProvider + row( dri = elements.map { it.dri }.toSet(), sourceSets = elements.flatMap { it.sourceSets }.toSet(), kind = kind, styles = emptySet(), extra = elementName?.let { name -> extra + SymbolAnchorHint(name, kind) } ?: extra - ) { - link(elementName.orEmpty(), elements.first().dri, kind = kind) - divergentGroup( - ContentDivergentGroup.GroupID(name), - elements.map { it.dri }.toSet(), - kind = kind, - extra = extra + ) { + link(elementName.orEmpty(), elements.first().dri, kind = kind) + divergentGroup( + ContentDivergentGroup.GroupID(name), + elements.map { it.dri }.toSet(), + kind = kind, + extra = extra ) { elements.map { - instance(setOf(it.dri), it.sourceSets.toSet(), extra = PropertyContainer.withAll(SymbolAnchorHint(it.name ?: "", kind))) { + instance( + setOf(it.dri), + it.sourceSets.toSet(), + extra = PropertyContainer.withAll(SymbolAnchorHint(it.name ?: "", kind)) + ) { divergent(extra = PropertyContainer.empty()) { group { +buildSignature(it) @@ -625,6 +645,6 @@ open class DefaultPageCreator( private val Documentable.hasSeparatePage: Boolean get() = this !is DTypeAlias - private fun <T: Documentable> T.nameAfterClash(): String = + private fun <T : Documentable> T.nameAfterClash(): String = ((this as? WithExtraProperties<out Documentable>)?.extra?.get(DriClashAwareName)?.value ?: name).orEmpty() } diff --git a/plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt b/plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt index 9fee60cb..ba21f089 100644 --- a/plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt +++ b/plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt @@ -7,7 +7,6 @@ import org.jetbrains.dokka.base.transformers.pages.comments.CommentsToContentCon import org.jetbrains.dokka.links.DRI import org.jetbrains.dokka.model.Documentable import org.jetbrains.dokka.model.SourceSetDependent -import org.jetbrains.dokka.model.doc.Description import org.jetbrains.dokka.model.doc.DocTag import org.jetbrains.dokka.model.properties.PropertyContainer import org.jetbrains.dokka.model.toDisplaySourceSets @@ -89,16 +88,6 @@ open class PageContentBuilder( contents += this } - private val defaultHeaders - get() = listOf( - contentFor(mainDRI, mainSourcesetData) { - text("Name") - }, - contentFor(mainDRI, mainSourcesetData) { - text("Summary") - } - ) - fun header( level: Int, text: String, @@ -150,15 +139,11 @@ open class PageContentBuilder( sourceSets: Set<DokkaSourceSet> = mainSourcesetData, styles: Set<Style> = mainStyles, extra: PropertyContainer<ContentNode> = mainExtra, - operation: DocumentableContentBuilder.() -> List<ContentGroup> + operation: TableBuilder.() -> Unit = {} ) { - contents += ContentTable( - defaultHeaders, - null, - operation(), - DCI(mainDRI, kind), - sourceSets.toDisplaySourceSets(), styles, extra - ) + contents += TableBuilder(mainDRI, sourceSets, kind, styles, extra).apply { + operation() + }.build() } fun <T : Documentable> block( @@ -171,14 +156,14 @@ open class PageContentBuilder( extra: PropertyContainer<ContentNode> = mainExtra, renderWhenEmpty: Boolean = false, needsSorting: Boolean = true, - headers: List<ContentGroup>? = null, + headers: List<ContentGroup> = emptyList(), needsAnchors: Boolean = false, operation: DocumentableContentBuilder.(T) -> Unit ) { if (renderWhenEmpty || elements.any()) { header(level, name, kind = kind) { } contents += ContentTable( - header = headers ?: defaultHeaders, + header = headers, children = elements .let { if (needsSorting) @@ -300,14 +285,20 @@ open class PageContentBuilder( sourceSets: Set<DokkaSourceSet> = mainSourcesetData, styles: Set<Style> = mainStyles, extra: PropertyContainer<ContentNode> = mainExtra - ){ + ) { val builtDescription = commentsConverter.buildContent( content, DCI(mainDRI, kind), sourceSets ) - contents += ContentGroup(briefFromContentNodes(builtDescription), DCI(mainDRI, kind), sourceSets.toDisplaySourceSets(), styles, extra) + contents += ContentGroup( + briefFromContentNodes(builtDescription), + DCI(mainDRI, kind), + sourceSets.toDisplaySourceSets(), + styles, + extra + ) } fun group( @@ -394,6 +385,66 @@ open class PageContentBuilder( } @ContentBuilderMarker + open inner class TableBuilder( + private val mainDRI: Set<DRI>, + private val mainSourceSets: Set<DokkaSourceSet>, + private val mainKind: Kind, + private val mainStyles: Set<Style>, + private val mainExtra: PropertyContainer<ContentNode> + ) { + private val headerRows: MutableList<ContentGroup> = mutableListOf() + private val rows: MutableList<ContentGroup> = mutableListOf() + private var caption: ContentGroup? = null + + fun header( + dri: Set<DRI> = mainDRI, + sourceSets: Set<DokkaSourceSet> = mainSourceSets, + kind: Kind = mainKind, + styles: Set<Style> = mainStyles, + extra: PropertyContainer<ContentNode> = mainExtra, + block: DocumentableContentBuilder.() -> Unit + ) { + headerRows += contentFor(dri, sourceSets, kind, styles, extra, block) + } + + fun row( + dri: Set<DRI> = mainDRI, + sourceSets: Set<DokkaSourceSet> = mainSourceSets, + kind: Kind = mainKind, + styles: Set<Style> = mainStyles, + extra: PropertyContainer<ContentNode> = mainExtra, + block: DocumentableContentBuilder.() -> Unit + ) { + rows += contentFor(dri, sourceSets, kind, styles, extra, block) + } + + fun caption( + dri: Set<DRI> = mainDRI, + sourceSets: Set<DokkaSourceSet> = mainSourceSets, + kind: Kind = mainKind, + styles: Set<Style> = mainStyles, + extra: PropertyContainer<ContentNode> = mainExtra, + block: DocumentableContentBuilder.() -> Unit + ) { + caption = contentFor(dri, sourceSets, kind, styles, extra, block) + } + + fun build( + sourceSets: Set<DokkaSourceSet> = mainSourceSets, + kind: Kind = mainKind, + styles: Set<Style> = mainStyles, + extra: PropertyContainer<ContentNode> = mainExtra + ) = ContentTable( + headerRows, + caption, + rows, + DCI(mainDRI, kind), + sourceSets.toDisplaySourceSets(), + styles, extra + ) + } + + @ContentBuilderMarker open inner class DivergentBuilder( private val mainDRI: Set<DRI>, private val mainKind: Kind, |