aboutsummaryrefslogtreecommitdiff
path: root/plugins/base
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/base')
-rw-r--r--plugins/base/src/main/kotlin/DokkaBase.kt5
-rw-r--r--plugins/base/src/main/kotlin/transformers/documentables/DefaultDocumentableMerger.kt116
2 files changed, 121 insertions, 0 deletions
diff --git a/plugins/base/src/main/kotlin/DokkaBase.kt b/plugins/base/src/main/kotlin/DokkaBase.kt
index 648acfbb..b18e2ad5 100644
--- a/plugins/base/src/main/kotlin/DokkaBase.kt
+++ b/plugins/base/src/main/kotlin/DokkaBase.kt
@@ -2,10 +2,15 @@ package org.jetbrains.dokka.base
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.plugability.DokkaPlugin
class DokkaBase: DokkaPlugin() {
val defaultDescriptorToDocumentationTranslator by extending(isFallback = true) {
CoreExtensions.descriptorToDocumentationTranslator providing ::DefaultDescriptorToDocumentationTranslator
}
+
+ val defaultDocumentableMerger by extending(isFallback = true) {
+ CoreExtensions.documentableMerger with DefaultDocumentableMerger
+ }
} \ No newline at end of file
diff --git a/plugins/base/src/main/kotlin/transformers/documentables/DefaultDocumentableMerger.kt b/plugins/base/src/main/kotlin/transformers/documentables/DefaultDocumentableMerger.kt
new file mode 100644
index 00000000..f2e6f177
--- /dev/null
+++ b/plugins/base/src/main/kotlin/transformers/documentables/DefaultDocumentableMerger.kt
@@ -0,0 +1,116 @@
+package org.jetbrains.dokka.base.transformers.documentables
+
+import org.jetbrains.dokka.model.*
+import org.jetbrains.dokka.model.Enum
+import org.jetbrains.dokka.model.Function
+import org.jetbrains.dokka.plugability.DokkaContext
+import org.jetbrains.dokka.transformers.documentation.DocumentableMerger
+import org.jetbrains.dokka.utilities.pullOutNull
+
+internal object DefaultDocumentableMerger : DocumentableMerger {
+ override fun invoke(modules: Collection<Module>, context: DokkaContext): Module {
+ if (!modules.all { it.name == modules.first().name })
+ context.logger.error("All module names need to be the same")
+ return Module(
+ modules.first().name,
+ merge(
+ modules.flatMap { it.packages },
+ Package::mergeWith
+ )
+ )
+ }
+}
+
+private fun <T : Documentable> merge(elements: List<T>, reducer: (T, T) -> T): List<T> =
+ elements.groupingBy { it.dri }
+ .reduce { _, left, right -> reducer(left, right) }
+ .values.toList()
+
+fun PlatformInfo.mergeWith(other: PlatformInfo?) = BasePlatformInfo(
+ documentationNode,
+ (platformData + (other?.platformData ?: emptyList())).distinct()
+)
+
+fun ClassPlatformInfo.mergeWith(other: ClassPlatformInfo?) = ClassPlatformInfo(
+ info.mergeWith(other?.info),
+ (inherited + (other?.inherited ?: emptyList())).distinct()
+)
+
+fun List<ClassPlatformInfo>.mergeClassPlatformInfo(): List<ClassPlatformInfo> =
+ groupingBy { it.documentationNode.children + it.inherited }.reduce { _, left, right ->
+ left.mergeWith(right)
+ }.values.toList()
+
+fun List<PlatformInfo>.merge(): List<PlatformInfo> =
+ groupingBy { it.documentationNode }.reduce { _, left, right ->
+ left.mergeWith(right)
+ }.values.toList()
+
+fun Function.mergeWith(other: Function): Function = Function(
+ dri,
+ name,
+ returnType,
+ isConstructor,
+ (receiver to other.receiver).pullOutNull()?.let { (f, s) -> f.mergeWith(s) },
+ merge(parameters + other.parameters, Parameter::mergeWith),
+ expected?.mergeWith(other.expected),
+ (actual + other.actual).merge(),
+ visibility = (visibility + other.visibility)
+)
+
+fun Property.mergeWith(other: Property) = Property(
+ dri,
+ name,
+ (receiver to other.receiver).pullOutNull()?.let { (f, s) -> f.mergeWith(s) },
+ expected?.mergeWith(other.expected),
+ (actual + other.actual).merge(),
+ accessors = (this.accessors + other.accessors).distinct(),
+ visibility = (visibility + other.visibility)
+)
+
+fun Classlike.mergeWith(other: Classlike): Classlike = when {
+ this is Class && other is Class -> mergeWith(other)
+ this is Enum && other is Enum -> mergeWith(other)
+ else -> throw IllegalStateException("${this::class.qualifiedName} ${this.name} cannot be merged with ${other::class.qualifiedName} ${other.name}")
+}
+
+fun Class.mergeWith(other: Class) = Class(
+ dri = dri,
+ name = name,
+ kind = kind,
+ constructors = merge(constructors + other.constructors, Function::mergeWith),
+ functions = merge(functions + other.functions, Function::mergeWith),
+ properties = merge(properties + other.properties, Property::mergeWith),
+ classlikes = merge(classlikes + other.classlikes, Classlike::mergeWith),
+ expected = expected?.mergeWith(other.expected),
+ actual = (actual + other.actual).mergeClassPlatformInfo(),
+ visibility = (visibility + other.visibility)
+)
+
+fun Enum.mergeWith(other: Enum) = Enum(
+ dri = dri,
+ name = name,
+ functions = merge(functions + other.functions, Function::mergeWith),
+ properties = merge(properties + other.properties, Property::mergeWith),
+ classlikes = merge(classlikes + other.classlikes, Classlike::mergeWith),
+ expected = expected?.mergeWith(other.expected),
+ actual = (actual + other.actual).mergeClassPlatformInfo(),
+ entries = (this.entries + other.entries.distinctBy { it.dri }.toList()),
+ constructors = merge(constructors + other.constructors, Function::mergeWith),
+ visibility = visibility
+)
+
+fun Parameter.mergeWith(other: Parameter) = Parameter(
+ dri,
+ name,
+ type,
+ expected?.mergeWith(other.expected),
+ (actual + other.actual).merge()
+)
+
+fun Package.mergeWith(other: Package): Package = Package(
+ dri,
+ merge(functions + other.functions, Function::mergeWith),
+ merge(properties + other.properties, Property::mergeWith),
+ merge(classlikes + other.classlikes, Classlike::mergeWith)
+) \ No newline at end of file