diff options
author | Paweł Marks <pmarks@virtuslab.com> | 2019-11-19 16:54:47 +0100 |
---|---|---|
committer | Błażej Kardyś <bkardys@virtuslab.com> | 2019-11-25 16:24:16 +0100 |
commit | 8a057a4611684a6a4616e136d480c005997070cd (patch) | |
tree | 47068c1ae3af98ce82a6f66c5eea52aa67d823c6 | |
parent | 007aacb9ae3b228d0cef45ff5beb066b1dcd4cdc (diff) | |
download | dokka-8a057a4611684a6a4616e136d480c005997070cd.tar.gz dokka-8a057a4611684a6a4616e136d480c005997070cd.tar.bz2 dokka-8a057a4611684a6a4616e136d480c005997070cd.zip |
Working extensions in plugins
-rw-r--r-- | .idea/compiler.xml | 4 | ||||
-rw-r--r-- | core/src/main/kotlin/DokkaGenerator.kt | 36 | ||||
-rw-r--r-- | core/src/main/kotlin/plugability/DokkaContext.kt | 30 | ||||
-rw-r--r-- | core/src/main/kotlin/plugability/DokkaPlugin.kt | 58 | ||||
-rw-r--r-- | core/src/main/kotlin/plugability/extensions.kt | 52 | ||||
-rw-r--r-- | plugins/mathjax/build.gradle | 6 | ||||
-rw-r--r-- | runners/fatjar/build.gradle | 4 | ||||
-rw-r--r-- | settings.gradle | 3 |
8 files changed, 159 insertions, 34 deletions
diff --git a/.idea/compiler.xml b/.idea/compiler.xml index e8fe0465..34ea6446 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -44,7 +44,11 @@ <module name="dokka.integration.test" target="1.8" /> <module name="dokka.plugins.javadoc8.main" target="1.8" /> <module name="dokka.plugins.javadoc8.test" target="1.8" /> + <module name="dokka.plugins.ma.main" target="1.8" /> + <module name="dokka.plugins.ma.test" target="1.8" /> <module name="dokka.plugins.main" target="1.8" /> + <module name="dokka.plugins.mathjax.main" target="1.8" /> + <module name="dokka.plugins.mathjax.test" target="1.8" /> <module name="dokka.plugins.test" target="1.8" /> <module name="dokka.runners.android-gradle-plugin.main" target="1.8" /> <module name="dokka.runners.android-gradle-plugin.test" target="1.8" /> diff --git a/core/src/main/kotlin/DokkaGenerator.kt b/core/src/main/kotlin/DokkaGenerator.kt index fb4bf98f..f02f1e87 100644 --- a/core/src/main/kotlin/DokkaGenerator.kt +++ b/core/src/main/kotlin/DokkaGenerator.kt @@ -26,14 +26,8 @@ class DokkaGenerator( logger.debug("Initializing plugins") val context = DokkaContext.from(configuration.pluginsClasspath) - context.pluginNames.also { names -> - logger.progress("Loaded plugins: $names") - names.groupingBy { it }.eachCount().filter { it.value > 1 }.forEach { - logger.warn("Duplicate plugin name: ${it.key}. It will make debugging much harder.") - } - } - - + logger.progress("Loaded plugins: ${context.pluginNames}") + logger.progress("Loaded: ${context.loadedListForDebug}") configuration.passesConfigurations.map { pass -> AnalysisEnvironment(DokkaMessageCollector(logger), pass.analysisPlatform).run { @@ -79,23 +73,23 @@ class DokkaGenerator( ).render(it) } } -} -private fun nierzigoj(niczym: String) {} + private fun nierzigoj(niczym: String) {} -private class DokkaMessageCollector(private val logger: DokkaLogger) : MessageCollector { - override fun clear() { - seenErrors = false - } + private class DokkaMessageCollector(private val logger: DokkaLogger) : MessageCollector { + override fun clear() { + seenErrors = false + } - private var seenErrors = false + private var seenErrors = false - override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation?) { - if (severity == CompilerMessageSeverity.ERROR) { - seenErrors = true + override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation?) { + if (severity == CompilerMessageSeverity.ERROR) { + seenErrors = true + } + logger.error(MessageRenderer.PLAIN_FULL_PATHS.render(severity, message, location)) } - logger.error(MessageRenderer.PLAIN_FULL_PATHS.render(severity, message, location)) - } - override fun hasErrors() = seenErrors + override fun hasErrors() = seenErrors + } }
\ 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 b54d8ed0..d67f34b1 100644 --- a/core/src/main/kotlin/plugability/DokkaContext.kt +++ b/core/src/main/kotlin/plugability/DokkaContext.kt @@ -3,17 +3,27 @@ package org.jetbrains.dokka.plugability import java.io.File import java.net.URLClassLoader import java.util.* +import kotlin.reflect.KClass class DokkaContext private constructor() { - private val plugins = mutableListOf<DokkaPlugin>() + private val plugins = mutableMapOf<KClass<*>, DokkaPlugin>() + + internal val extensions = mutableMapOf<ExtensionPoint<*>, MutableList<Extension<*>>>() + + @PublishedApi + internal fun plugin(kclass: KClass<*>) = plugins[kclass] val pluginNames: List<String> - get() = plugins.map { it.name } + get() = plugins.values.map { it::class.qualifiedName.toString() } + + val loadedListForDebug + get() = extensions.run { keys + values.flatten() }.toList() + .joinToString(prefix = "[\n", separator = ",\n", postfix = "\n]") { "\t$it" } private fun install(plugin: DokkaPlugin) { - plugins += plugin - plugin.install(this) + plugins[plugin::class] = plugin + plugin.internalInstall(this) } companion object { @@ -28,9 +38,15 @@ class DokkaContext private constructor() { } private fun checkClasspath(classLoader: URLClassLoader) { - classLoader.findResource(javaClass.name.replace('.','/') + ".class")?.also { - throw AssertionError("Dokka API found on plugins classpath. This will lead to subtle bugs. " + - "Please fix your plugins dependencies or exclude dokka api artifact from plugin classpath") + classLoader.findResource(javaClass.name.replace('.', '/') + ".class")?.also { + throw AssertionError( + "Dokka API found on plugins classpath. This will lead to subtle bugs. " + + "Please fix your plugins dependencies or exclude dokka api artifact from plugin classpath" + ) } } + + internal fun addExtension(it: Extension<*>) { + extensions.getOrPut(it.extensionPoint, ::mutableListOf) += it + } } diff --git a/core/src/main/kotlin/plugability/DokkaPlugin.kt b/core/src/main/kotlin/plugability/DokkaPlugin.kt index 2654bcee..60ca245c 100644 --- a/core/src/main/kotlin/plugability/DokkaPlugin.kt +++ b/core/src/main/kotlin/plugability/DokkaPlugin.kt @@ -1,6 +1,58 @@ package org.jetbrains.dokka.plugability -interface DokkaPlugin { - val name: String - fun install(context: DokkaContext) +import kotlin.properties.ReadOnlyProperty +import kotlin.reflect.KProperty +import kotlin.reflect.KProperty1 +import kotlin.reflect.KTypeProjection +import kotlin.reflect.full.createInstance +import kotlin.reflect.full.createType +import kotlin.reflect.full.declaredMemberProperties +import kotlin.reflect.jvm.isAccessible +import kotlin.reflect.jvm.jvmErasure + +private typealias ExtensionDelegate<T> = ReadOnlyProperty<DokkaPlugin, Extension<T>> + +abstract class DokkaPlugin { + private val extensionDelegates = mutableListOf<KProperty<*>>() + + @PublishedApi + internal var context: DokkaContext? = null + + protected open fun install(context: DokkaContext) {} + + protected inline fun <reified T : DokkaPlugin> plugin(): T = + context?.plugin(T::class) as? T ?: T::class.createInstance().also { it.context = this.context } + + protected fun <T : Any> extensionPoint() = + object : ReadOnlyProperty<DokkaPlugin, ExtensionPoint<T>> { + override fun getValue(thisRef: DokkaPlugin, property: KProperty<*>) = ExtensionPoint<T>( + thisRef::class.qualifiedName ?: throw AssertionError("Plugin must be named class"), + property.name + ) + } + + protected fun <T: Any> extending(definition: ExtendingDSL.() -> Extension<T>) = ExtensionProvider(definition) + + protected class ExtensionProvider<T: Any> internal constructor( + private val definition: ExtendingDSL.() -> Extension<T> + ) { + operator fun provideDelegate(thisRef: DokkaPlugin, property: KProperty<*>) = lazy { + ExtendingDSL( + thisRef::class.qualifiedName ?: throw AssertionError("Plugin must be named class"), + property.name + ).definition() + }.also { thisRef.extensionDelegates += property } + } + + internal fun internalInstall(ctx: DokkaContext) { + context = ctx + install(ctx) + + extensionDelegates.asSequence() + .filterIsInstance<KProperty1<DokkaPlugin, Extension<*>>>() // always true + .map { it.get(this) } + .forEach { ctx.addExtension(it) } + } + + }
\ No newline at end of file diff --git a/core/src/main/kotlin/plugability/extensions.kt b/core/src/main/kotlin/plugability/extensions.kt new file mode 100644 index 00000000..c1573e1a --- /dev/null +++ b/core/src/main/kotlin/plugability/extensions.kt @@ -0,0 +1,52 @@ +package org.jetbrains.dokka.plugability + +data class ExtensionPoint<T : Any> internal constructor( + internal val pluginClass: String, + internal val pointName: String +) { + override fun toString() = "ExtensionPoint: $pluginClass/$pointName" +} + +class Extension<T : Any> internal constructor( + internal val extensionPoint: ExtensionPoint<T>, + internal val pluginClass: String, + internal val extensionName: String, + internal val action: T, + internal val ordering: (OrderDsl.() -> Unit)? = null +) { + override fun toString() = "Extension: $pluginClass/$extensionName" + + override fun equals(other: Any?) = + if (other is Extension<*>) this.pluginClass == other.extensionName && this.extensionName == other.extensionName + else false + + override fun hashCode() = listOf(pluginClass, extensionName).hashCode() +} + +internal data class Ordering(val previous: Set<Extension<*>>, val following: Set<Extension<*>>) + +@DslMarker +annotation class ExtensionsDsl + +@ExtensionsDsl +class ExtendingDSL(private val pluginClass: String, private val extensionName: String) { + infix fun <T: Any> ExtensionPoint<T>.with(action: T) = + Extension(this, this@ExtendingDSL.pluginClass, extensionName, action) + + infix fun <T: Any> Extension<T>.order(block: OrderDsl.() -> Unit) = + Extension(extensionPoint, pluginClass, extensionName, action, block) +} + +@ExtensionsDsl +class OrderDsl { + private val previous = mutableSetOf<Extension<*>>() + private val following = mutableSetOf<Extension<*>>() + + fun after(vararg extensions: Extension<*>) { + previous += extensions + } + + fun before(vararg extensions: Extension<*>) { + following += extensions + } +}
\ No newline at end of file diff --git a/plugins/mathjax/build.gradle b/plugins/mathjax/build.gradle new file mode 100644 index 00000000..a4a59c50 --- /dev/null +++ b/plugins/mathjax/build.gradle @@ -0,0 +1,6 @@ +import javax.tools.ToolProvider + + +dependencies { + compileOnly project(':core') +}
\ No newline at end of file diff --git a/runners/fatjar/build.gradle b/runners/fatjar/build.gradle index 1da23841..cab64c0f 100644 --- a/runners/fatjar/build.gradle +++ b/runners/fatjar/build.gradle @@ -33,7 +33,7 @@ shadowJar { exclude 'src/**' - relocate('kotlin.reflect.full', 'kotlin.reflect') +// relocate('kotlin.reflect.full', 'kotlin.reflect') } task apiShadow(type: ShadowJar) { @@ -56,7 +56,7 @@ task apiShadow(type: ShadowJar) { exclude 'src/**' - relocate('kotlin.reflect.full', 'kotlin.reflect') +// relocate('kotlin.reflect.full', 'kotlin.reflect') } apply plugin: 'maven-publish' diff --git a/settings.gradle b/settings.gradle index c793bd79..0447a904 100644 --- a/settings.gradle +++ b/settings.gradle @@ -9,5 +9,6 @@ include 'core', 'runners:ant', 'runners:cli', // 'runners:maven-plugin', - 'runners:gradle-plugin' + 'runners:gradle-plugin', // 'plugins:javadoc8' + 'plugins:mathjax' |