aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaweł Marks <pmarks@virtuslab.com>2019-11-19 16:54:47 +0100
committerBłażej Kardyś <bkardys@virtuslab.com>2019-11-25 16:24:16 +0100
commit8a057a4611684a6a4616e136d480c005997070cd (patch)
tree47068c1ae3af98ce82a6f66c5eea52aa67d823c6
parent007aacb9ae3b228d0cef45ff5beb066b1dcd4cdc (diff)
downloaddokka-8a057a4611684a6a4616e136d480c005997070cd.tar.gz
dokka-8a057a4611684a6a4616e136d480c005997070cd.tar.bz2
dokka-8a057a4611684a6a4616e136d480c005997070cd.zip
Working extensions in plugins
-rw-r--r--.idea/compiler.xml4
-rw-r--r--core/src/main/kotlin/DokkaGenerator.kt36
-rw-r--r--core/src/main/kotlin/plugability/DokkaContext.kt30
-rw-r--r--core/src/main/kotlin/plugability/DokkaPlugin.kt58
-rw-r--r--core/src/main/kotlin/plugability/extensions.kt52
-rw-r--r--plugins/mathjax/build.gradle6
-rw-r--r--runners/fatjar/build.gradle4
-rw-r--r--settings.gradle3
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'