model.properties.PropertyContainer.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dokka-core Show documentation
Show all versions of dokka-core Show documentation
Dokka is an API documentation engine for Kotlin and Java, performing the same function as Javadoc for Java
package org.jetbrains.dokka.model.properties
data class PropertyContainer internal constructor(
@PublishedApi internal val map: Map, ExtraProperty>
) {
operator fun plus(prop: ExtraProperty): PropertyContainer =
PropertyContainer(map + (prop.key to prop))
// TODO: Add logic for caching calculated properties
inline operator fun get(key: ExtraProperty.Key): T? = when (val prop = map[key]) {
is T? -> prop
else -> throw ClassCastException("Property for $key stored under not matching key type.")
}
inline fun allOfType(): List = map.values.filterIsInstance()
fun addAll(extras: Collection>): PropertyContainer =
PropertyContainer(map + extras.map { p -> p.key to p })
operator fun minus(prop: ExtraProperty.Key): PropertyContainer =
PropertyContainer(map.filterNot { it.key == prop })
companion object {
fun empty(): PropertyContainer = PropertyContainer(emptyMap())
fun withAll(vararg extras: ExtraProperty?) = empty().addAll(extras.filterNotNull())
fun withAll(extras: Collection>) = empty().addAll(extras)
}
}
operator fun PropertyContainer.plus(prop: ExtraProperty?): PropertyContainer =
if (prop == null) this else PropertyContainer(map + (prop.key to prop))
interface WithExtraProperties {
val extra: PropertyContainer
fun withNewExtras(newExtras: PropertyContainer): C
}
fun C.mergeExtras(left: C, right: C): C where C : Any, C : WithExtraProperties {
val aggregatedExtras: List>> =
(left.extra.map.values + right.extra.map.values)
.groupBy { it.key }
.values
.map { it.distinct() }
val (unambiguous, toMerge) = aggregatedExtras.partition { it.size == 1 }
@Suppress("UNCHECKED_CAST")
val strategies: List> = toMerge.map { (l, r) ->
(l.key as ExtraProperty.Key>).mergeStrategyFor(l, r)
}
strategies.filterIsInstance().firstOrNull()?.error?.invoke()
val replaces: List> =
strategies.filterIsInstance>().map { it.newProperty }
val needingFullMerge: List<(preMerged: C, left: C, right: C) -> C> =
strategies.filterIsInstance>().map { it.merger }
val newExtras = PropertyContainer((unambiguous.flatten() + replaces).associateBy { it.key })
return needingFullMerge.fold(withNewExtras(newExtras)) { acc, merger -> merger(acc, left, right) }
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy