From e99be615ce7c2c2b5c3ee5e3f8941c41c1e7a944 Mon Sep 17 00:00:00 2001 From: Kamil Doległo Date: Fri, 31 Jan 2020 00:37:29 +0100 Subject: Bump Gradle version, migrate to Kotlin DSL, refactor publishing --- core/src/main/kotlin/DokkaBootstrap.kt | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 core/src/main/kotlin/DokkaBootstrap.kt (limited to 'core/src/main/kotlin/DokkaBootstrap.kt') diff --git a/core/src/main/kotlin/DokkaBootstrap.kt b/core/src/main/kotlin/DokkaBootstrap.kt new file mode 100644 index 00000000..b78eb9c6 --- /dev/null +++ b/core/src/main/kotlin/DokkaBootstrap.kt @@ -0,0 +1,10 @@ +package org.jetbrains.dokka + +import java.util.function.BiConsumer + +interface DokkaBootstrap { + + fun configure(logger: BiConsumer, serializedConfigurationJSON: String) + + fun generate() +} \ No newline at end of file -- cgit From bb942786909961443eb1ff7feee90c190040ed49 Mon Sep 17 00:00:00 2001 From: "sebastian.sellmair" Date: Thu, 9 Jul 2020 11:04:34 +0200 Subject: Refactor dokka tasks classpath configuration --- core/src/main/kotlin/DokkaBootstrap.kt | 6 +- core/src/main/kotlin/DokkaBootstrapImpl.kt | 22 ++--- .../main/kotlin/DokkaMultimoduleBootstrapImpl.kt | 7 +- .../dokka/gradle/DokkaBootstrapFactory.kt | 18 +++++ .../jetbrains/dokka/gradle/DokkaMultimoduleTask.kt | 70 +++++++--------- .../kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt | 78 ++++++++---------- .../main/kotlin/org/jetbrains/dokka/gradle/main.kt | 94 ++++------------------ 7 files changed, 114 insertions(+), 181 deletions(-) create mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaBootstrapFactory.kt (limited to 'core/src/main/kotlin/DokkaBootstrap.kt') diff --git a/core/src/main/kotlin/DokkaBootstrap.kt b/core/src/main/kotlin/DokkaBootstrap.kt index b78eb9c6..ffaae03e 100644 --- a/core/src/main/kotlin/DokkaBootstrap.kt +++ b/core/src/main/kotlin/DokkaBootstrap.kt @@ -3,8 +3,6 @@ package org.jetbrains.dokka import java.util.function.BiConsumer interface DokkaBootstrap { - - fun configure(logger: BiConsumer, serializedConfigurationJSON: String) - + fun configure(serializedConfigurationJSON: String, logger: BiConsumer) fun generate() -} \ No newline at end of file +} diff --git a/core/src/main/kotlin/DokkaBootstrapImpl.kt b/core/src/main/kotlin/DokkaBootstrapImpl.kt index be3d6c9b..936fbe6c 100644 --- a/core/src/main/kotlin/DokkaBootstrapImpl.kt +++ b/core/src/main/kotlin/DokkaBootstrapImpl.kt @@ -37,6 +37,10 @@ fun parsePerPackageOptions(args: List): List = args.map } +/** + * Accessed with reflection + */ +@Suppress("unused") class DokkaBootstrapImpl : DokkaBootstrap { class DokkaProxyLogger(val consumer: BiConsumer) : DokkaLogger { @@ -95,20 +99,18 @@ class DokkaBootstrapImpl : DokkaBootstrap { return links } - val configurationWithLinks = - configuration.copy( - sourceSets = - sourceSets.map { - val links: List = - it.externalDocumentationLinks + defaultLinks(it) - it.copy(externalDocumentationLinks = links) - } - ) + val configurationWithLinks = configuration.copy( + sourceSets = sourceSets.map { + val links: List = + it.externalDocumentationLinks + defaultLinks(it) + it.copy(externalDocumentationLinks = links) + } + ) generator = DokkaGenerator(configurationWithLinks, logger) } - override fun configure(logger: BiConsumer, serializedConfigurationJSON: String) = configure( + override fun configure(serializedConfigurationJSON: String, logger: BiConsumer) = configure( DokkaProxyLogger(logger), DokkaConfigurationImpl(serializedConfigurationJSON) ) diff --git a/core/src/main/kotlin/DokkaMultimoduleBootstrapImpl.kt b/core/src/main/kotlin/DokkaMultimoduleBootstrapImpl.kt index 70b99f8d..c0726584 100644 --- a/core/src/main/kotlin/DokkaMultimoduleBootstrapImpl.kt +++ b/core/src/main/kotlin/DokkaMultimoduleBootstrapImpl.kt @@ -1,3 +1,8 @@ +/** + * Accessed with reflection + */ +@file:Suppress("unused") + package org.jetbrains.dokka import org.jetbrains.dokka.DokkaBootstrapImpl.DokkaProxyLogger @@ -12,7 +17,7 @@ class DokkaMultimoduleBootstrapImpl : DokkaBootstrap { generator = DokkaGenerator(configuration, logger) } - override fun configure(logger: BiConsumer, serializedConfigurationJSON: String) = configure( + override fun configure(serializedConfigurationJSON: String, logger: BiConsumer) = configure( DokkaProxyLogger(logger), DokkaConfigurationImpl(serializedConfigurationJSON) ) diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaBootstrapFactory.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaBootstrapFactory.kt new file mode 100644 index 00000000..df29c19b --- /dev/null +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaBootstrapFactory.kt @@ -0,0 +1,18 @@ +package org.jetbrains.dokka.gradle + +import org.gradle.api.artifacts.Configuration +import org.jetbrains.dokka.DokkaBootstrap +import java.net.URLClassLoader + + +fun DokkaBootstrap(configuration: Configuration, bootstrapClassFQName: String): DokkaBootstrap { + val runtimeJars = configuration.resolve() + val runtimeClassLoader = URLClassLoader( + runtimeJars.map { it.toURI().toURL() }.toTypedArray(), + ClassLoader.getSystemClassLoader().parent + ) + + val bootstrapClass = runtimeClassLoader.loadClass(bootstrapClassFQName) + val bootstrapInstance = bootstrapClass.constructors.first().newInstance() + return automagicTypedProxy(DokkaPlugin::class.java.classLoader, bootstrapInstance) +} diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaMultimoduleTask.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaMultimoduleTask.kt index 803c91c0..d04ad258 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaMultimoduleTask.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaMultimoduleTask.kt @@ -3,11 +3,13 @@ package org.jetbrains.dokka.gradle import com.google.gson.GsonBuilder import org.gradle.api.DefaultTask import org.gradle.api.artifacts.Configuration +import org.gradle.api.attributes.Usage import org.gradle.api.tasks.Classpath import org.gradle.api.tasks.Input import org.gradle.api.tasks.Internal import org.gradle.api.tasks.TaskAction import org.jetbrains.dokka.DokkaBootstrap +import org.jetbrains.dokka.DokkaVersion import org.jetbrains.dokka.plugability.Configurable import java.net.URLClassLoader import java.util.function.BiConsumer @@ -23,13 +25,18 @@ open class DokkaMultimoduleTask : DefaultTask(), Configurable { @Input var outputDirectory: String = "" - @get:Classpath - lateinit var pluginsConfig: Configuration - internal set + @Classpath + val runtime = project.configurations.create("${name}Runtime").apply { + defaultDependencies { dependencies -> + dependencies.add(project.dependencies.create("org.jetbrains.dokka:dokka-core:${DokkaVersion.version}")) + } + } - @get:Classpath - lateinit var dokkaRuntime: Configuration - internal set + @Classpath + val plugins = project.configurations.create("${name}Plugin").apply { + attributes.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage::class.java, "java-runtime")) + isCanBeConsumed = false + } @Input override val pluginsConfiguration: Map = mutableMapOf() @@ -40,30 +47,19 @@ open class DokkaMultimoduleTask : DefaultTask(), Configurable { System.setProperty(DokkaTask.COLORS_ENABLED_PROPERTY, "false") try { - loadCore() - val bootstrapClass = - ClassloaderContainer.coreClassLoader!!.loadClass("org.jetbrains.dokka.DokkaMultimoduleBootstrapImpl") - val bootstrapInstance = bootstrapClass.constructors.first().newInstance() - val bootstrapProxy: DokkaBootstrap = automagicTypedProxy( - javaClass.classLoader, - bootstrapInstance - ) + val bootstrap = DokkaBootstrap(runtime, "org.jetbrains.dokka.DokkaMultimoduleBootstrapImpl") val gson = GsonBuilder().setPrettyPrinting().create() val configuration = getConfiguration() - bootstrapProxy.configure( - BiConsumer { level, message -> - when (level) { - "debug" -> logger.debug(message) - "info" -> logger.info(message) - "progress" -> logger.lifecycle(message) - "warn" -> logger.warn(message) - "error" -> logger.error(message) - } - }, - gson.toJson(configuration) - ) - - bootstrapProxy.generate() + bootstrap.configure(gson.toJson(configuration)) { level, message -> + when (level) { + "debug" -> logger.debug(message) + "info" -> logger.info(message) + "progress" -> logger.lifecycle(message) + "warn" -> logger.warn(message) + "error" -> logger.error(message) + } + } + bootstrap.generate() } finally { System.setProperty(DokkaTask.COLORS_ENABLED_PROPERTY, kotlinColorsEnabledBefore) } @@ -74,30 +70,18 @@ open class DokkaMultimoduleTask : DefaultTask(), Configurable { GradleDokkaConfigurationImpl().apply { outputDir = project.file(outputDirectory).absolutePath format = outputFormat - pluginsClasspath = pluginsConfig.resolve().toList() + pluginsClasspath = plugins.resolve().toList() pluginsConfiguration = this@DokkaMultimoduleTask.pluginsConfiguration modules = project.subprojects .mapNotNull { subproject -> subproject.tasks.withType(DokkaTask::class.java).firstOrNull()?.let { dokkaTask -> GradleDokkaModuleDescription().apply { name = subproject.name - path = - subproject.projectDir.resolve(dokkaTask.outputDirectory).toRelativeString( - project.file(outputDirectory) - ) + path = subproject.projectDir.resolve(dokkaTask.outputDirectory) + .toRelativeString(project.file(outputDirectory)) docFile = subproject.projectDir.resolve(documentationFileName).absolutePath } } } } - - private fun loadCore() { - if (ClassloaderContainer.coreClassLoader == null) { - val jars = dokkaRuntime!!.resolve() - ClassloaderContainer.coreClassLoader = URLClassLoader( - jars.map { it.toURI().toURL() }.toTypedArray(), - ClassLoader.getSystemClassLoader().parent - ) - } - } } diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt index d4ade2d9..9bcbe9e0 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt @@ -3,6 +3,7 @@ package org.jetbrains.dokka.gradle import com.google.gson.GsonBuilder import org.gradle.api.* import org.gradle.api.artifacts.Configuration +import org.gradle.api.attributes.Usage import org.gradle.api.file.FileCollection import org.gradle.api.internal.plugins.DslObject import org.gradle.api.plugins.JavaBasePlugin @@ -50,9 +51,6 @@ open class DokkaTask : DefaultTask(), Configurable { @Input var outputDirectory: String = "" - @get:Classpath - lateinit var dokkaRuntime: Configuration - internal set @Input var subProjects: List = emptyList() @@ -64,17 +62,27 @@ open class DokkaTask : DefaultTask(), Configurable { @Input var cacheRoot: String? = null - @get:Classpath - lateinit var pluginsClasspathConfiguration: Configuration - internal set + @Classpath + val runtime = project.configurations.create("${name}Runtime").apply { + defaultDependencies { dependencies -> + dependencies.add(project.dependencies.create("org.jetbrains.dokka:dokka-core:${DokkaVersion.version}")) + } + } + + @Classpath + val plugins: Configuration = project.configurations.create("${name}Plugin").apply { + attributes.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage::class.java, "java-runtime")) + isCanBeConsumed = false + } @get:Internal internal var config: GradleDokkaConfigurationImpl? = null - var dokkaSourceSets: NamedDomainObjectContainer - @Suppress("UNCHECKED_CAST") - @Nested get() = (DslObject(this).extensions.getByName(SOURCE_SETS_EXTENSION_NAME) as NamedDomainObjectContainer) - internal set(value) = DslObject(this).extensions.add(SOURCE_SETS_EXTENSION_NAME, value) + @get:Nested + val dokkaSourceSets: NamedDomainObjectContainer = + project.container(GradleDokkaSourceSet::class.java) { name -> GradleDokkaSourceSet(name, project) } + .also { container -> DslObject(this).extensions.add("dokkaSourceSets", container) } + private val kotlinTasks: List by lazy { extractKotlinCompileTasks( @@ -96,16 +104,6 @@ open class DokkaTask : DefaultTask(), Configurable { private var outputDiagnosticInfo: Boolean = false // Workaround for Gradle, which fires some methods (like collectConfigurations()) multiple times in its lifecycle - private fun loadCore() { - if (ClassloaderContainer.coreClassLoader == null) { - val jars = dokkaRuntime.resolve() - ClassloaderContainer.coreClassLoader = URLClassLoader( - jars.map { it.toURI().toURL() }.toTypedArray(), - ClassLoader.getSystemClassLoader().parent - ) - } - } - protected fun extractKotlinCompileTasks(collectTasks: List?): List { val inputList = (collectTasks ?: emptyList()).filterNotNull() val (paths, other) = inputList.partition { it is String } @@ -152,29 +150,20 @@ open class DokkaTask : DefaultTask(), Configurable { val kotlinColorsEnabledBefore = System.getProperty(COLORS_ENABLED_PROPERTY) ?: "false" System.setProperty(COLORS_ENABLED_PROPERTY, "false") try { - loadCore() - - val bootstrapClass = - ClassloaderContainer.coreClassLoader!!.loadClass("org.jetbrains.dokka.DokkaBootstrapImpl") - val bootstrapInstance = bootstrapClass.constructors.first().newInstance() - val bootstrapProxy: DokkaBootstrap = - automagicTypedProxy(javaClass.classLoader, bootstrapInstance) - - bootstrapProxy.configure( - BiConsumer { level, message -> - when (level) { - "debug" -> logger.debug(message) - "info" -> logger.info(message) - "progress" -> logger.lifecycle(message) - "warn" -> logger.warn(message) - "error" -> logger.error(message) - } - }, - GsonBuilder().setPrettyPrinting().create().toJson(configuration) - ) - - bootstrapProxy.generate() + val bootstrap = DokkaBootstrap(runtime, "org.jetbrains.dokka.DokkaBootstrapImpl") + bootstrap.configure( + GsonBuilder().setPrettyPrinting().create().toJson(configuration) + ) { level, message -> + when (level) { + "debug" -> logger.debug(message) + "info" -> logger.info(message) + "progress" -> logger.lifecycle(message) + "warn" -> logger.warn(message) + "error" -> logger.error(message) + } + } + bootstrap.generate() } finally { System.setProperty(COLORS_ENABLED_PROPERTY, kotlinColorsEnabledBefore) } @@ -199,7 +188,7 @@ open class DokkaTask : DefaultTask(), Configurable { cacheRoot = this@DokkaTask.cacheRoot offlineMode = this@DokkaTask.offlineMode sourceSets = defaultModulesConfiguration - pluginsClasspath = pluginsClasspathConfiguration.resolve().toList() + pluginsClasspath = plugins.resolve().toList() pluginsConfiguration = this@DokkaTask.pluginsConfiguration failOnWarning = this@DokkaTask.failOnWarning } @@ -351,7 +340,8 @@ open class DokkaTask : DefaultTask(), Configurable { @Classpath fun getInputClasspath(): FileCollection = - project.files((configuredDokkaSourceSets.flatMap { it.classpath } as List).map { project.fileTree(File(it.toString())) }) + project.files((configuredDokkaSourceSets.flatMap { it.classpath } as List) + .map { project.fileTree(File(it.toString())) }) companion object { const val COLORS_ENABLED_PROPERTY = "kotlin.colors.enabled" diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/main.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/main.kt index a92f5475..60750373 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/main.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/main.kt @@ -2,102 +2,38 @@ package org.jetbrains.dokka.gradle import org.gradle.api.Plugin import org.gradle.api.Project -import org.gradle.api.artifacts.Configuration -import org.gradle.api.attributes.Usage -import org.gradle.util.GradleVersion +import org.gradle.kotlin.dsl.register import org.jetbrains.dokka.DokkaVersion import java.io.File -internal const val SOURCE_SETS_EXTENSION_NAME = "dokkaSourceSets" internal const val DOKKA_TASK_NAME = "dokka" internal const val DOKKA_COLLECTOR_TASK_NAME = "dokkaCollector" internal const val DOKKA_MULTIMODULE_TASK_NAME = "dokkaMultimodule" open class DokkaPlugin : Plugin { override fun apply(project: Project) { - val dokkaRuntimeConfiguration = addConfiguration(project) - val pluginsConfiguration = project.configurations.create("dokkaPlugins").apply { - dependencies.add(project.dependencies.create("org.jetbrains.dokka:dokka-base:${DokkaVersion.version}")) - attributes.attribute( - Usage.USAGE_ATTRIBUTE, project.objects.named(Usage::class.java, "java-runtime") - ) - isCanBeConsumed = false - } - addDokkaTasks(project, dokkaRuntimeConfiguration, pluginsConfiguration, DokkaTask::class.java) - addDokkaCollectorTasks(project, DokkaCollectorTask::class.java) - addDokkaMultimoduleTasks( - project.rootProject, - dokkaRuntimeConfiguration, - pluginsConfiguration, - DokkaMultimoduleTask::class.java - ) + addDokkaTasks(project) + addDokkaCollectorTasks(project) + addDokkaMultimoduleTasks(project.rootProject) } - - private fun addConfiguration(project: Project) = - project.configurations.create("dokkaRuntime").apply { - defaultDependencies { dependencies -> - dependencies.add(project.dependencies.create("org.jetbrains.dokka:dokka-core:${DokkaVersion.version}")) - } - } - - private fun addDokkaTasks( - project: Project, - runtimeConfiguration: Configuration, - pluginsConfiguration: Configuration, - taskClass: Class - ) { - if (GradleVersion.current() >= GradleVersion.version("4.10")) { - project.tasks.register(DOKKA_TASK_NAME, taskClass) - } else { - project.tasks.create(DOKKA_TASK_NAME, taskClass) - } - project.tasks.withType(taskClass) { task -> - task.dokkaSourceSets = project.container(GradleDokkaSourceSet::class.java) { name -> - GradleDokkaSourceSet(name, project) - } - task.dokkaRuntime = runtimeConfiguration - task.pluginsClasspathConfiguration = pluginsConfiguration - task.outputDirectory = File(project.buildDir, DOKKA_TASK_NAME).absolutePath + private fun addDokkaTasks(project: Project) { + project.tasks.register(DOKKA_TASK_NAME) { + val dokkaBase = project.dependencies.create("org.jetbrains.dokka:dokka-base:${DokkaVersion.version}") + plugins.dependencies.add(dokkaBase) + outputDirectory = File(project.buildDir, DOKKA_TASK_NAME).absolutePath } } - private fun addDokkaCollectorTasks( - project: Project, - taskClass: Class - ) { - if (GradleVersion.current() >= GradleVersion.version("4.10")) { - project.tasks.register(DOKKA_COLLECTOR_TASK_NAME, taskClass) - } else { - project.tasks.create(DOKKA_COLLECTOR_TASK_NAME, taskClass) - } - project.tasks.withType(taskClass) { task -> - task.outputDirectory = File(project.buildDir, DOKKA_TASK_NAME).absolutePath + private fun addDokkaCollectorTasks(project: Project) { + project.tasks.register(DOKKA_COLLECTOR_TASK_NAME) { + outputDirectory = File(project.buildDir, DOKKA_TASK_NAME).absolutePath } } - private fun addDokkaMultimoduleTasks( - project: Project, - runtimeConfiguration: Configuration, - pluginsConfiguration: Configuration, - taskClass: Class - ) { - if (project.tasks.find { it.name == DOKKA_MULTIMODULE_TASK_NAME } == null) { - if (GradleVersion.current() >= GradleVersion.version("4.10")) { - project.tasks.register(DOKKA_MULTIMODULE_TASK_NAME, taskClass) - } else { - project.tasks.create(DOKKA_MULTIMODULE_TASK_NAME, taskClass) - } - project.tasks.withType(taskClass) { task -> - task.dokkaRuntime = runtimeConfiguration - task.pluginsConfig = pluginsConfiguration - task.outputDirectory = File(project.buildDir, DOKKA_TASK_NAME).absolutePath - } + private fun addDokkaMultimoduleTasks(project: Project) { + project.tasks.register(DOKKA_MULTIMODULE_TASK_NAME) { + outputDirectory = File(project.buildDir, DOKKA_TASK_NAME).absolutePath } } } - -internal object ClassloaderContainer { - @JvmField - var coreClassLoader: ClassLoader? = null -} -- cgit From 3fc8223f92ba140dbfa8e8371157b3bf782bda85 Mon Sep 17 00:00:00 2001 From: "sebastian.sellmair" Date: Tue, 14 Jul 2020 18:29:48 +0200 Subject: Mark `DokkaBootstrap` with `Throws` annotation to avoid "UndeclaredThrowableException" when used with automagicProxy --- core/src/main/kotlin/DokkaBootstrap.kt | 3 ++ .../org/jetbrains/dokka/gradle/ProxyUtils.kt | 17 ++++---- .../jetbrains/dokka/gradle/AutomagicProxyTest.kt | 48 ++++++++++++++++++++++ 3 files changed, 58 insertions(+), 10 deletions(-) create mode 100644 runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/AutomagicProxyTest.kt (limited to 'core/src/main/kotlin/DokkaBootstrap.kt') diff --git a/core/src/main/kotlin/DokkaBootstrap.kt b/core/src/main/kotlin/DokkaBootstrap.kt index ffaae03e..159172a5 100644 --- a/core/src/main/kotlin/DokkaBootstrap.kt +++ b/core/src/main/kotlin/DokkaBootstrap.kt @@ -1,8 +1,11 @@ package org.jetbrains.dokka import java.util.function.BiConsumer +import kotlin.jvm.Throws interface DokkaBootstrap { fun configure(serializedConfigurationJSON: String, logger: BiConsumer) + + @Throws(Throwable::class) fun generate() } diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/ProxyUtils.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/ProxyUtils.kt index 85b6ea3b..468f597f 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/ProxyUtils.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/ProxyUtils.kt @@ -1,9 +1,6 @@ package org.jetbrains.dokka.gradle -import java.lang.reflect.InvocationHandler -import java.lang.reflect.InvocationTargetException -import java.lang.reflect.Method -import java.lang.reflect.Proxy +import java.lang.reflect.* /** @@ -14,7 +11,7 @@ import java.lang.reflect.Proxy */ @Suppress("UNCHECKED_CAST") internal inline fun automagicTypedProxy(targetClassLoader: ClassLoader, delegate: Any): T = - automagicProxy(targetClassLoader, T::class.java, delegate) as T + automagicProxy(targetClassLoader, T::class.java, delegate) as T /** @@ -25,11 +22,11 @@ internal inline fun automagicTypedProxy(targetClassLoader: Cla * */ internal fun automagicProxy(targetClassLoader: ClassLoader, targetType: Class<*>, delegate: Any): Any = - Proxy.newProxyInstance( - targetClassLoader, - arrayOf(targetType), - DelegatedInvocationHandler(delegate) - ) + Proxy.newProxyInstance( + targetClassLoader, + arrayOf(targetType), + DelegatedInvocationHandler(delegate) + ) internal class DelegatedInvocationHandler(private val delegate: Any) : InvocationHandler { diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/AutomagicProxyTest.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/AutomagicProxyTest.kt new file mode 100644 index 00000000..e981d6fe --- /dev/null +++ b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/AutomagicProxyTest.kt @@ -0,0 +1,48 @@ +package org.jetbrains.dokka.gradle + +import org.jetbrains.dokka.DokkaBootstrap +import org.jetbrains.dokka.gradle.AutomagicProxyTest.TestInterface +import java.util.function.BiConsumer +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertFailsWith + + +class AutomagicProxyTest { + + private class TestException(message: String, cause: Throwable?) : Exception(message, cause) + + private fun interface TestInterface { + @Throws(Throwable::class) + operator fun invoke(): Int + } + + @Test + fun `simple method invocation`() { + val instance = TestInterface { 0 } + val proxy = automagicTypedProxy(instance.javaClass.classLoader, instance) + assertEquals(0, proxy()) + } + + @Test + fun `exception throw in DokkaBootstrap is not wrapped inside UndeclaredThrowableException`() { + val instanceThrowingTestException = object : DokkaBootstrap { + override fun configure(serializedConfigurationJSON: String, logger: BiConsumer) = Unit + override fun generate() { + throw TestException("Test Exception Message", Exception("Cause Exception Message")) + } + } + + val proxy = automagicTypedProxy( + instanceThrowingTestException.javaClass.classLoader, + instanceThrowingTestException + ) + + val exception = assertFailsWith { + proxy.generate() + } + + assertEquals("Test Exception Message", exception.message) + assertEquals("Cause Exception Message", exception.cause?.message) + } +} -- cgit