[WIP] Separate free compiler args and Kotlin sources in build tools
diff --git a/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/KotlinCompilerClient.kt b/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/KotlinCompilerClient.kt
index 39b6031..5c759f6 100644
--- a/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/KotlinCompilerClient.kt
+++ b/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/KotlinCompilerClient.kt
@@ -159,6 +159,7 @@
         val services = BasicCompilerServicesWithResultsFacadeServer(messageCollector, outputsCollector, port)
         compilerService.compile(
                 sessionId,
+                emptyArray(),
                 args,
                 CompilationOptions(
                         compilerMode,
@@ -264,6 +265,7 @@
 
                     val res = daemon.compile(
                         CompileService.NO_SESSION,
+                        emptyArray(),
                         filteredArgs.toList().toTypedArray(),
                         compilationOptions,
                         servicesFacade,
diff --git a/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/CompileService.kt b/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/CompileService.kt
index 13f8e7c..e4be9ed 100644
--- a/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/CompileService.kt
+++ b/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/CompileService.kt
@@ -118,11 +118,12 @@
 
     @Throws(RemoteException::class)
     fun compile(
-            sessionId: Int,
-            compilerArguments: Array<out String>,
-            compilationOptions: CompilationOptions,
-            servicesFacade: CompilerServicesFacadeBase,
-            compilationResults: CompilationResults?
+        sessionId: Int,
+        sources: Array<String>,
+        compilerArguments: Array<out String>,
+        compilationOptions: CompilationOptions,
+        servicesFacade: CompilerServicesFacadeBase,
+        compilationResults: CompilationResults?
     ): CallResult<Int>
 
     @Throws(RemoteException::class)
diff --git a/compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt b/compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt
index 2e043d2..20c9360 100644
--- a/compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt
+++ b/compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt
@@ -286,6 +286,7 @@
 
     protected inline fun <ServicesFacadeT, JpsServicesFacadeT, CompilationResultsT> compileImpl(
         sessionId: Int,
+        sources: Array<String>,
         compilerArguments: Array<out String>,
         compilationOptions: CompilationOptions,
         servicesFacade: ServicesFacadeT,
@@ -317,6 +318,7 @@
             CompileService.CallResult.Good(ExitCode.COMPILATION_ERROR.code)
         } else when (compilationOptions.compilerMode) {
             CompilerMode.JPS_COMPILER -> {
+                k2PlatformArgs.freeArgs += sources
                 @Suppress("UNCHECKED_CAST")
                 servicesFacade as JpsServicesFacadeT
                 withIncrementalCompilation(k2PlatformArgs, enabled = servicesFacade.hasIncrementalCaches()) {
@@ -327,6 +329,7 @@
                 }
             }
             CompilerMode.NON_INCREMENTAL_COMPILER -> {
+                k2PlatformArgs.freeArgs += sources
                 doCompile(sessionId, daemonReporter, tracer = null) { _, _ ->
                     val exitCode = compiler.exec(messageCollector, Services.EMPTY, k2PlatformArgs)
 
@@ -349,6 +352,7 @@
                     CompileService.TargetPlatform.JVM -> withIncrementalCompilation(k2PlatformArgs) {
                         doCompile(sessionId, daemonReporter, tracer = null) { _, _ ->
                             execIncrementalCompiler(
+                                sources,
                                 k2PlatformArgs as K2JVMCompilerArguments,
                                 gradleIncrementalArgs,
                                 messageCollector,
@@ -363,6 +367,7 @@
                     CompileService.TargetPlatform.JS -> withJsIC(k2PlatformArgs) {
                         doCompile(sessionId, daemonReporter, tracer = null) { _, _ ->
                             execJsIncrementalCompiler(
+                                sources,
                                 k2PlatformArgs as K2JSCompilerArguments,
                                 gradleIncrementalArgs,
                                 messageCollector,
@@ -529,22 +534,29 @@
     }
 
     protected fun execJsIncrementalCompiler(
+        sources: Array<String>,
         args: K2JSCompilerArguments,
         incrementalCompilationOptions: IncrementalCompilationOptions,
         compilerMessageCollector: MessageCollector,
         reporter: RemoteBuildReporter
     ): ExitCode {
         reporter.startMeasureGc()
-        val allKotlinFiles = arrayListOf<File>()
-        val freeArgsWithoutKotlinFiles = arrayListOf<String>()
-        args.freeArgs.forEach {
-            if (it.endsWith(".kt") && File(it).exists()) {
-                allKotlinFiles.add(File(it))
-            } else {
-                freeArgsWithoutKotlinFiles.add(it)
+        val allKotlinFiles = if (sources.isNotEmpty()) {
+            sources.map { File(it) }
+        } else {
+            // fallback logic
+            val allKotlinFiles = arrayListOf<File>()
+            val freeArgsWithoutKotlinFiles = arrayListOf<String>()
+            args.freeArgs.forEach {
+                if (it.endsWith(".kt") && File(it).exists()) {
+                    allKotlinFiles.add(File(it))
+                } else {
+                    freeArgsWithoutKotlinFiles.add(it)
+                }
             }
+            args.freeArgs = freeArgsWithoutKotlinFiles
+            allKotlinFiles
         }
-        args.freeArgs = freeArgsWithoutKotlinFiles
 
         val changedFiles = if (incrementalCompilationOptions.areFileChangesKnown) {
             ChangedFiles.Known(incrementalCompilationOptions.modifiedFiles!!, incrementalCompilationOptions.deletedFiles!!)
@@ -574,6 +586,7 @@
     }
 
     protected fun execIncrementalCompiler(
+        sources: Array<String>,
         k2jvmArgs: K2JVMCompilerArguments,
         incrementalCompilationOptions: IncrementalCompilationOptions,
         compilerMessageCollector: MessageCollector,
@@ -582,18 +595,24 @@
         reporter.startMeasureGc()
         val allKotlinExtensions = (DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS +
                 (incrementalCompilationOptions.kotlinScriptExtensions ?: emptyArray())).distinct()
-        val dotExtensions = allKotlinExtensions.map { ".$it" }
-        val freeArgs = arrayListOf<String>()
-        val allKotlinFiles = arrayListOf<File>()
-        for (arg in k2jvmArgs.freeArgs) {
-            val file = File(arg)
-            if (file.isFile && dotExtensions.any { ext -> file.path.endsWith(ext, ignoreCase = true) }) {
-                allKotlinFiles.add(file)
-            } else {
-                freeArgs.add(arg)
+        val allKotlinFiles = if (sources.isNotEmpty()) {
+            sources.map { File(it) }
+        } else {
+            // fallback logic
+            val dotExtensions = allKotlinExtensions.map { ".$it" }
+            val freeArgs = arrayListOf<String>()
+            val allKotlinFiles = arrayListOf<File>()
+            for (arg in k2jvmArgs.freeArgs) {
+                val file = File(arg)
+                if (file.isFile && dotExtensions.any { ext -> file.path.endsWith(ext, ignoreCase = true) }) {
+                    allKotlinFiles.add(file)
+                } else {
+                    freeArgs.add(arg)
+                }
             }
+            k2jvmArgs.freeArgs = freeArgs
+            allKotlinFiles
         }
-        k2jvmArgs.freeArgs = freeArgs
 
         val changedFiles = if (incrementalCompilationOptions.areFileChangesKnown) {
             ChangedFiles.Known(incrementalCompilationOptions.modifiedFiles!!, incrementalCompilationOptions.deletedFiles!!)
@@ -759,6 +778,7 @@
 
     override fun compile(
         sessionId: Int,
+        sources: Array<String>,
         compilerArguments: Array<out String>,
         compilationOptions: CompilationOptions,
         servicesFacade: CompilerServicesFacadeBase,
@@ -766,6 +786,7 @@
     ) = ifAlive {
         compileImpl(
             sessionId,
+            sources,
             compilerArguments,
             compilationOptions,
             servicesFacade,
diff --git a/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsKotlinCompilerRunner.kt b/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsKotlinCompilerRunner.kt
index 16bd742..97bbc80 100644
--- a/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsKotlinCompilerRunner.kt
+++ b/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsKotlinCompilerRunner.kt
@@ -219,6 +219,7 @@
                 progress.compilationStarted()
                 daemon.compile(
                     sessionId,
+                    emptyArray(),
                     withAdditionalCompilerArgs(compilerArgs),
                     options,
                     JpsCompilerServicesFacadeImpl(environment),
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt
index f5be0ee..cc9e4aa 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt
@@ -112,6 +112,7 @@
      * @see [GradleKotlinCompilerWork]
      */
     fun runJvmCompilerAsync(
+        sources: List<File>,
         args: K2JVMCompilerArguments,
         environment: GradleCompilerEnvironment,
         jdkHome: File,
@@ -119,7 +120,7 @@
     ): WorkQueue? {
         if (args.jdkHome == null && !args.noJdk) args.jdkHome = jdkHome.absolutePath
         loggerProvider.kotlinInfo("Kotlin compilation 'jdkHome' argument: ${args.jdkHome}")
-        return runCompilerAsync(KotlinCompilerClass.JVM, args, environment, taskOutputsBackup)
+        return runCompilerAsync(KotlinCompilerClass.JVM, sources, args, environment, taskOutputsBackup)
     }
 
     /**
@@ -127,11 +128,12 @@
      * @see [GradleKotlinCompilerWork]
      */
     fun runJsCompilerAsync(
+        sources: List<File>,
         args: K2JSCompilerArguments,
         environment: GradleCompilerEnvironment,
         taskOutputsBackup: TaskOutputsBackup?
     ): WorkQueue? {
-        return runCompilerAsync(KotlinCompilerClass.JS, args, environment, taskOutputsBackup)
+        return runCompilerAsync(KotlinCompilerClass.JS, sources, args, environment, taskOutputsBackup)
     }
 
     /**
@@ -139,10 +141,11 @@
      * @see [GradleKotlinCompilerWork]
      */
     fun runMetadataCompilerAsync(
+        sources: List<File>,
         args: K2MetadataCompilerArguments,
         environment: GradleCompilerEnvironment
     ): WorkQueue? {
-        return runCompilerAsync(KotlinCompilerClass.METADATA, args, environment)
+        return runCompilerAsync(KotlinCompilerClass.METADATA, sources, args, environment)
     }
 
     private fun reportCompilerArgumentsStatistics(compilerArgs: CommonCompilerArguments, argsArray: Array<String>) {
@@ -194,6 +197,7 @@
 
     private fun prepareWorkArguments(
         compilerClassName: String,
+        sources: List<File>,
         compilerArgs: CommonCompilerArguments,
         environment: GradleCompilerEnvironment,
         argsArray: Array<String>
@@ -201,6 +205,7 @@
         val incrementalCompilationEnvironment = environment.incrementalCompilationEnvironment
         val modulesInfo = incrementalCompilationEnvironment?.let { incrementalModuleInfoProvider.get().info }
         return GradleKotlinCompilerWorkArguments(
+            sources = sources,
             projectFiles = ProjectFilesForCompilation(
                 loggerProvider,
                 projectDirProvider,
@@ -230,6 +235,7 @@
 
     private fun runCompilerAsync(
         compilerClassName: String,
+        sources: List<File>,
         compilerArgs: CommonCompilerArguments,
         environment: GradleCompilerEnvironment,
         taskOutputsBackup: TaskOutputsBackup? = null
@@ -243,7 +249,7 @@
         }
         val argsArray = ArgumentUtils.convertArgumentsToStringList(compilerArgs).toTypedArray()
         reportCompilerArgumentsStatistics(compilerArgs, argsArray)
-        val workArgs = prepareWorkArguments(compilerClassName, compilerArgs, environment, argsArray)
+        val workArgs = prepareWorkArguments(compilerClassName, sources, compilerArgs, environment, argsArray)
         TaskLoggers.put(pathProvider, loggerProvider)
         return runCompilerAsync(
             workArgs,
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt
index f4124fd..d440711 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt
@@ -75,9 +75,10 @@
     val errorsFile: File?,
     val kotlinPluginVersion: String,
     val kotlinLanguageVersion: KotlinVersion,
+    val sources: List<File>,
 ) : Serializable {
     companion object {
-        const val serialVersionUID: Long = 1
+        const val serialVersionUID: Long = 2
     }
 }
 
@@ -113,6 +114,9 @@
     private val errorsFile = config.errorsFile
     private val kotlinPluginVersion = config.kotlinPluginVersion
     private val kotlinLanguageVersion = config.kotlinLanguageVersion
+    private val sources = config.sources
+    private val compilerArgsWithSources: Array<String>
+        get() = compilerArgs + sources.map { it.absolutePath }
 
     private val log: KotlinLogger =
         TaskLoggers.get(taskPath)?.let { GradleKotlinLogger(it).apply { debug("Using '$taskPath' logger") } }
@@ -171,7 +175,7 @@
             kotlinDebug {
                 "Kotlin compiler classpath: ${compilerFullClasspath.joinToString(File.pathSeparator) { it.normalize().absolutePath }}"
             }
-            kotlinDebug { "$taskPath Kotlin compiler args: ${compilerArgs.joinToString(" ")}" }
+            kotlinDebug { "$taskPath Kotlin compiler args: ${compilerArgsWithSources.joinToString(" ")}" }
         }
 
         if (compilerExecutionSettings.strategy == KotlinCompilerExecutionStrategy.DAEMON) {
@@ -299,7 +303,14 @@
         val servicesFacade = GradleCompilerServicesFacadeImpl(log, bufferingMessageCollector)
         val compilationResults = GradleCompilationResults(log, projectRootFile)
         return metrics.measure(BuildTime.NON_INCREMENTAL_COMPILATION_DAEMON) {
-            daemon.compile(sessionId, compilerArgs, compilationOptions, servicesFacade, compilationResults)
+            daemon.compile(
+                sessionId,
+                sources.map { it.absolutePath }.toTypedArray(),
+                compilerArgs,
+                compilationOptions,
+                servicesFacade,
+                compilationResults
+            )
         }.also {
             metrics.addMetrics(compilationResults.buildMetrics)
             icLogLines = compilationResults.icLogLines
@@ -341,7 +352,14 @@
         val compilationResults = GradleCompilationResults(log, projectRootFile)
         metrics.addTimeMetric(BuildPerformanceMetric.CALL_KOTLIN_DAEMON)
         return metrics.measure(BuildTime.RUN_COMPILATION) {
-            daemon.compile(sessionId, compilerArgs, compilationOptions, servicesFacade, compilationResults)
+            daemon.compile(
+                sessionId,
+                sources.map { it.absolutePath }.toTypedArray(),
+                compilerArgs,
+                compilationOptions,
+                servicesFacade,
+                compilationResults
+            )
         }.also {
             metrics.addMetrics(compilationResults.buildMetrics)
             icLogLines = compilationResults.icLogLines
@@ -353,7 +371,7 @@
         cleanOutputsAndLocalState(outputFiles, log, metrics, reason = "out-of-process execution strategy is non-incremental")
 
         return metrics.measure(BuildTime.NON_INCREMENTAL_COMPILATION_OUT_OF_PROCESS) {
-            runToolInSeparateProcess(compilerArgs, compilerClassName, compilerFullClasspath, log, buildDir)
+            runToolInSeparateProcess(compilerArgsWithSources, compilerClassName, compilerFullClasspath, log, buildDir)
         }
     }
 
@@ -395,7 +413,7 @@
             Array<String>::class.java
         )
 
-        val res = exec.invoke(compiler.newInstance(), out, emptyServices, compilerArgs)
+        val res = exec.invoke(compiler.newInstance(), out, emptyServices, compilerArgsWithSources)
         val exitCode = ExitCode.valueOf(res.toString())
         processCompilerOutput(
             messageCollector,
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptGenerateStubsTask.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptGenerateStubsTask.kt
index a799569..998be8d 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptGenerateStubsTask.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptGenerateStubsTask.kt
@@ -140,8 +140,8 @@
             args.friendPaths = friendPaths.toPathsArray()
         }
 
-        sources{ args ->
-            args.freeArgs += (scriptSources.asFileTree.files + javaSources.files + sources.asFileTree.files).map { it.absolutePath }
+        sources { args ->
+            args.freeArgs += javaSources.files.map { it.absolutePath }
         }
     }
 }
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Kotlin2JsCompile.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Kotlin2JsCompile.kt
index 540b69d..b4d509a 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Kotlin2JsCompile.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Kotlin2JsCompile.kt
@@ -203,8 +203,6 @@
             } else {
                 args.commonSources = commonSourceSet.asFileTree.toPathsArray()
             }
-
-            args.freeArgs += sources.asFileTree.files.map { it.absolutePath }
         }
 
         contributeAdditionalCompilerArguments(this)
@@ -341,7 +339,14 @@
             incrementalCompilationEnvironment = icEnv
         )
         processArgsBeforeCompile(args)
+
+        val sourceFiles = sources.asFileTree.files.toList()
+        if (logger.isInfoEnabled) {
+            logger.info("Kotlin source files: $sourceFiles")
+        }
+
         compilerRunner.runJsCompilerAsync(
+            sourceFiles,
             args,
             environment,
             taskOutputsBackup
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompile.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompile.kt
index bf4a21e..17aa7e6 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompile.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompile.kt
@@ -273,18 +273,13 @@
                 args.commonSources = commonSourceSet.asFileTree.toPathsArray()
             }
 
-            val sourcesFiles = sources.asFileTree.files.toList()
             val javaSourcesFiles = javaSources.files.toList()
-            val scriptSourcesFiles = scriptSources.asFileTree.files.toList()
 
             if (logger.isInfoEnabled) {
-                logger.info("Kotlin source files: ${sourcesFiles.joinToString()}")
                 logger.info("Java source files: ${javaSourcesFiles.joinToString()}")
-                logger.info("Script source files: ${scriptSourcesFiles.joinToString()}")
-                logger.info("Script file extensions: ${scriptExtensions.get().joinToString()}")
             }
 
-            args.freeArgs += (scriptSourcesFiles + javaSourcesFiles + sourcesFiles).map { it.absolutePath }
+            args.freeArgs += javaSourcesFiles.map { it.absolutePath }
         }
     }
 
@@ -345,7 +340,18 @@
             incrementalCompilationEnvironment = icEnv,
             kotlinScriptExtensions = scriptExtensions.get().toTypedArray()
         )
+
+        val sourcesFiles = sources.asFileTree.files.toList()
+        val scriptSourcesFiles = scriptSources.asFileTree.files.toList()
+
+        if (logger.isInfoEnabled) {
+            logger.info("Kotlin source files: ${sourcesFiles.joinToString()}")
+            logger.info("Script source files: ${scriptSourcesFiles.joinToString()}")
+            logger.info("Script file extensions: ${scriptExtensions.get().joinToString()}")
+        }
+
         compilerRunner.runJvmCompilerAsync(
+            sourcesFiles + scriptSourcesFiles,
             args,
             environment,
             defaultKotlinJavaToolchain.get().buildJvm.get().javaHome,
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompileCommon.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompileCommon.kt
index b293592..0b775f15 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompileCommon.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompileCommon.kt
@@ -115,7 +115,6 @@
         }
 
         sources { args ->
-            args.freeArgs += sources.asFileTree.map { it.absolutePath }
             args.commonSources = commonSourceSet.asFileTree.toPathsArray()
         }
     }
@@ -143,7 +142,11 @@
             reportingSettings = reportingSettings(),
             outputFiles = allOutputFiles()
         )
-        compilerRunner.runMetadataCompilerAsync(args, environment)
+        val sourceFiles = sources.asFileTree.toList()
+        if (logger.isInfoEnabled) {
+            logger.info("Kotlin source files: $sourceFiles")
+        }
+        compilerRunner.runMetadataCompilerAsync(sourceFiles, args, environment)
         compilerRunner.errorsFile?.also { gradleMessageCollector.flush(it) }
     }
 }