package org.jetbrains.dokka.plugability import org.jetbrains.dokka.DokkaConfiguration data class ExtensionPoint internal constructor( internal val pluginClass: String, internal val pointName: String ) { override fun toString() = "ExtensionPoint: $pluginClass/$pointName" } abstract class Extension internal constructor( internal val extensionPoint: ExtensionPoint, internal val pluginClass: String, internal val extensionName: String, internal val action: LazyEvaluated, internal val ordering: (OrderDsl.() -> Unit)? = null, internal val condition: DokkaConfiguration.() -> Boolean = { true } ) { override fun toString() = "Extension: $pluginClass/$extensionName" override fun equals(other: Any?) = if (other is Extension<*>) this.pluginClass == other.pluginClass && this.extensionName == other.extensionName else false override fun hashCode() = listOf(pluginClass, extensionName).hashCode() abstract fun setCondition(condition: (DokkaConfiguration.() -> Boolean)): Extension } class ExtensionOrdered internal constructor( extensionPoint: ExtensionPoint, pluginClass: String, extensionName: String, action: LazyEvaluated, ordering: (OrderDsl.() -> Unit), condition: DokkaConfiguration.() -> Boolean = { true } ) : Extension( extensionPoint, pluginClass, extensionName, action, ordering, condition ) { override fun setCondition(condition: DokkaConfiguration.() -> Boolean) = ExtensionOrdered(extensionPoint, pluginClass, extensionName, action, ordering!!, condition) } class ExtensionUnordered internal constructor( extensionPoint: ExtensionPoint, pluginClass: String, extensionName: String, action: LazyEvaluated, condition: DokkaConfiguration.() -> Boolean = { true } ) : Extension( extensionPoint, pluginClass, extensionName, action, null, condition ) { override fun setCondition(condition: DokkaConfiguration.() -> Boolean) = ExtensionUnordered(extensionPoint, pluginClass, extensionName, action, condition) } internal data class Ordering(val previous: Set>, val following: Set>) @DslMarker annotation class ExtensionsDsl @ExtensionsDsl class ExtendingDSL(private val pluginClass: String, private val extensionName: String) { infix fun ExtensionPoint.with(action: T) = ExtensionUnordered(this, this@ExtendingDSL.pluginClass, extensionName, LazyEvaluated.fromInstance(action)) infix fun ExtensionPoint.providing(action: (DokkaContext) -> T) = ExtensionUnordered(this, this@ExtendingDSL.pluginClass, extensionName, LazyEvaluated.fromRecipe(action)) infix fun ExtensionUnordered.order(block: OrderDsl.() -> Unit) = ExtensionOrdered(extensionPoint, pluginClass, extensionName, action, block) infix fun Extension.applyIf(condition: DokkaConfiguration.() -> Boolean): Extension = this.setCondition(condition) } @ExtensionsDsl class OrderDsl { internal val previous = mutableSetOf>() internal val following = mutableSetOf>() fun after(vararg extensions: Extension<*>) { previous += extensions } fun before(vararg extensions: Extension<*>) { following += extensions } }