aboutsummaryrefslogtreecommitdiff
path: root/plugins/base/src/main/kotlin
diff options
context:
space:
mode:
authorKamil Doległo <9080183+kamildoleglo@users.noreply.github.com>2021-01-04 12:59:03 +0100
committerGitHub <noreply@github.com>2021-01-04 12:59:03 +0100
commitd3f0e03284999e6f7fac99a345ed91cb63503706 (patch)
tree0becbb39444fbf7ee9300adc1fb6b04861ec54f6 /plugins/base/src/main/kotlin
parent6b0cdf3102b1f1dd213ca0c2e2c333f8756be6b4 (diff)
downloaddokka-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/main/kotlin')
-rw-r--r--plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt130
-rw-r--r--plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt97
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,