All Downloads are FREE. Search and download functionalities are using the official Maven repository.

model.properties.PropertyContainer.kt Maven / Gradle / Ivy

Go to download

Dokka is an API documentation engine for Kotlin and Java, performing the same function as Javadoc for Java

There is a newer version: 2.0.0
Show newest version
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