From 6554c8d6fdb37eef016f28722260558475094e4c Mon Sep 17 00:00:00 2001
From: tschuchortdev <t.schuchort@googlemail.com>
Date: Fri, 12 Aug 2022 21:37:03 +0200
Subject: [PATCH] Add MainComponentRegistrar to classpath only when plugins are
 given. Resolves #302

---
 .../compiletesting/AbstractKotlinCompilation.kt     | 12 +++++++++++-
 .../compiletesting/MainComponentRegistrar.kt        |  2 +-
 .../compiletesting/KotlinCompilationTests.kt        | 13 +++++++++++++
 3 files changed, 25 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..ac58e922 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<A : CommonCompilerArguments> 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<String> = emptyList()
 
@@ -126,6 +129,7 @@ abstract class AbstractKotlinCompilation<A : CommonCompilerArguments> internal c
         args.allWarningsAsErrors = allWarningsAsErrors
         args.reportOutputFiles = reportOutputFiles
         args.reportPerf = reportPerformance
+        args.useK2 = useK2
 
         if (languageVersion != null)
             args.languageVersion = this.languageVersion
@@ -191,7 +195,13 @@ abstract class AbstractKotlinCompilation<A : CommonCompilerArguments> internal c
                 } else {
                     emptyList()
                 }
-            args.pluginClasspaths = (args.pluginClasspaths ?: emptyArray()) + arrayOf(getResourcesPath())
+            args.pluginClasspaths = (args.pluginClasspaths ?: emptyArray()) +
+                    /** The resources path contains the MainComponentRegistrar 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 [compilerPlugins] to the emptyList. */
+                    if (compilerPlugins.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<ThreadLocalParameters> = 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 {}
 }