From ee44c53a1e17c8b557d6a17f4854b65dd13b23d9 Mon Sep 17 00:00:00 2001 From: tschuchortdev Date: Fri, 12 Aug 2022 22:08:34 +0200 Subject: [PATCH] Add MainComponentRegistrar to classpath only when plugins are given. Resolves #302 --- .../compiletesting/AbstractKotlinCompilation.kt | 15 ++++++++++++++- .../compiletesting/MainComponentRegistrar.kt | 2 +- .../compiletesting/KotlinCompilationTests.kt | 13 +++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/core/src/main/kotlin/com/tschuchort/compiletesting/AbstractKotlinCompilation.kt b/core/src/main/kotlin/com/tschuchort/compiletesting/AbstractKotlinCompilation.kt index 534fa489..9321b710 100644 --- a/core/src/main/kotlin/com/tschuchort/compiletesting/AbstractKotlinCompilation.kt +++ b/core/src/main/kotlin/com/tschuchort/compiletesting/AbstractKotlinCompilation.kt @@ -88,6 +88,9 @@ abstract class AbstractKotlinCompilation internal c var languageVersion: String? = null + /** Use the new experimental K2 compiler */ + var useK2: Boolean by default { false } + /** Additional string arguments to the Kotlin compiler */ var kotlincArguments: List = emptyList() @@ -126,6 +129,7 @@ abstract class AbstractKotlinCompilation internal c args.allWarningsAsErrors = allWarningsAsErrors args.reportOutputFiles = reportOutputFiles args.reportPerf = reportPerformance + args.useK2 = useK2 if (languageVersion != null) args.languageVersion = this.languageVersion @@ -191,7 +195,16 @@ abstract class AbstractKotlinCompilation internal c } else { emptyList() } - args.pluginClasspaths = (args.pluginClasspaths ?: emptyArray()) + arrayOf(getResourcesPath()) + args.pluginClasspaths = (args.pluginClasspaths ?: emptyArray()) + + /** The resources path contains the MainComponentRegistrar and MainCommandLineProcessor which will + be found by the Kotlin compiler's service loader. We add it only when the user has actually given + us ComponentRegistrar instances to be loaded by the MainComponentRegistrar because the experimental + K2 compiler doesn't support plugins yet. This way, users of K2 can prevent MainComponentRegistrar + from being loaded and crashing K2 by setting both [compilerPlugins] and [commandLineProcessors] to + the emptyList. */ + if (compilerPlugins.isNotEmpty() || commandLineProcessors.isNotEmpty()) + arrayOf(getResourcesPath()) + else emptyArray() } val compilerMessageCollector = PrintingMessageCollector( diff --git a/core/src/main/kotlin/com/tschuchort/compiletesting/MainComponentRegistrar.kt b/core/src/main/kotlin/com/tschuchort/compiletesting/MainComponentRegistrar.kt index dc9842e4..acea6bfc 100644 --- a/core/src/main/kotlin/com/tschuchort/compiletesting/MainComponentRegistrar.kt +++ b/core/src/main/kotlin/com/tschuchort/compiletesting/MainComponentRegistrar.kt @@ -47,7 +47,7 @@ internal class MainComponentRegistrar : ComponentRegistrar { companion object { /** This compiler plugin is instantiated by K2JVMCompiler using * a service locator. So we can't just pass parameters to it easily. - * Instead we need to use a thread-local global variable to pass + * Instead, we need to use a thread-local global variable to pass * any parameters that change between compilations */ val threadLocalParameters: ThreadLocal = ThreadLocal() diff --git a/core/src/test/kotlin/com/tschuchort/compiletesting/KotlinCompilationTests.kt b/core/src/test/kotlin/com/tschuchort/compiletesting/KotlinCompilationTests.kt index c1c51e57..f98a85ad 100644 --- a/core/src/test/kotlin/com/tschuchort/compiletesting/KotlinCompilationTests.kt +++ b/core/src/test/kotlin/com/tschuchort/compiletesting/KotlinCompilationTests.kt @@ -904,5 +904,18 @@ class KotlinCompilationTests { } } + @Test + fun `runs the K2 compiler without compiler plugins`() { + val result = defaultCompilerConfig().apply { + sources = listOf(SourceFile.kotlin("kSource.kt", "class KSource")) + compilerPlugins = emptyList() + pluginClasspaths = emptyList() + useK2 = true + }.compile() + + assertThat(result.exitCode).isEqualTo(ExitCode.OK) + assertClassLoadable(result, "KSource") + } + class InheritedClass {} }