diff options
author | Paweł Marks <pmarks@virtuslab.com> | 2019-11-26 13:44:27 +0100 |
---|---|---|
committer | Paweł Marks <pmarks@virtuslab.com> | 2019-11-26 21:02:20 +0100 |
commit | 49439594f86217d8a25e8df2580b8ef29d836230 (patch) | |
tree | 50dc1b0793c4804b382c6b75fd7a3a0d27cb869a /core/src/main/kotlin/plugability | |
parent | c185e420971950747535e98f96a12e480159dd83 (diff) | |
download | dokka-49439594f86217d8a25e8df2580b8ef29d836230.tar.gz dokka-49439594f86217d8a25e8df2580b8ef29d836230.tar.bz2 dokka-49439594f86217d8a25e8df2580b8ef29d836230.zip |
Introduction of all important extension points and restructuring of DokkaGenerator
Diffstat (limited to 'core/src/main/kotlin/plugability')
-rw-r--r-- | core/src/main/kotlin/plugability/DefaultExtensions.kt | 25 | ||||
-rw-r--r-- | core/src/main/kotlin/plugability/DokkaContext.kt | 61 | ||||
-rw-r--r-- | core/src/main/kotlin/plugability/extensions.kt | 2 |
3 files changed, 65 insertions, 23 deletions
diff --git a/core/src/main/kotlin/plugability/DefaultExtensions.kt b/core/src/main/kotlin/plugability/DefaultExtensions.kt new file mode 100644 index 00000000..dd656386 --- /dev/null +++ b/core/src/main/kotlin/plugability/DefaultExtensions.kt @@ -0,0 +1,25 @@ +package org.jetbrains.dokka.plugability + +import org.jetbrains.dokka.CoreExtensions +import org.jetbrains.dokka.pages.DefaultMarkdownToContentConverter +import org.jetbrains.dokka.renderers.DefaultRenderer +import org.jetbrains.dokka.renderers.HtmlRenderer +import org.jetbrains.dokka.resolvers.DefaultLocationProvider +import org.jetbrains.dokka.transformers.descriptors.DefaultDescriptorToDocumentationTranslator +import org.jetbrains.dokka.transformers.documentation.DefaultDocumentationNodeMerger +import org.jetbrains.dokka.transformers.documentation.DefaultDocumentationToPageTranslator + +object DefaultExtensions : DokkaExtensionHandler { + @Suppress("IMPLICIT_CAST_TO_ANY", "UNCHECKED_CAST") + override fun <T : Any, E : ExtensionPoint<T>> get(point: E, askDefault: AskDefault): List<T> = + when (point) { + CoreExtensions.descriptorToDocumentationTranslator -> DefaultDescriptorToDocumentationTranslator + CoreExtensions.documentationMerger -> DefaultDocumentationNodeMerger + CoreExtensions.markdownToContentConverterFactory -> ::DefaultMarkdownToContentConverter + CoreExtensions.documentationToPageTranslator -> DefaultDocumentationToPageTranslator + CoreExtensions.renderer -> ::HtmlRenderer + CoreExtensions.locationProvider -> ::DefaultLocationProvider + CoreExtensions.fileExtension -> ".html" + else -> null + }.let { listOfNotNull(it) as List<T> } +}
\ No newline at end of file diff --git a/core/src/main/kotlin/plugability/DokkaContext.kt b/core/src/main/kotlin/plugability/DokkaContext.kt index b917ff99..31c56728 100644 --- a/core/src/main/kotlin/plugability/DokkaContext.kt +++ b/core/src/main/kotlin/plugability/DokkaContext.kt @@ -1,23 +1,35 @@ package org.jetbrains.dokka.plugability import org.jetbrains.dokka.DokkaLogger +import org.jetbrains.dokka.EnvironmentAndFacade +import org.jetbrains.dokka.pages.PlatformData import java.io.File import java.net.URLClassLoader import java.util.* import kotlin.reflect.KClass import kotlin.reflect.full.createInstance -interface DokkaContext { - operator fun <T, E> get(point: E, askDefault: AskDefault = AskDefault.WhenEmpty): List<Extension<T>> + +interface DokkaExtensionHandler { + operator fun <T, E> get(point: E, askDefault: AskDefault = AskDefault.WhenEmpty): List<T> where T : Any, E : ExtensionPoint<T> +} + +interface DokkaContext : DokkaExtensionHandler { fun <T : DokkaPlugin> plugin(kclass: KClass<T>): T? val logger: DokkaLogger + val platforms: Map<PlatformData, EnvironmentAndFacade> + companion object { - fun create(pluginsClasspath: Iterable<File>, logger: DokkaLogger): DokkaContext = - DokkaContextConfigurationImpl(logger, DefaultContext(logger)).apply { + fun create( + pluginsClasspath: Iterable<File>, + logger: DokkaLogger, + platforms: Map<PlatformData, EnvironmentAndFacade> + ): DokkaContext = + DokkaContextConfigurationImpl(logger, DefaultExtensions, platforms).apply { pluginsClasspath.map { it.relativeTo(File(".").absoluteFile).toURI().toURL() } .toTypedArray() .let { URLClassLoader(it, this.javaClass.classLoader) } @@ -28,13 +40,27 @@ interface DokkaContext { } } +fun <T, E> DokkaContext.single(point: E): T where T : Any, E : ExtensionPoint<T> { + fun throwBadArity(substitution: String): Nothing = throw IllegalStateException( + "$point was expected to have exactly one extension registered, but $substitution found." + ) + + val extensions = get(point, AskDefault.WhenEmpty) + return when (extensions.size) { + 0 -> throwBadArity("none was") + 1 -> extensions.first() + else -> throwBadArity("multiple were") + } +} + interface DokkaContextConfiguration { fun addExtension(extension: Extension<*>) } private class DokkaContextConfigurationImpl( override val logger: DokkaLogger, - private val defaultContext: DokkaContext? + private val defaultHandler: DokkaExtensionHandler?, + override val platforms: Map<PlatformData, EnvironmentAndFacade> ) : DokkaContext, DokkaContextConfiguration { private val plugins = mutableMapOf<KClass<*>, DokkaPlugin>() @@ -45,15 +71,16 @@ private class DokkaContextConfigurationImpl( @Suppress("UNCHECKED_CAST") override operator fun <T, E> get(point: E, askDefault: AskDefault) where T : Any, E : ExtensionPoint<T> = when (askDefault) { - AskDefault.Never -> extensions[point].orEmpty() - AskDefault.Always -> extensions[point].orEmpty() + defaultContext?.get(point, askDefault).orEmpty() + AskDefault.Never -> actions(point).orEmpty() + AskDefault.Always -> actions(point).orEmpty() + defaultHandler?.get(point, askDefault).orEmpty() AskDefault.WhenEmpty -> - extensions[point]?.takeIf { it.isNotEmpty() } ?: defaultContext?.get(point, askDefault).orEmpty() - } as List<Extension<T>> + actions(point)?.takeIf { it.isNotEmpty() } ?: defaultHandler?.get(point, askDefault).orEmpty() + } as List<T> + + private fun <E : ExtensionPoint<*>> actions(point: E) = extensions[point]?.map { it.action } @Suppress("UNCHECKED_CAST") - override fun <T : DokkaPlugin> plugin(kclass: KClass<T>) = - (plugins[kclass] ?: defaultContext?.plugin(kclass) ?: pluginStubFor(kclass)) as T + override fun <T : DokkaPlugin> plugin(kclass: KClass<T>) = (plugins[kclass] ?: pluginStubFor(kclass)) as T private fun <T : DokkaPlugin> pluginStubFor(kclass: KClass<T>): DokkaPlugin = pluginStubs.getOrPut(kclass) { kclass.createInstance().also { it.context = this } } @@ -69,7 +96,7 @@ private class DokkaContextConfigurationImpl( } fun logInitialisationInfo() { - val pluginNames: List<String> = plugins.values.map { it::class.qualifiedName.toString() } + val pluginNames = plugins.values.map { it::class.qualifiedName.toString() } val loadedListForDebug = extensions.run { keys + values.flatten() }.toList() .joinToString(prefix = "[\n", separator = ",\n", postfix = "\n]") { "\t$it" } @@ -89,16 +116,6 @@ private fun checkClasspath(classLoader: URLClassLoader) { } } -class DefaultContext(override val logger: DokkaLogger) : DokkaContext { - override fun <T : Any, E : ExtensionPoint<T>> get(point: E, askDefault: AskDefault): List<Extension<T>> = - when (point) { - - else -> emptyList() - } - - override fun <T : DokkaPlugin> plugin(kclass: KClass<T>): Nothing? = null -} - enum class AskDefault { Always, Never, WhenEmpty }
\ No newline at end of file diff --git a/core/src/main/kotlin/plugability/extensions.kt b/core/src/main/kotlin/plugability/extensions.kt index c1573e1a..3039cb5a 100644 --- a/core/src/main/kotlin/plugability/extensions.kt +++ b/core/src/main/kotlin/plugability/extensions.kt @@ -11,7 +11,7 @@ class Extension<T : Any> internal constructor( internal val extensionPoint: ExtensionPoint<T>, internal val pluginClass: String, internal val extensionName: String, - internal val action: T, + val action: T, internal val ordering: (OrderDsl.() -> Unit)? = null ) { override fun toString() = "Extension: $pluginClass/$extensionName" |