diff options
author | Paweł Marks <pmarks@virtuslab.com> | 2020-06-30 21:05:16 +0200 |
---|---|---|
committer | Paweł Marks <Kordyjan@users.noreply.github.com> | 2020-07-07 10:07:21 +0200 |
commit | 9b7e163ae69272c7e56088d6f256d6b19f9a01d4 (patch) | |
tree | 333c56d610ae7e612d9f49d579e4931f7e8f9863 | |
parent | 33cf9d62f409dd5d98678fdcd29227763af11586 (diff) | |
download | dokka-9b7e163ae69272c7e56088d6f256d6b19f9a01d4.tar.gz dokka-9b7e163ae69272c7e56088d6f256d6b19f9a01d4.tar.bz2 dokka-9b7e163ae69272c7e56088d6f256d6b19f9a01d4.zip |
Refactor Extension DSL and remove fallback mechanism
-rw-r--r-- | core/src/main/kotlin/plugability/DokkaContext.kt | 33 | ||||
-rw-r--r-- | core/src/main/kotlin/plugability/DokkaPlugin.kt | 17 | ||||
-rw-r--r-- | core/src/main/kotlin/plugability/extensions.kt | 101 | ||||
-rw-r--r-- | plugins/base/src/main/kotlin/DokkaBase.kt | 24 |
4 files changed, 68 insertions, 107 deletions
diff --git a/core/src/main/kotlin/plugability/DokkaContext.kt b/core/src/main/kotlin/plugability/DokkaContext.kt index 15349ff0..12b1557b 100644 --- a/core/src/main/kotlin/plugability/DokkaContext.kt +++ b/core/src/main/kotlin/plugability/DokkaContext.kt @@ -46,7 +46,7 @@ inline fun <reified T : DokkaPlugin> DokkaContext.plugin(): T = plugin(T::class) ?: throw java.lang.IllegalStateException("Plugin ${T::class.qualifiedName} is not present in context.") interface DokkaContextConfiguration { - fun addExtensionDependencies(extension: Extension<*>) + fun addExtensionDependencies(extension: Extension<*, *, *>) } private class DokkaContextConfigurationImpl( @@ -55,7 +55,7 @@ private class DokkaContextConfigurationImpl( ) : DokkaContext, DokkaContextConfiguration { private val plugins = mutableMapOf<KClass<*>, DokkaPlugin>() private val pluginStubs = mutableMapOf<KClass<*>, DokkaPlugin>() - internal val extensions = mutableMapOf<ExtensionPoint<*>, MutableList<Extension<*>>>() + val extensions = mutableMapOf<ExtensionPoint<*>, MutableList<Extension<*, *, *>>>() val pointsUsed: MutableSet<ExtensionPoint<*>> = mutableSetOf() val pointsPopulated: MutableSet<ExtensionPoint<*>> = mutableSetOf() override val unusedPoints: Set<ExtensionPoint<*>> @@ -67,14 +67,14 @@ private class DokkaContextConfigurationImpl( VISITED; } - internal val verticesWithState = mutableMapOf<Extension<*>, State>() - internal val adjacencyList: MutableMap<Extension<*>, MutableList<Extension<*>>> = mutableMapOf() + val verticesWithState = mutableMapOf<Extension<*, *, *>, State>() + val adjacencyList: MutableMap<Extension<*, *, *>, MutableList<Extension<*, *, *>>> = mutableMapOf() private fun topologicalSort() { - val result: MutableList<Extension<*>> = mutableListOf() + val result: MutableList<Extension<*, *, *>> = mutableListOf() - fun visit(n: Extension<*>) { + fun visit(n: Extension<*, *, *>) { val state = verticesWithState[n] if (state == State.VISITED) return @@ -107,14 +107,11 @@ private class DokkaContextConfigurationImpl( ) pointsUsed += point - val extensions = extensions[point].orEmpty() as List<Extension<T>> + val extensions = extensions[point].orEmpty() as List<Extension<T, *, *>> return when (extensions.size) { 0 -> throwBadArity("none was") 1 -> extensions.single().action.get(this) - else -> { - val notFallbacks = extensions.filterNot { it.isFallback } - if (notFallbacks.size == 1) notFallbacks.single().action.get(this) else throwBadArity("many were") - } + else -> throwBadArity("many were") } } @@ -132,13 +129,15 @@ private class DokkaContextConfigurationImpl( plugin.internalInstall(this, this.configuration) } - override fun addExtensionDependencies(extension: Extension<*>) { - val orderDsl = OrderDsl() - extension.ordering?.invoke(orderDsl) + override fun addExtensionDependencies(extension: Extension<*, *, *>) { + if (extension.ordering is OrderingKind.ByDsl) { + val orderDsl = OrderDsl() + extension.ordering.block.invoke(orderDsl) - verticesWithState += extension to State.UNVISITED - adjacencyList.getOrPut(extension, ::mutableListOf) += orderDsl.following.toList() - orderDsl.previous.forEach { adjacencyList.getOrPut(it, ::mutableListOf) += extension } + verticesWithState += extension to State.UNVISITED + adjacencyList.getOrPut(extension, ::mutableListOf) += orderDsl.following.toList() + orderDsl.previous.forEach { adjacencyList.getOrPut(it, ::mutableListOf) += extension } + } } fun logInitialisationInfo() { diff --git a/core/src/main/kotlin/plugability/DokkaPlugin.kt b/core/src/main/kotlin/plugability/DokkaPlugin.kt index 7ead43b8..bf82daa7 100644 --- a/core/src/main/kotlin/plugability/DokkaPlugin.kt +++ b/core/src/main/kotlin/plugability/DokkaPlugin.kt @@ -7,8 +7,6 @@ import kotlin.reflect.KProperty import kotlin.reflect.KProperty1 import kotlin.reflect.full.createInstance -private typealias ExtensionDelegate<T> = ReadOnlyProperty<DokkaPlugin, Extension<T>> - abstract class DokkaPlugin { private val extensionDelegates = mutableListOf<KProperty<*>>() @@ -25,15 +23,10 @@ abstract class DokkaPlugin { ) } - protected fun <T : Any> extending(isFallback: Boolean = false, definition: ExtendingDSL.() -> Extension<T>) = - if (isFallback) { - ExtensionProvider { definition().markedAsFallback() } - } else { - ExtensionProvider(definition) - } + protected fun <T : Any> extending(definition: ExtendingDSL.() -> Extension<T, *, *>) = ExtensionProvider(definition) protected class ExtensionProvider<T : Any> internal constructor( - private val definition: ExtendingDSL.() -> Extension<T> + private val definition: ExtendingDSL.() -> Extension<T, *, *> ) { operator fun provideDelegate(thisRef: DokkaPlugin, property: KProperty<*>) = lazy { ExtendingDSL( @@ -45,7 +38,7 @@ abstract class DokkaPlugin { internal fun internalInstall(ctx: DokkaContextConfiguration, configuration: DokkaConfiguration) { extensionDelegates.asSequence() - .filterIsInstance<KProperty1<DokkaPlugin, Extension<*>>>() // should be always true + .filterIsInstance<KProperty1<DokkaPlugin, Extension<*, *, *>>>() // should be always true .map { it.get(this) } .forEach { if (it.condition.invoke(configuration)) ctx.addExtensionDependencies(it) } } @@ -76,8 +69,8 @@ fun throwIllegalQuery(): Nothing = inline fun <reified T : DokkaPlugin, reified R : ConfigurableBlock> configuration(context: DokkaContext): ReadOnlyProperty<Any?, R> { return object : ReadOnlyProperty<Any?, R> { override fun getValue(thisRef: Any?, property: KProperty<*>): R { - return context.configuration.pluginsConfiguration.get(T::class.qualifiedName - ?: throw AssertionError("Plugin must be named class")).let { + return context.configuration.pluginsConfiguration[T::class.qualifiedName + ?: throw AssertionError("Plugin must be named class")].let { Gson().fromJson(it, R::class.java) } } diff --git a/core/src/main/kotlin/plugability/extensions.kt b/core/src/main/kotlin/plugability/extensions.kt index 20b60469..c6dd0b85 100644 --- a/core/src/main/kotlin/plugability/extensions.kt +++ b/core/src/main/kotlin/plugability/extensions.kt @@ -9,79 +9,43 @@ data class ExtensionPoint<T : Any> internal constructor( override fun toString() = "ExtensionPoint: $pluginClass/$pointName" } -abstract class Extension<T : Any> internal constructor( +sealed class OrderingKind { + object None : OrderingKind() + class ByDsl(val block: (OrderDsl.() -> Unit)) : OrderingKind() +} + +sealed class OverrideKind { + object None : OverrideKind() + class Present(val overriden: Extension<*, *, *>) : OverrideKind() +} + +class Extension<T : Any, Ordering : OrderingKind, Override : OverrideKind> internal constructor( internal val extensionPoint: ExtensionPoint<T>, internal val pluginClass: String, internal val extensionName: String, internal val action: LazyEvaluated<T>, - internal val ordering: (OrderDsl.() -> Unit)? = null, - internal val conditions: Array<DokkaConfiguration.() -> Boolean> = emptyArray(), - internal val isFallback: Boolean + internal val ordering: Ordering, + internal val override: Override, + internal val conditions: List<DokkaConfiguration.() -> Boolean> ) { override fun toString() = "Extension: $pluginClass/$extensionName" override fun equals(other: Any?) = - if (other is Extension<*>) this.pluginClass == other.pluginClass && this.extensionName == other.extensionName + if (other is Extension<*, *, *>) this.pluginClass == other.pluginClass && this.extensionName == other.extensionName else false override fun hashCode() = listOf(pluginClass, extensionName).hashCode() - abstract fun addCondition(condition: (DokkaConfiguration.() -> Boolean)): Extension<T> - - abstract fun markedAsFallback(): Extension<T> - - open val condition: DokkaConfiguration.() -> Boolean - get() = { conditions.all { it(this) }} + val condition: DokkaConfiguration.() -> Boolean + get() = { conditions.all { it(this) } } } -class ExtensionOrdered<T : Any> internal constructor( +private fun <T : Any> Extension( extensionPoint: ExtensionPoint<T>, pluginClass: String, extensionName: String, - action: LazyEvaluated<T>, - ordering: (OrderDsl.() -> Unit), - conditions: Array<DokkaConfiguration.() -> Boolean> = emptyArray(), - isFallback: Boolean = false -) : Extension<T>( - extensionPoint, - pluginClass, - extensionName, - action, - ordering, - conditions, - isFallback -) { - override fun addCondition(condition: DokkaConfiguration.() -> Boolean) = - ExtensionOrdered(extensionPoint, pluginClass, extensionName, action, ordering!!, conditions + condition) - - override fun markedAsFallback() = - ExtensionOrdered(extensionPoint, pluginClass, extensionName, action, ordering!!, conditions, true) -} - -class ExtensionUnordered<T : Any> internal constructor( - extensionPoint: ExtensionPoint<T>, - pluginClass: String, - extensionName: String, - action: LazyEvaluated<T>, - conditions: Array<DokkaConfiguration.() -> Boolean> = emptyArray(), - isFallback: Boolean = false -) : Extension<T>( - extensionPoint, - pluginClass, - extensionName, - action, - null, - conditions, - isFallback -) { - override fun addCondition(condition: DokkaConfiguration.() -> Boolean) = - ExtensionUnordered(extensionPoint, pluginClass, extensionName, action, conditions + condition) - - override fun markedAsFallback() = - ExtensionUnordered(extensionPoint, pluginClass, extensionName, action, conditions, true) -} - -internal data class Ordering(val previous: Set<Extension<*>>, val following: Set<Extension<*>>) + action: LazyEvaluated<T> +) = Extension(extensionPoint, pluginClass, extensionName, action, OrderingKind.None, OverrideKind.None, emptyList()) @DslMarker annotation class ExtensionsDsl @@ -90,29 +54,34 @@ annotation class ExtensionsDsl class ExtendingDSL(private val pluginClass: String, private val extensionName: String) { infix fun <T : Any> ExtensionPoint<T>.with(action: T) = - ExtensionUnordered(this, this@ExtendingDSL.pluginClass, extensionName, LazyEvaluated.fromInstance(action)) + Extension(this, this@ExtendingDSL.pluginClass, extensionName, LazyEvaluated.fromInstance(action)) infix fun <T : Any> ExtensionPoint<T>.providing(action: (DokkaContext) -> T) = - ExtensionUnordered(this, this@ExtendingDSL.pluginClass, extensionName, LazyEvaluated.fromRecipe(action)) + Extension(this, this@ExtendingDSL.pluginClass, extensionName, LazyEvaluated.fromRecipe(action)) - infix fun <T : Any> ExtensionUnordered<T>.order(block: OrderDsl.() -> Unit) = - ExtensionOrdered(extensionPoint, pluginClass, extensionName, action, block) + infix fun <T : Any, Override : OverrideKind> Extension<T, OrderingKind.None, Override>.order( + block: OrderDsl.() -> Unit + ) = Extension(extensionPoint, pluginClass, extensionName, action, OrderingKind.ByDsl(block), override, conditions) - infix fun <T : Any> Extension<T>.applyIf(condition: DokkaConfiguration.() -> Boolean): Extension<T> = - this.addCondition(condition) + infix fun <T : Any, Override : OverrideKind, Ordering: OrderingKind> Extension<T, Ordering, Override>.applyIf( + condition: DokkaConfiguration.() -> Boolean + ) = Extension(extensionPoint, pluginClass, extensionName, action, ordering, override, conditions + condition) + infix fun <T : Any, Override : OverrideKind, Ordering: OrderingKind> Extension<T, Ordering, Override>.override( + overriden: Extension<T, *, *> + ) = Extension(extensionPoint, pluginClass, extensionName, action, ordering, OverrideKind.Present(overriden), conditions) } @ExtensionsDsl class OrderDsl { - internal val previous = mutableSetOf<Extension<*>>() - internal val following = mutableSetOf<Extension<*>>() + internal val previous = mutableSetOf<Extension<*, *, *>>() + internal val following = mutableSetOf<Extension<*, *, *>>() - fun after(vararg extensions: Extension<*>) { + fun after(vararg extensions: Extension<*, *, *>) { previous += extensions } - fun before(vararg extensions: Extension<*>) { + fun before(vararg extensions: Extension<*, *, *>) { following += extensions } }
\ No newline at end of file diff --git a/plugins/base/src/main/kotlin/DokkaBase.kt b/plugins/base/src/main/kotlin/DokkaBase.kt index 0e535c86..8fed0afd 100644 --- a/plugins/base/src/main/kotlin/DokkaBase.kt +++ b/plugins/base/src/main/kotlin/DokkaBase.kt @@ -55,19 +55,19 @@ class DokkaBase : DokkaPlugin() { } } - val documentableMerger by extending(isFallback = true) { + val documentableMerger by extending { CoreExtensions.documentableMerger with DefaultDocumentableMerger } - val deprecatedDocumentableFilter by extending(isFallback = true) { + val deprecatedDocumentableFilter by extending { CoreExtensions.preMergeDocumentableTransformer providing ::DeprecatedDocumentableFilterTransformer } - val documentableVisbilityFilter by extending(isFallback = true) { + val documentableVisbilityFilter by extending { CoreExtensions.preMergeDocumentableTransformer providing ::DocumentableVisibilityFilterTransformer } - val emptyPackagesFilter by extending(isFallback = true) { + val emptyPackagesFilter by extending { CoreExtensions.preMergeDocumentableTransformer providing ::EmptyPackagesFilterTransformer order { after(deprecatedDocumentableFilter, documentableVisbilityFilter) } @@ -77,13 +77,13 @@ class DokkaBase : DokkaPlugin() { CoreExtensions.documentableTransformer with ActualTypealiasAdder() } - val modulesAndPackagesDocumentation by extending(isFallback = true) { + val modulesAndPackagesDocumentation by extending { CoreExtensions.preMergeDocumentableTransformer providing { ctx -> ModuleAndPackageDocumentationTransformer(ctx, ctx.single(kotlinAnalysis)) } } - val kotlinSignatureProvider by extending(isFallback = true) { + val kotlinSignatureProvider by extending { signatureProvider providing { ctx -> KotlinSignatureProvider(ctx.single(commentsToContentConverter), ctx.logger) } @@ -106,7 +106,7 @@ class DokkaBase : DokkaPlugin() { CoreExtensions.documentableTransformer with ExtensionExtractorTransformer() } - val documentableToPageTranslator by extending(isFallback = true) { + val documentableToPageTranslator by extending { CoreExtensions.documentableToPageTranslator providing { ctx -> DefaultDocumentableToPageTranslator( ctx.single(commentsToContentConverter), @@ -116,7 +116,7 @@ class DokkaBase : DokkaPlugin() { } } - val docTagToContentConverter by extending(isFallback = true) { + val docTagToContentConverter by extending { commentsToContentConverter with DocTagToContentConverter } @@ -138,11 +138,11 @@ class DokkaBase : DokkaPlugin() { CoreExtensions.renderer providing ::HtmlRenderer applyIf { format == "html" } } - val defaultKotlinAnalysis by extending(isFallback = true) { + val defaultKotlinAnalysis by extending { kotlinAnalysis providing { ctx -> KotlinAnalysis(ctx) } } - val locationProvider by extending(isFallback = true) { + val locationProvider by extending { locationProviderFactory providing ::DefaultLocationProviderFactory } @@ -154,7 +154,7 @@ class DokkaBase : DokkaPlugin() { externalLocationProviderFactory with DokkaExternalLocationProviderFactory() } - val fileWriter by extending(isFallback = true) { + val fileWriter by extending { outputWriter providing ::FileWriter } @@ -211,7 +211,7 @@ class DokkaBase : DokkaPlugin() { htmlPreprocessors providing ::SourcesetDependencyAppender order { after(rootCreator) } } - val allModulePageCreators by extending(isFallback = true) { + val allModulePageCreators by extending { CoreExtensions.allModulePageCreator providing { MultimodulePageCreator(it) } |