diff options
| author | KrystianUjma <kujma@virtuslab.com> | 2019-03-19 11:34:38 +0100 |
|---|---|---|
| committer | KrystianUjma <kujma@virtuslab.com> | 2019-03-19 15:56:01 +0100 |
| commit | 2e94ac4098d9e2582223485b981114fa462e5757 (patch) | |
| tree | ed1b772bce9d790c473b346bcce435e893b29be7 /core/src/main/kotlin/Formats | |
| parent | b566f8852e94f9a17be86bf845aeff6c36bd8378 (diff) | |
| parent | a9c91cb7dc54c1554be5cf8de90516c929c0c1cb (diff) | |
| download | dokka-2e94ac4098d9e2582223485b981114fa462e5757.tar.gz dokka-2e94ac4098d9e2582223485b981114fa462e5757.tar.bz2 dokka-2e94ac4098d9e2582223485b981114fa462e5757.zip | |
Merge branch 'kotlin-website-jonnyzzz' into multiplatform-support
Diffstat (limited to 'core/src/main/kotlin/Formats')
6 files changed, 617 insertions, 228 deletions
diff --git a/core/src/main/kotlin/Formats/FormatDescriptor.kt b/core/src/main/kotlin/Formats/FormatDescriptor.kt index b497fb0f..4bac8aa0 100644 --- a/core/src/main/kotlin/Formats/FormatDescriptor.kt +++ b/core/src/main/kotlin/Formats/FormatDescriptor.kt @@ -25,6 +25,7 @@ abstract class FileGeneratorBasedFormatDescriptor : FormatDescriptor { override fun configureOutput(binder: Binder): Unit = with(binder) { bind<Generator>() toType NodeLocationAwareGenerator::class bind<NodeLocationAwareGenerator>() toType generatorServiceClass + bind(generatorServiceClass.java) // https://github.com/google/guice/issues/847 bind<LanguageService>() toType languageServiceClass diff --git a/core/src/main/kotlin/Formats/KotlinWebsiteFormatService.kt b/core/src/main/kotlin/Formats/KotlinWebsiteFormatService.kt index a98002d4..51ceb47e 100644 --- a/core/src/main/kotlin/Formats/KotlinWebsiteFormatService.kt +++ b/core/src/main/kotlin/Formats/KotlinWebsiteFormatService.kt @@ -57,8 +57,8 @@ open class KotlinWebsiteOutputBuilder( } } - override fun appendAsOverloadGroup(to: StringBuilder, platforms: Set<String>, block: () -> Unit) { - div(to, "overload-group", calculateDataAttributes(platforms), true) { + override fun appendAsOverloadGroup(to: StringBuilder, platforms: PlatformsData, block: () -> Unit) { + div(to, "overload-group", calculateDataAttributes(platforms.keys), true) { ensureParagraph() block() ensureParagraph() @@ -159,14 +159,14 @@ open class KotlinWebsiteOutputBuilder( return "$platformsAttr$kotlinVersionAttr$jreVersionAttr" } - override fun appendIndexRow(platforms: Set<String>, block: () -> Unit) { + override fun appendIndexRow(platforms: PlatformsData, block: () -> Unit) { if (platforms.isNotEmpty()) - wrap("<tr${calculateDataAttributes(platforms)}>", "</tr>", block) + wrap("<tr${calculateDataAttributes(platforms.keys)}>", "</tr>", block) else appendTableRow(block) } - override fun appendPlatforms(platforms: Set<String>) { + override fun appendPlatforms(platforms: PlatformsData) { } } diff --git a/core/src/main/kotlin/Formats/KotlinWebsiteHtmlFormatService.kt b/core/src/main/kotlin/Formats/KotlinWebsiteHtmlFormatService.kt index 6ced75b5..86bc9df9 100644 --- a/core/src/main/kotlin/Formats/KotlinWebsiteHtmlFormatService.kt +++ b/core/src/main/kotlin/Formats/KotlinWebsiteHtmlFormatService.kt @@ -3,7 +3,6 @@ package org.jetbrains.dokka import com.google.inject.Inject import com.google.inject.name.Named import org.jetbrains.dokka.Utilities.impliedPlatformsName -import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty import java.io.File @@ -20,7 +19,7 @@ open class KotlinWebsiteHtmlOutputBuilder( generator: NodeLocationAwareGenerator, languageService: LanguageService, extension: String, - impliedPlatforms: List<String>, + val impliedPlatforms: List<String>, templateService: HtmlTemplateService ) : HtmlOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms, templateService) { private var needHardLineBreaks = false @@ -60,7 +59,7 @@ open class KotlinWebsiteHtmlOutputBuilder( } } - override fun appendAsOverloadGroup(to: StringBuilder, platforms: Set<String>, block: () -> Unit) { + override fun appendAsOverloadGroup(to: StringBuilder, platforms: PlatformsData, block: () -> Unit) { div(to, "overload-group", calculateDataAttributes(platforms)) { block() } @@ -69,27 +68,29 @@ open class KotlinWebsiteHtmlOutputBuilder( override fun appendLink(href: String, body: () -> Unit) = wrap("<a href=\"$href\">", "</a>", body) override fun appendTable(vararg columns: String, body: () -> Unit) { - to.appendln("<table class=\"api-docs-table\">") - body() - to.appendln("</table>") + //to.appendln("<table class=\"api-docs-table\">") + div(to, "api-declarations-list") { + body() + } + //to.appendln("</table>") } override fun appendTableBody(body: () -> Unit) { - to.appendln("<tbody>") + //to.appendln("<tbody>") body() - to.appendln("</tbody>") + //to.appendln("</tbody>") } override fun appendTableRow(body: () -> Unit) { - to.appendln("<tr>") + //to.appendln("<tr>") body() - to.appendln("</tr>") + //to.appendln("</tr>") } override fun appendTableCell(body: () -> Unit) { - to.appendln("<td>") +// to.appendln("<td>") body() - to.appendln("\n</td>") +// to.appendln("\n</td>") } override fun appendSymbol(text: String) { @@ -122,34 +123,79 @@ open class KotlinWebsiteHtmlOutputBuilder( else -> "identifier" } - fun calculateDataAttributes(platforms: Set<String>): String { - fun String.isKotlinVersion() = this.startsWith("Kotlin") - fun String.isJREVersion() = this.startsWith("JRE") - val kotlinVersion = platforms.singleOrNull(String::isKotlinVersion) - val jreVersion = platforms.singleOrNull(String::isJREVersion) - val targetPlatforms = platforms.filterNot { it.isKotlinVersion() || it.isJREVersion() } + private data class PlatformsForElement( + val platformToVersion: Map<String, String> + ) + + private fun calculatePlatforms(platforms: PlatformsData): PlatformsForElement { + //val kotlinVersion = platforms.singleOrNull(String::isKotlinVersion)?.removePrefix("Kotlin ") + val jreVersion = platforms.keys.filter(String::isJREVersion).min()?.takeUnless { it.endsWith("6") } + val targetPlatforms = platforms.filterNot { it.key.isJREVersion() } + + listOfNotNull(jreVersion?.let { it to platforms[it]!! }) + + return PlatformsForElement( + targetPlatforms.mapValues { (_, nodes) -> effectiveSinceKotlinForNodes(nodes) } + ) + } - val kotlinVersionAttr = kotlinVersion?.let { " data-kotlin-version=\"$it\"" } ?: "" - val jreVersionAttr = jreVersion?.let { " data-jre-version=\"$it\"" } ?: "" - val platformsAttr = targetPlatforms.ifNotEmpty { " data-platform=\"${targetPlatforms.joinToString()}\"" } ?: "" - return "$platformsAttr$kotlinVersionAttr$jreVersionAttr" + private fun calculateDataAttributes(platforms: PlatformsData): String { + val platformToVersion = calculatePlatforms(platforms).platformToVersion + val (platformNames, versions) = platformToVersion.toList().unzip() + return "data-platform=\"${platformNames.joinToString()}\" "+ + "data-kotlin-version=\"${versions.joinToString()}\"" } - override fun appendIndexRow(platforms: Set<String>, block: () -> Unit) { - if (platforms.isNotEmpty()) - wrap("<tr${calculateDataAttributes(platforms)}>", "</tr>", block) - else - appendTableRow(block) + override fun appendIndexRow(platforms: PlatformsData, block: () -> Unit) { +// if (platforms.isNotEmpty()) +// wrap("<tr${calculateDataAttributes(platforms)}>", "</tr>", block) +// else +// appendTableRow(block) + div(to, "declarations", otherAttributes = " ${calculateDataAttributes(platforms)}") { + block() + } } - override fun appendPlatforms(platforms: Set<String>) {} + override fun appendPlatforms(platforms: PlatformsData) { + val platformToVersion = calculatePlatforms(platforms).platformToVersion + div(to, "tags") { + div(to, "spacer") {} + platformToVersion.entries.sortedBy { + platformSortWeight(it.key) + }.forEach { (platform, version) -> + div(to, "tags__tag platform tag-value-$platform", + otherAttributes = " data-tag-version=\"$version\"") { + to.append(platform) + } + } + div(to, "tags__tag kotlin-version") { + to.append(mergeVersions(platformToVersion.values.toList())) + } + } + } + + override fun appendAsNodeDescription(platforms: PlatformsData, block: () -> Unit) { + div(to, "node-page-main", otherAttributes = " ${calculateDataAttributes(platforms)}") { + block() + } + + } override fun appendBreadcrumbSeparator() { to.append(" / ") } + override fun appendPlatformsAsText(platforms: PlatformsData) { + appendHeader(5) { + val filtered = platforms.keys.filterNot { it.isJREVersion() }.sortedBy { platformSortWeight(it) } + if (filtered.isNotEmpty()) { + to.append("For ") + filtered.joinTo(to) + } + } + } + override fun appendSampleBlockCode(language: String, imports: () -> Unit, body: () -> Unit) { - div(to, "sample") { + div(to, "sample", otherAttributes = " data-min-compiler-version=\"1.3\"") { appendBlockCode(language) { imports() wrap("\n\nfun main(args: Array<String>) {".htmlEscape(), "}") { @@ -169,6 +215,29 @@ open class KotlinWebsiteHtmlOutputBuilder( appendContent(section) } } + + override fun appendAsPlatformDependentBlock(platforms: PlatformsData, block: (PlatformsData) -> Unit) { + if (platforms.isNotEmpty()) + wrap("<div ${calculateDataAttributes(platforms)}>", "</div>") { + block(platforms) + } + else + block(platforms) + } + + override fun appendAsSummaryGroup(platforms: PlatformsData, block: (PlatformsData) -> Unit) { + div(to, "summary-group", otherAttributes = " ${calculateDataAttributes(platforms)}") { + block(platforms) + } + } + + fun platformSortWeight(name: String) = when(name.toLowerCase()) { + "common" -> 0 + "jvm" -> 1 + "js" -> 3 + "native" -> 4 + else -> 2 // This is hack to support JRE/JUnit and so on + } } class KotlinWebsiteHtmlFormatService @Inject constructor( @@ -184,3 +253,6 @@ class KotlinWebsiteHtmlFormatService @Inject constructor( KotlinWebsiteHtmlOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms, templateService) } + +private fun String.isKotlinVersion() = this.startsWith("Kotlin") +private fun String.isJREVersion() = this.startsWith("JRE", ignoreCase=true)
\ No newline at end of file diff --git a/core/src/main/kotlin/Formats/PackageListService.kt b/core/src/main/kotlin/Formats/PackageListService.kt index 7b68098e..e675d927 100644 --- a/core/src/main/kotlin/Formats/PackageListService.kt +++ b/core/src/main/kotlin/Formats/PackageListService.kt @@ -32,10 +32,13 @@ class DefaultPackageListService @Inject constructor( node.members.forEach { visit(it, relocated = true) } } NodeKind.GroupNode -> { - //only children of top-level GN records interesting for us, since link to top-level ones should point to GN - node.members.forEach { it.members.forEach { visit(it, relocated = true) } } - //record signature of GN as signature of type alias and class merged to GN, so link to it should point to GN - node.detailOrNull(NodeKind.Signature)?.let { visit(it, relocated = true) } + if (node.members.isNotEmpty()) { + // Only nodes only has single file is need to be relocated + // TypeAliases for example + node.origins + .filter { it.members.isEmpty() } + .forEach { visit(it, relocated = true) } + } } else -> { if (nodeKind in NodeKind.classLike || nodeKind in NodeKind.memberLike) { diff --git a/core/src/main/kotlin/Formats/StructuredFormatService.kt b/core/src/main/kotlin/Formats/StructuredFormatService.kt index 410de281..04810498 100644 --- a/core/src/main/kotlin/Formats/StructuredFormatService.kt +++ b/core/src/main/kotlin/Formats/StructuredFormatService.kt @@ -1,18 +1,59 @@ package org.jetbrains.dokka import org.jetbrains.dokka.LanguageService.RenderMode +import org.jetbrains.kotlin.utils.keysToMap import java.util.* data class FormatLink(val text: String, val href: String) +private data class Summarized( + val data: List<SummarizedBySummary> +) { + + constructor(data: Map<ContentNode, Map<ContentNode, List<DocumentationNode>>>) : this( + data.entries.map { (summary, signatureToMember) -> + SummarizedBySummary( + summary, + signatureToMember.map { (signature, nodes) -> + SummarizedNodes(signature, nodes) + } + ) + } + ) + + data class SummarizedNodes(val content: ContentNode, val nodes: List<DocumentationNode>) { + val platforms = effectivePlatformsForMembers(nodes) + } + data class SummarizedBySummary(val content: ContentNode, val signatures: List<SummarizedNodes>) { + val platforms = effectivePlatformsForMembers(signatures.flatMap { it.nodes }) + val platformsOnSignature = !samePlatforms(signatures.map { it.platforms }) + } + + + fun computePlatformLevel(): PlatformPlacement { + if (data.any { it.platformsOnSignature }) { + return PlatformPlacement.Signature + } + if (samePlatforms(data.map { it.platforms })) { + return PlatformPlacement.Row + } + return PlatformPlacement.Summary + } + val platformPlacement: PlatformPlacement = computePlatformLevel() + val platforms = effectivePlatformsForMembers(data.flatMap { it.signatures.flatMap { it.nodes } }) + + + enum class PlatformPlacement { + Row, Summary, Signature + } +} + abstract class StructuredOutputBuilder(val to: StringBuilder, val location: Location, val generator: NodeLocationAwareGenerator, val languageService: LanguageService, val extension: String, - val impliedPlatforms: List<String>) : FormattedOutputBuilder { - - protected fun DocumentationNode.location() = generator.location(this) + impliedPlatforms: List<String>) : FormattedOutputBuilder { protected fun wrap(prefix: String, suffix: String, body: () -> Unit) { to.append(prefix) @@ -83,6 +124,14 @@ abstract class StructuredOutputBuilder(val to: StringBuilder, } } + open fun appendAsPlatformDependentBlock(platforms: PlatformsData, block: (PlatformsData) -> Unit) { + block(platforms) + } + + open fun appendAsSummaryGroup(platforms: PlatformsData, block: (PlatformsData) -> Unit) { + appendAsPlatformDependentBlock(platforms, block) + } + open fun appendSymbol(text: String) { appendText(text) } @@ -95,6 +144,10 @@ abstract class StructuredOutputBuilder(val to: StringBuilder, appendText(text) } + open fun appendAsNodeDescription(platforms: PlatformsData, block: () -> Unit) { + block() + } + fun appendEntity(text: String) { to.append(text) } @@ -158,7 +211,7 @@ abstract class StructuredOutputBuilder(val to: StringBuilder, } is ContentNodeLink -> { val node = content.node - val linkTo = if (node != null) locationHref(location, node) else "#" + val linkTo = if (node != null) locationHref(location, node, generator) else "#" appendLinkIfNotThisPage(linkTo, content) } is ContentExternalLink -> appendLinkIfNotThisPage(content.href, content) @@ -196,31 +249,19 @@ abstract class StructuredOutputBuilder(val to: StringBuilder, } } - open fun link(from: DocumentationNode, - to: DocumentationNode, - name: (DocumentationNode) -> String = DocumentationNode::name): FormatLink = link(from, to, extension, name) - - open fun link(from: DocumentationNode, - to: DocumentationNode, - extension: String, - name: (DocumentationNode) -> String = DocumentationNode::name): FormatLink { - if (to.owner?.kind == NodeKind.GroupNode) - return link(from, to.owner!!, extension, name) - - if (from.owner?.kind == NodeKind.GroupNode) - return link(from.owner!!, to, extension, name) + open fun link( + from: DocumentationNode, + to: DocumentationNode, + name: (DocumentationNode) -> String = DocumentationNode::name + ): FormatLink = link(from, to, extension, name) - return FormatLink(name(to), from.location().relativePathTo(to.location())) - } - - fun locationHref(from: Location, to: DocumentationNode): String { - val topLevelPage = to.references(RefKind.TopLevelPage).singleOrNull()?.to - if (topLevelPage != null) { - val signature = to.detailOrNull(NodeKind.Signature) - return from.relativePathTo(topLevelPage.location(), signature?.name ?: to.name) - } - return from.relativePathTo(to.location()) - } + open fun link( + from: DocumentationNode, + to: DocumentationNode, + extension: String, + name: (DocumentationNode) -> String = DocumentationNode::name + ): FormatLink = + FormatLink(name(to), generator.relativePathToLocation(from, to)) private fun DocumentationNode.isModuleOrPackage(): Boolean = kind == NodeKind.Module || kind == NodeKind.Package @@ -229,18 +270,25 @@ abstract class StructuredOutputBuilder(val to: StringBuilder, block() } - protected open fun appendAsOverloadGroup(to: StringBuilder, platforms: Set<String>, block: () -> Unit) { + protected open fun appendAsOverloadGroup(to: StringBuilder, platforms: PlatformsData, block: () -> Unit) { block() } - protected open fun appendIndexRow(platforms: Set<String>, block: () -> Unit) { + protected open fun appendIndexRow(platforms: PlatformsData, block: () -> Unit) { appendTableRow(block) } - protected open fun appendPlatforms(platforms: Set<String>) { + protected open fun appendPlatformsAsText(platforms: PlatformsData) { + if (platforms.isNotEmpty()) { + appendLine() + appendText(platforms.keys.joinToString(prefix = "(", postfix = ")")) + } + } + + protected open fun appendPlatforms(platforms: PlatformsData) { if (platforms.isNotEmpty()) { appendLine() - appendText(platforms.joinToString(prefix = "(", postfix = ")")) + appendText(platforms.keys.joinToString(prefix = "(", postfix = ")")) } } @@ -289,7 +337,6 @@ abstract class StructuredOutputBuilder(val to: StringBuilder, val packageName = if (singleNode.name.isEmpty()) "<root>" else singleNode.name appendHeader(2) { appendText("Package $packageName") } } - singleNode.appendPlatforms() appendContent(singleNode.content) } else { val breakdownByName = nodes.groupBy { node -> node.name } @@ -302,45 +349,136 @@ abstract class StructuredOutputBuilder(val to: StringBuilder, } private fun appendDocumentation(overloads: Iterable<DocumentationNode>, isSingleNode: Boolean) { - val breakdownBySummary = overloads.groupByTo(LinkedHashMap()) { node -> node.content } + val breakdownBySummary = overloads.groupByTo(LinkedHashMap()) { node -> + when (node.kind) { + NodeKind.GroupNode -> node.origins.map { it.content } + else -> node.content + } + } if (breakdownBySummary.size == 1) { - formatOverloadGroup(breakdownBySummary.values.single(), isSingleNode) + val node = breakdownBySummary.values.single() + appendAsNodeDescription(effectivePlatformsForMembers(node)) { + formatOverloadGroup(node, isSingleNode) + } } else { for ((_, items) in breakdownBySummary) { - - appendAsOverloadGroup(to, platformsOfItems(items)) { + appendAsOverloadGroup(to, effectivePlatformsForMembers(items)) { formatOverloadGroup(items) } - } } } private fun formatOverloadGroup(items: List<DocumentationNode>, isSingleNode: Boolean = false) { + + val platformsPerGroup = samePlatforms( + items.flatMap { + if (it.kind == NodeKind.GroupNode) { + it.origins.groupBy { origin -> + languageService.render(origin) + }.values.map { origins -> effectivePlatformsForMembers(origins) } + } else { + listOf(effectivePlatformsForNode(it)) + } + } + ) + + if (platformsPerGroup) { + appendAsPlatformDependentBlock(effectivePlatformsForMembers(items)) { platforms -> + appendPlatforms(platforms) + } + } for ((index, item) in items.withIndex()) { if (index > 0) appendLine() + + if (item.kind == NodeKind.GroupNode) { + renderGroupNode(item, isSingleNode, !platformsPerGroup) + } else { + renderSimpleNode(item, isSingleNode, !platformsPerGroup) + } + + } + // All items have exactly the same documentation, so we can use any item to render it + val item = items.first() + // TODO: remove this block cause there is no one node with OverloadGroupNote detail + item.details(NodeKind.OverloadGroupNote).forEach { + appendContent(it.content) + } + + if (item.kind == NodeKind.GroupNode) { + val groupByContent = item.origins.groupBy { it.content } + if (groupByContent.count { !it.key.isEmpty() } > 1) { + if (groupByContent.size > 1) println("[mult] Found ov diff: ${generator.location(item).path}") + } + for ((content, origins) in groupByContent) { + if (content.isEmpty()) continue + appendAsPlatformDependentBlock(effectivePlatformsForMembers(origins)) { platforms -> + if (groupByContent.count { !it.key.isEmpty() } > 1) { + appendPlatformsAsText(platforms) + } + appendContent(content.summary) + content.appendDescription() + } + } + } else { + if (!item.content.isEmpty()) { + val platforms = effectivePlatformsForNode(item) + appendAsPlatformDependentBlock(platforms) { + appendContent(item.summary) + item.content.appendDescription() + } + } + } + } + + + fun renderSimpleNode(item: DocumentationNode, isSingleNode: Boolean, withPlatforms: Boolean = true) { + appendAsPlatformDependentBlock(effectivePlatformsForMembers(listOf(item))) { platforms -> + // TODO: use summarizesignatures val rendered = languageService.render(item) item.detailOrNull(NodeKind.Signature)?.let { if (item.kind !in NodeKind.classLike || !isSingleNode) appendAnchor(it.name) } + if (withPlatforms) { + appendPlatforms(platforms) + } appendAsSignature(rendered) { appendCode { appendContent(rendered) } item.appendSourceLink() } item.appendOverrides() item.appendDeprecation() - item.appendPlatforms() } - // All items have exactly the same documentation, so we can use any item to render it - val item = items.first() - item.details(NodeKind.OverloadGroupNote).forEach { - appendContent(it.content) + } + + fun renderGroupNode(item: DocumentationNode, isSingleNode: Boolean, withPlatforms: Boolean = true) { + // TODO: use summarizesignatures + val groupBySignature = item.origins.groupBy { + languageService.render(it) } - appendContent(item.content.summary) - item.appendDescription() + for ((sign, nodes) in groupBySignature) { + appendAsPlatformDependentBlock(effectivePlatformsForMembers(nodes)) { platforms -> + val first = nodes.first() + first.detailOrNull(NodeKind.Signature)?.let { + if (item.kind !in NodeKind.classLike || !isSingleNode) + appendAnchor(it.name) + } + + if (withPlatforms) { + appendPlatforms(platforms) + } + + appendAsSignature(sign) { + appendCode { appendContent(sign) } + } + first.appendOverrides() + first.appendDeprecation() + } + + } } private fun DocumentationNode.appendSourceLink() { @@ -355,7 +493,7 @@ abstract class StructuredOutputBuilder(val to: StringBuilder, overrides.forEach { appendParagraph { to.append("Overrides ") - val location = location().relativePathTo(it.location()) + val location = generator.relativePathToLocation(this, it) appendLink(FormatLink(it.owner!!.name + "." + it.name, location)) } @@ -367,82 +505,95 @@ abstract class StructuredOutputBuilder(val to: StringBuilder, val deprecationParameter = deprecation!!.details(NodeKind.Parameter).firstOrNull() val deprecationValue = deprecationParameter?.details(NodeKind.Value)?.firstOrNull() appendLine() - if (deprecationValue != null) { - appendStrong { to.append("Deprecated:") } - appendText(" " + deprecationValue.name.removeSurrounding("\"")) - appendLine() - appendLine() - } else if (deprecation?.content != Content.Empty) { - appendStrong { to.append("Deprecated:") } - to.append(" ") - appendContent(deprecation!!.content) - } else { - appendStrong { to.append("Deprecated") } - appendLine() - appendLine() - } - } - } - - private fun DocumentationNode.appendPlatforms() { - val platforms = if (isModuleOrPackage()) - platformsToShow.toSet() + platformsOfItems(members) - else - platformsToShow - - if (platforms.isEmpty()) return - - appendParagraph { - appendStrong { to.append("Platform and version requirements:") } - to.append(" " + platforms.joinToString()) - } - } - - protected fun platformsOfItems(items: List<DocumentationNode>): Set<String> { - val platforms = items.asSequence().map { - when (it.kind) { - NodeKind.ExternalClass, NodeKind.Package, NodeKind.Module, NodeKind.GroupNode -> platformsOfItems(it.members) - else -> it.platformsToShow.toSet() - } - } - - fun String.isKotlinVersion() = this.startsWith("Kotlin") - - // Calculating common platforms for items - return platforms.reduce { result, platformsOfItem -> - val otherKotlinVersion = result.find { it.isKotlinVersion() } - val (kotlinVersions, otherPlatforms) = platformsOfItem.partition { it.isKotlinVersion() } - - // When no Kotlin version specified, it means that version is 1.0 - if (otherKotlinVersion != null && kotlinVersions.isNotEmpty()) { - val allKotlinVersions = (kotlinVersions + otherKotlinVersion).distinct() - - val minVersion = allKotlinVersions.min()!! - val resultVersion = when { - allKotlinVersions.size == 1 -> allKotlinVersions.single() - minVersion.endsWith("+") -> minVersion - else -> minVersion + "+" + when { + deprecationValue != null -> { + appendStrong { to.append("Deprecated:") } + appendText(" " + deprecationValue.name.removeSurrounding("\"")) + appendLine() + appendLine() + } + deprecation?.content != Content.Empty -> { + appendStrong { to.append("Deprecated:") } + to.append(" ") + appendContent(deprecation!!.content) + } + else -> { + appendStrong { to.append("Deprecated") } + appendLine() + appendLine() } - - result.intersect(otherPlatforms) + resultVersion - } else { - result.intersect(platformsOfItem) } } } - val DocumentationNode.platformsToShow: List<String> - get() = platforms.let { if (it.containsAll(impliedPlatforms)) it - impliedPlatforms else it } - private fun DocumentationNode.appendDescription() { - if (content.description != ContentEmpty) { - appendContent(content.description) - } - content.getSectionsWithSubjects().forEach { +// protected fun platformsOfItems(items: List<DocumentationNode>): Set<String> { +// val platforms = items.asSequence().map { +// when (it.kind) { +// NodeKind.ExternalClass, NodeKind.Package, NodeKind.Module -> platformsOfItems(it.members) +// NodeKind.GroupNode -> platformsOfItems(it.origins) +// else -> it.platformsToShow.toSet() +// } +// } +// +// fun String.isKotlinVersion() = this.startsWith("Kotlin") +// +// if (platforms.count() == 0) return emptySet() +// +// // Calculating common platforms for items +// return platforms.reduce { result, platformsOfItem -> +// val otherKotlinVersion = result.find { it.isKotlinVersion() } +// val (kotlinVersions, otherPlatforms) = platformsOfItem.partition { it.isKotlinVersion() } +// +// // When no Kotlin version specified, it means that version is 1.0 +// if (otherKotlinVersion != null && kotlinVersions.isNotEmpty()) { +// result.intersect(platformsOfItem) + mergeVersions(otherKotlinVersion, kotlinVersions) +// } else { +// result.intersect(platformsOfItem) +// } +// } +// } +// +// protected fun unionPlatformsOfItems(items: List<DocumentationNode>): Set<String> { +// val platforms = items.asSequence().map { +// when (it.kind) { +// NodeKind.GroupNode -> unionPlatformsOfItems(it.origins) +// else -> it.platformsToShow.toSet() +// } +// } +// +// fun String.isKotlinVersion() = this.startsWith("Kotlin") +// +// if (platforms.count() == 0) return emptySet() +// +// // Calculating common platforms for items +// return platforms.reduce { result, platformsOfItem -> +// val otherKotlinVersion = result.find { it.isKotlinVersion() } +// val (kotlinVersions, otherPlatforms) = platformsOfItem.partition { it.isKotlinVersion() } +// +// // When no Kotlin version specified, it means that version is 1.0 +// if (otherKotlinVersion != null && kotlinVersions.isNotEmpty()) { +// result.union(otherPlatforms) + mergeVersions(otherKotlinVersion, kotlinVersions) +// } else { +// result.union(otherPlatforms) +// } +// } +// } + +// val DocumentationNode.platformsToShow: List<String> +// get() = platforms + + private fun Content.appendDescription() { + if (description != ContentEmpty) { + appendContent(description) + } + + + getSectionsWithSubjects().forEach { appendSectionWithSubject(it.key, it.value) } - for (section in content.sections.filter { it.subjectName == null }) { + for (section in sections.filter { it.subjectName == null }) { appendSectionWithTag(section) } } @@ -461,6 +612,38 @@ abstract class StructuredOutputBuilder(val to: StringBuilder, } } } + + fun appendOriginsGroupByContent(node: DocumentationNode) { + require(node.kind == NodeKind.GroupNode) + val groupByContent = + node.origins.groupBy { it.content } + .mapValues { (_, origins) -> + effectivePlatformsForMembers(origins) + } + .filterNot { it.key.isEmpty() } + .toList() + .sortedByDescending { it.second.size } + + if (groupByContent.size > 1) println("[mult] Found diff: ${generator.location(node).path}") + for ((content, platforms) in groupByContent) { + appendAsPlatformDependentBlock(platforms) { + if (groupByContent.size > 1) { + appendPlatformsAsText(platforms) + } + appendContent(content.summary) + content.appendDescription() + } + } + } + } + + inner class SingleNodePageBuilder(val node: DocumentationNode, noHeader: Boolean = false) : + PageBuilder(listOf(node), noHeader) { + + override fun build() { + super.build() + SectionsBuilder(node).build() + } } |
