diff options
Diffstat (limited to 'plugins/base')
-rw-r--r-- | plugins/base/src/main/kotlin/DokkaBase.kt | 5 | ||||
-rw-r--r-- | plugins/base/src/main/kotlin/transformers/documentables/DefaultDocumentableMerger.kt | 116 |
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 |