diff --git a/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/KotlinCompilerArguments.kt b/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/KotlinCompilerArguments.kt new file mode 100644 index 0000000000..3dd49fb102 --- /dev/null +++ b/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/KotlinCompilerArguments.kt @@ -0,0 +1,93 @@ +/* + * Copyright 2022 Google LLC + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.devtools.ksp.gradle + +import java.io.File + +/** + * A simplified version of CommonComilerArguments. + */ +open class KotlinCompilerArguments { + open var freeArgs: List = emptyList() + open var verbose: Boolean = false + open var allWarningsAsErrors: Boolean = false + open var languageVersion: String? = null + open var apiVersion: String? = null + open var useK2: Boolean = false + open var incrementalCompilation: Boolean = false + open var pluginOptions: List = emptyList() + open var pluginClasspaths: List = emptyList() + open var multiPlatform: Boolean = false + open var expectActualLinker: Boolean = false + + // A.K.A. friend modules + open var friendPaths: List = emptyList() + + // A.K.A. classpath + open var libraries: List = emptyList() + + // A.K.A. output, output file + open var destination: File? = null +} + +/** + * A simplified version of K2JVMComilerArguments. + */ +class KotlinJvmCompilerArguments : KotlinCompilerArguments() { + var noJdk: Boolean = false + var noStdlib: Boolean = false + var noReflect: Boolean = false + var moduleName: String? = null + var jvmTarget: String? = null + var jdkRelease: String? = null + var allowNoSourceFiles: Boolean = false + + var javaSourceRoots: List = emptyList() +} + +/** + * A simplified version of K2JSComilerArguments. + */ +class KotlinJsCompilerArguments : KotlinCompilerArguments() { + var noStdlib: Boolean = false + var irOnly: Boolean = false + var irProduceJs: Boolean = false + var irProduceKlibDir: Boolean = false + var irProduceKlibFile: Boolean = false + var irBuildCache: Boolean = false + var wasm: Boolean = false + var target: String = "v5" + + override var multiPlatform = true +} + +/** + * A simplified version of K2MetadataComilerArguments. + */ +class KotlinMetadataCompilerArguments : KotlinCompilerArguments() { + override var multiPlatform = true + override var expectActualLinker = true +} + +/** + * A simplified version of K2NativeComilerArguments. + */ +class KotlinNativeCompilerArguments : KotlinCompilerArguments() { + var target: String? = null + override var multiPlatform = true +} diff --git a/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/KotlinCompilerRunner.kt b/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/KotlinCompilerRunner.kt index d3534e0d31..4c91df7e5f 100644 --- a/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/KotlinCompilerRunner.kt +++ b/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/KotlinCompilerRunner.kt @@ -26,10 +26,6 @@ import org.gradle.api.provider.ListProperty import org.gradle.api.provider.Property import org.gradle.api.tasks.Classpath import org.gradle.api.tasks.Internal -import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments -import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments -import org.jetbrains.kotlin.cli.common.arguments.K2MetadataCompilerArguments -import org.jetbrains.kotlin.cli.common.arguments.K2NativeCompilerArguments import org.jetbrains.kotlin.gradle.tasks.KotlinCompilerExecutionStrategy import org.jetbrains.kotlin.gradle.utils.newInstance import java.io.File @@ -53,7 +49,7 @@ interface KotlinCompilerRunner { interface KotlinJvmCompilerRunner : KotlinCompilerRunner { fun runJvmCompilerAsync( - args: K2JVMCompilerArguments, + args: KotlinJvmCompilerArguments, sources: List, commonSources: List, outputs: List @@ -62,7 +58,7 @@ interface KotlinJvmCompilerRunner : KotlinCompilerRunner { interface KotlinJsCompilerRunner : KotlinCompilerRunner { fun runJsCompilerAsync( - args: K2JSCompilerArguments, + args: KotlinJsCompilerArguments, sources: List, commonSources: List, outputs: List @@ -71,7 +67,7 @@ interface KotlinJsCompilerRunner : KotlinCompilerRunner { interface KotlinMetadataCompilerRunner : KotlinCompilerRunner { fun runMetadataCompilerAsync( - args: K2MetadataCompilerArguments, + args: KotlinMetadataCompilerArguments, sources: List, commonSources: List, outputs: List @@ -80,7 +76,7 @@ interface KotlinMetadataCompilerRunner : KotlinCompilerRunner { interface KotlinNativeCompilerRunner : KotlinCompilerRunner { fun runNativeCompilerAsync( - args: K2NativeCompilerArguments, + args: KotlinNativeCompilerArguments, sources: List, commonSources: List, outputs: List, diff --git a/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/KotlinCompilerRunnerImpls.kt b/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/KotlinCompilerRunnerImpls.kt index 14f2b21df4..587b662275 100644 --- a/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/KotlinCompilerRunnerImpls.kt +++ b/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/KotlinCompilerRunnerImpls.kt @@ -28,10 +28,12 @@ import org.gradle.process.ExecOperations import org.gradle.workers.WorkerExecutor import org.jetbrains.kotlin.build.report.metrics.BuildMetricsReporter import org.jetbrains.kotlin.build.report.metrics.BuildMetricsReporterImpl +import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.K2MetadataCompilerArguments -import org.jetbrains.kotlin.cli.common.arguments.K2NativeCompilerArguments +import org.jetbrains.kotlin.cli.common.arguments.isIrBackendEnabled +import org.jetbrains.kotlin.cli.common.arguments.isPreIrBackendDisabled import org.jetbrains.kotlin.compilerRunner.CompilerExecutionSettings import org.jetbrains.kotlin.compilerRunner.GradleCompilerEnvironment import org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers @@ -45,6 +47,9 @@ import org.jetbrains.kotlin.gradle.tasks.GradleCompileTaskProvider import org.jetbrains.kotlin.gradle.utils.newInstance import org.jetbrains.kotlin.gradle.utils.propertyWithNewInstance import org.jetbrains.kotlin.konan.target.KonanTarget +import org.jetbrains.kotlin.library.impl.isKotlinLibrary +import org.jetbrains.kotlin.utils.JsLibraryUtils +import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty import java.io.File import javax.inject.Inject @@ -105,6 +110,20 @@ abstract class KotlinCompilerRunnerImpl @Inject constructor( } } +internal fun CommonCompilerArguments.copyFrom(args: KotlinCompilerArguments) { + freeArgs = args.freeArgs + verbose = args.verbose + allWarningsAsErrors = args.allWarningsAsErrors + languageVersion = args.languageVersion + apiVersion = args.apiVersion + useK2 = args.useK2 + incrementalCompilation = args.incrementalCompilation + pluginOptions = args.pluginOptions.toTypedArray() + pluginClasspaths = args.pluginClasspaths.map { it.absolutePath }.toTypedArray() + expectActualLinker = args.expectActualLinker + multiPlatform = args.multiPlatform +} + abstract class KotlinJvmCompilerRunnerImpl @Inject constructor( task: Task, objectFactory: ObjectFactory, @@ -112,19 +131,35 @@ abstract class KotlinJvmCompilerRunnerImpl @Inject constructor( ) : KotlinCompilerRunnerImpl(task, objectFactory, workerExecutor), KotlinJvmCompilerRunner { override fun runJvmCompilerAsync( - args: K2JVMCompilerArguments, + args: KotlinJvmCompilerArguments, sources: List, commonSources: List, outputs: List ) { val environment = prepareEnvironment(args.allWarningsAsErrors, outputs) val compilerRunner = prepareCompilerRunner() + val compilerArgs = K2JVMCompilerArguments().apply { + copyFrom(args) + + friendPaths = args.friendPaths.map { it.absolutePath }.toTypedArray() + classpath = args.libraries.map { it.absolutePath }.joinToString(File.pathSeparator) + destination = args.destination?.absolutePath + + noJdk = args.noJdk + noStdlib = args.noStdlib + noReflect = args.noReflect + moduleName = args.moduleName + jvmTarget = args.jvmTarget + jdkRelease = args.jdkRelease + allowNoSourceFiles = args.allowNoSourceFiles + javaSourceRoots = args.javaSourceRoots.map { it.absolutePath }.toTypedArray() + } compilerRunner.runJvmCompilerAsync( sourcesToCompile = sources, commonSources = commonSources, javaPackagePrefix = null, - args = args, + args = compilerArgs, environment = environment, jdkHome = defaultKotlinJavaToolchain.get().providedJvm.get().javaHome, null @@ -138,16 +173,52 @@ abstract class KotlinJsCompilerRunnerImpl @Inject constructor( workerExecutor: WorkerExecutor ) : KotlinCompilerRunnerImpl(task, objectFactory, workerExecutor), KotlinJsCompilerRunner { + private fun libFilter(args: K2JSCompilerArguments, file: File): Boolean = + file.exists() && when { + // JS_IR + args.isIrBackendEnabled() && args.isPreIrBackendDisabled() -> + isKotlinLibrary(file) + + // JS_LEGACY + !args.isIrBackendEnabled() && !args.isPreIrBackendDisabled() -> + JsLibraryUtils.isKotlinJavascriptLibrary(file) + + // JS_BOTH + args.isIrBackendEnabled() && !args.isPreIrBackendDisabled() -> + isKotlinLibrary(file) && JsLibraryUtils.isKotlinJavascriptLibrary(file) + + else -> throw IllegalArgumentException("Cannot determine JS backend.") + } + override fun runJsCompilerAsync( - args: K2JSCompilerArguments, + args: KotlinJsCompilerArguments, sources: List, commonSources: List, outputs: List ) { val environment = prepareEnvironment(args.allWarningsAsErrors, outputs) val compilerRunner = prepareCompilerRunner() + val compilerArgs = K2JSCompilerArguments().apply { + copyFrom(args) + + outputFile = args.destination?.absolutePath + + noStdlib = args.noStdlib + irOnly = args.irOnly + irProduceJs = args.irProduceJs + irProduceKlibDir = args.irProduceKlibDir + irProduceKlibFile = args.irProduceKlibFile + irBuildCache = args.irBuildCache + wasm = args.wasm + target = args.target + + friendModules = args.friendPaths.filter { libFilter(this, it) } + .map { it.absolutePath }.joinToString(File.pathSeparator) + libraries = args.libraries.filter { libFilter(this, it) } + .map { it.absolutePath }.joinToString(File.pathSeparator) + } - compilerRunner.runJsCompilerAsync(sources, commonSources, args, environment, null) + compilerRunner.runJsCompilerAsync(sources, commonSources, compilerArgs, environment, null) } } @@ -158,15 +229,22 @@ abstract class KotlinMetadataCompilerRunnerImpl @Inject constructor( ) : KotlinCompilerRunnerImpl(task, objectFactory, workerExecutor), KotlinMetadataCompilerRunner { override fun runMetadataCompilerAsync( - args: K2MetadataCompilerArguments, + args: KotlinMetadataCompilerArguments, sources: List, commonSources: List, outputs: List ) { val environment = prepareEnvironment(args.allWarningsAsErrors, outputs) val compilerRunner = prepareCompilerRunner() + val compilerArgs = K2MetadataCompilerArguments().apply { + copyFrom(args) + + friendPaths = args.friendPaths.map { it.absolutePath }.toTypedArray() + classpath = args.libraries.map { it.absolutePath }.joinToString(File.pathSeparator) + destination = args.destination?.absolutePath + } - compilerRunner.runMetadataCompilerAsync(sources, commonSources, args, environment) + compilerRunner.runMetadataCompilerAsync(sources, commonSources, compilerArgs, environment) } } @@ -181,7 +259,7 @@ abstract class KotlinNativeCompilerRunnerImpl @Inject constructor( .KotlinNativeCompilerRunner.Settings.fromProject(task.project) override fun runNativeCompilerAsync( - args: K2NativeCompilerArguments, + args: KotlinNativeCompilerArguments, sources: List, commonSources: List, outputs: List, @@ -195,10 +273,10 @@ abstract class KotlinNativeCompilerRunnerImpl @Inject constructor( "-p", "library", "-Xmulti-platform" ) - args.libraries?.flatMap { listOf("-l", it) }?.let { buildArgs.addAll(it) } - args.friendModules?.let { + args.libraries.flatMap { listOf("-l", it.absolutePath) }.let { buildArgs.addAll(it) } + args.friendPaths.ifNotEmpty { buildArgs.add("-friend-modules") - buildArgs.add(it) + buildArgs.add(joinToString(File.pathSeparator)) } if (args.verbose) @@ -206,8 +284,8 @@ abstract class KotlinNativeCompilerRunnerImpl @Inject constructor( if (args.allWarningsAsErrors) buildArgs.add("-Werror") - args.pluginClasspaths?.map { "-Xplugin=$it" }?.let { buildArgs.addAll(it) } - args.pluginOptions?.flatMap { listOf("-P", it) }?.let { buildArgs.addAll(it) } + args.pluginClasspaths.map { "-Xplugin=${it.absolutePath}" }.let { buildArgs.addAll(it) } + args.pluginOptions.flatMap { listOf("-P", it) }.let { buildArgs.addAll(it) } args.languageVersion?.let { buildArgs.add("-language-version") diff --git a/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/tasks/standalone/StandaloneTasks.kt b/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/tasks/standalone/StandaloneTasks.kt index 84762327c6..aade62b2d5 100644 --- a/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/tasks/standalone/StandaloneTasks.kt +++ b/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/tasks/standalone/StandaloneTasks.kt @@ -19,6 +19,11 @@ package com.google.devtools.ksp.gradle.tasks.standalone +import com.google.devtools.ksp.gradle.KotlinCompilerArguments +import com.google.devtools.ksp.gradle.KotlinJsCompilerArguments +import com.google.devtools.ksp.gradle.KotlinJvmCompilerArguments +import com.google.devtools.ksp.gradle.KotlinMetadataCompilerArguments +import com.google.devtools.ksp.gradle.KotlinNativeCompilerArguments import com.google.devtools.ksp.gradle.KspExtension import com.google.devtools.ksp.gradle.KspGradleSubplugin import com.google.devtools.ksp.gradle.KspGradleSubplugin.Companion.getKspCachesDir @@ -58,14 +63,7 @@ import org.gradle.util.GradleVersion import org.gradle.work.ChangeType import org.gradle.work.Incremental import org.gradle.work.InputChanges -import org.jetbrains.kotlin.cli.common.arguments.Argument -import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments -import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments -import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments -import org.jetbrains.kotlin.cli.common.arguments.K2MetadataCompilerArguments -import org.jetbrains.kotlin.cli.common.arguments.K2NativeCompilerArguments import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions -import org.jetbrains.kotlin.gradle.dsl.KotlinJsOptions import org.jetbrains.kotlin.gradle.internal.kapt.incremental.CLASS_STRUCTURE_ARTIFACT_TYPE import org.jetbrains.kotlin.gradle.internal.kapt.incremental.ClasspathSnapshot import org.jetbrains.kotlin.gradle.internal.kapt.incremental.KaptClasspathChanges @@ -86,18 +84,13 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompileCommon import org.jetbrains.kotlin.gradle.tasks.KotlinCompileTool import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile import org.jetbrains.kotlin.incremental.ChangedFiles -import org.jetbrains.kotlin.incremental.classpathAsList -import org.jetbrains.kotlin.incremental.destinationAsFile import org.jetbrains.kotlin.incremental.isJavaFile import org.jetbrains.kotlin.incremental.isKotlinFile -import org.jetbrains.kotlin.library.impl.isKotlinLibrary -import org.jetbrains.kotlin.utils.JsLibraryUtils import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty import org.jetbrains.kotlin.utils.addToStdlib.safeAs import java.io.File import java.nio.file.Paths import javax.inject.Inject -import kotlin.reflect.KProperty1 object StandaloneTasks : KspTaskCreator { override fun createKspTask( @@ -144,6 +137,7 @@ object StandaloneTasks : KspTaskCreator { kspTask.destination = kspOutputDir kspTask.apOptions.value(kspExtension.arguments).disallowChanges() kspTask.kspCacheDir.fileValue(getKspCachesDir(project, sourceSetName, target)).disallowChanges() + kspTask.allWarningAsErrors.value(kspExtension.allWarningsAsErrors) kspTask.isKspIncremental = isIncremental @@ -181,9 +175,11 @@ object StandaloneTasks : KspTaskCreator { if (kotlinCompile is KotlinNativeCompile) { kspTask.commonSources.from(providers.provider { kotlinCompile.commonSources }) kspTask.friendPaths.from(kotlinCompile.compilation.friendPaths) + kspTask.multiplatform.value(true) } else if (kotlinCompile is AbstractKotlinCompile<*>) { kspTask.commonSources.from(providers.provider { kotlinCompile.commonSourceSet }) kspTask.friendPaths.from(kotlinCompile.friendPaths) + kspTask.multiplatform.set(kotlinCompile.multiPlatformEnabled) } else { throw IllegalArgumentException("Unknown compilation task type") } @@ -270,6 +266,12 @@ interface KspTaskStandalone : KspTask { @get:Internal val friendPaths: ConfigurableFileCollection + @get:Input + val multiplatform: Property + + @get:Input + val allWarningAsErrors: Property + fun configureCompilation( kotlinCompilation: KotlinCompilation<*>, kotlinCompile: KotlinCompileTool, @@ -290,7 +292,7 @@ private fun ChangedFiles.hasNonSourceChange(): Boolean { } } -fun CommonCompilerArguments.addChangedClasses(changed: KaptClasspathChanges) { +fun KotlinCompilerArguments.addChangedClasses(changed: KaptClasspathChanges) { if (changed is KaptClasspathChanges.Known) { changed.names.map { it.replace('/', '.').replace('$', '.') }.ifNotEmpty { addPluginOptions(listOf(SubpluginOption("changedClasses", joinToString(":")))) @@ -300,11 +302,11 @@ fun CommonCompilerArguments.addChangedClasses(changed: KaptClasspathChanges) { fun SubpluginOption.toArg() = "plugin:${KspGradleSubplugin.KSP_PLUGIN_ID}:$key=$value" -fun CommonCompilerArguments.addPluginOptions(options: List) { - pluginOptions = ((pluginOptions?.toList() ?: emptyList()) + options.map { it.toArg() }).toTypedArray() +fun KotlinCompilerArguments.addPluginOptions(options: List) { + pluginOptions += options.map { it.toArg() } } -fun CommonCompilerArguments.addChangedFiles(changedFiles: ChangedFiles) { +fun KotlinCompilerArguments.addChangedFiles(changedFiles: ChangedFiles) { if (changedFiles is ChangedFiles.Known) { val options = mutableListOf() changedFiles.modified.filter { it.isKotlinFile(listOf("kt")) || it.isJavaFile() }.ifNotEmpty { @@ -317,32 +319,6 @@ fun CommonCompilerArguments.addChangedFiles(changedFiles: ChangedFiles) { } } -private fun CommonCompilerArguments.blockOtherPlugins(kspPluginClasspath: FileCollection) { - pluginClasspaths = kspPluginClasspath.map { it.canonicalPath }.toTypedArray() - pluginOptions = arrayOf() -} - -// TODO: Move into dumpArgs after the compiler supports local function in inline functions. -private inline fun T.toPair(property: KProperty1): Pair { - @Suppress("UNCHECKED_CAST") - val value = property.get(this) - return property.name to if (value is Array<*>) - value.asList().toString() - else - value.toString() -} - -@Suppress("unused") -internal inline fun dumpArgs(args: T): Map { - @Suppress("UNCHECKED_CAST") - val argumentProperties = - args::class.members.mapNotNull { member -> - (member as? KProperty1)?.takeIf { it.annotations.any { ann -> ann is Argument } } - } - - return argumentProperties.associate(args::toPair).toSortedMap() -} - internal fun File.isParentOf(childCandidate: File): Boolean { val parentPath = Paths.get(this.absolutePath).normalize() val childCandidatePath = Paths.get(childCandidate.absolutePath).normalize() @@ -350,6 +326,19 @@ internal fun File.isParentOf(childCandidate: File): Boolean { return childCandidatePath.startsWith(parentPath) } +private fun KotlinCompilerArguments.fromTask(task: KspTaskStandalone) { + useK2 = false + incrementalCompilation = false + pluginClasspaths = task.pluginClasspath.files.toList() + apiVersion = task.kotlinApiVersion.orNull + languageVersion = task.kotlinLanguageVersion.orNull + verbose = task.verbose.get() + multiPlatform = task.multiplatform.get() + allWarningsAsErrors = task.allWarningAsErrors.get() + + addPluginOptions(task.options.get()) +} + @CacheableTask abstract class KspTaskJvm @Inject constructor( objectFactory: ObjectFactory, @@ -386,25 +375,18 @@ abstract class KspTaskJvm @Inject constructor( @TaskAction fun execute(inputChanges: InputChanges) { - val args = K2JVMCompilerArguments().apply { + val args = KotlinJvmCompilerArguments().apply { // Common - useK2 = false - incrementalCompilation = false - pluginClasspaths = pluginClasspath.files.map { it.absolutePath }.toTypedArray() - apiVersion = this@KspTaskJvm.kotlinApiVersion.orNull - languageVersion = this@KspTaskJvm.kotlinLanguageVersion.orNull - verbose = this@KspTaskJvm.verbose.get() - noJdk = this@KspTaskJvm.noJdk.get() - - addPluginOptions(options.get()) + fromTask(this@KspTaskJvm) // JVM + noJdk = this@KspTaskJvm.noJdk.get() allowNoSourceFiles = true - destinationAsFile = this@KspTaskJvm.destination + destination = this@KspTaskJvm.destination noReflect = true noStdlib = true - classpathAsList = libraries.files.toList() - friendPaths = this@KspTaskJvm.friendPaths.map { it.absolutePath }.toTypedArray() + libraries = this@KspTaskJvm.libraries.files.toList() + friendPaths = this@KspTaskJvm.friendPaths.files.toList() moduleName = this@KspTaskJvm.moduleName.get() } @@ -553,15 +535,6 @@ abstract class KspTaskJvm @Inject constructor( abstract class KspTaskJs @Inject constructor( objectFactory: ObjectFactory, ) : KspTaskStandalone, CompileUsingKotlinDaemon, DefaultTask() { - // TODO: setup by checking target info, instead of copying from compile task - private val backendSelectionArgs = listOf( - "-Xir-only", - "-Xir-produce-js", - "-Xir-produce-klib-dir", - "-Xir-produce-klib-file", - "-Xwasm" - ) - @get:Nested val compilerRunner = createKotlinJsCompilerRunner(this, objectFactory) @@ -575,33 +548,29 @@ abstract class KspTaskJs @Inject constructor( commonSources, ) - private fun isJsLib(file: File): Boolean = - file.exists() && when (backend.get()) { - JS_BACKEND.JS_IR -> isKotlinLibrary(file) - JS_BACKEND.JS_LEGACY -> JsLibraryUtils.isKotlinJavascriptLibrary(file) - JS_BACKEND.JS_BOTH -> JsLibraryUtils.isKotlinJavascriptLibrary(file) && isKotlinLibrary(file) - } - @TaskAction fun execute(inputChanges: InputChanges) { - val args = K2JSCompilerArguments().apply { + val args = KotlinJsCompilerArguments().apply { // Common - useK2 = false - incrementalCompilation = false - pluginClasspaths = pluginClasspath.files.map { it.absolutePath }.toTypedArray() - apiVersion = this@KspTaskJs.kotlinApiVersion.orNull - languageVersion = this@KspTaskJs.kotlinLanguageVersion.orNull - verbose = this@KspTaskJs.verbose.get() - - addPluginOptions(options.get()) + fromTask(this@KspTaskJs) // JS destination = this@KspTaskJs.destination noStdlib = true - libraries = this@KspTaskJs.libraries.filter { isJsLib(it) }.asPath - freeArgs = this@KspTaskJs.freeArgs.get() - outputFile = File(destination, "dummyOutput.js").canonicalPath - friendModules = this@KspTaskJs.friendPaths.filter { isJsLib(it) }.asPath + libraries = this@KspTaskJs.libraries.files.toList() + friendPaths = this@KspTaskJs.friendPaths.files.toList() + destination = File(destination, "dummyOutput.js") + + this@KspTaskJs.freeArgs.get().forEach { + when (it) { + "-Xir-only" -> irOnly = true + "-Xir-produce-js" -> irProduceJs = true + "-Xir-produce-klib-file" -> irProduceKlibFile = true + "-Xir-produce-klib-dir" -> irProduceKlibDir = true + "-Xir-build-cache" -> irBuildCache = true + "-Xwasm" -> wasm = true + } + } } // Clean outputs. Backups will be copied back if incremental. @@ -627,9 +596,6 @@ abstract class KspTaskJs @Inject constructor( ) } - @get:Internal - abstract val backend: Property - override fun configureCompilation( kotlinCompilation: KotlinCompilation<*>, kotlinCompile: KotlinCompileTool, @@ -642,45 +608,8 @@ abstract class KspTaskJs @Inject constructor( compilerRunner.useDaemonFallbackStrategy.set(kotlinCompile.useDaemonFallbackStrategy) compilerRunner.kotlinDaemonJvmArguments.set(kotlinCompile.kotlinDaemonJvmArguments) - val kotlinJsOptions = kotlinCompilation.kotlinOptions as KotlinJsOptions - backend.value( - when { - kotlinJsOptions.isIrBackendEnabled() && kotlinJsOptions.isPreIrBackendDisabled() -> - JS_BACKEND.JS_IR - !kotlinJsOptions.isIrBackendEnabled() && !kotlinJsOptions.isPreIrBackendDisabled() -> - JS_BACKEND.JS_LEGACY - kotlinJsOptions.isIrBackendEnabled() && !kotlinJsOptions.isPreIrBackendDisabled() -> - JS_BACKEND.JS_BOTH - else -> throw IllegalArgumentException("Unknown JS backend") - } - ) - freeArgs.value( - (kotlinCompile as Kotlin2JsCompile).kotlinOptions.freeCompilerArgs.filter { - it in backendSelectionArgs - } - ) - } - - enum class JS_BACKEND { - JS_IR, - JS_LEGACY, - JS_BOTH + freeArgs.value(kotlinCompilation.kotlinOptions.freeCompilerArgs) } - - private fun KotlinJsOptions.isPreIrBackendDisabled(): Boolean = - listOf( - "-Xir-only", - "-Xir-produce-js", - "-Xir-produce-klib-file" - ).any(freeCompilerArgs::contains) - - // see also isIncrementalCompilationEnabled - private fun KotlinJsOptions.isIrBackendEnabled(): Boolean = - listOf( - "-Xir-produce-klib-dir", - "-Xir-produce-js", - "-Xir-produce-klib-file" - ).any(freeCompilerArgs::contains) } @CacheableTask @@ -699,23 +628,15 @@ abstract class KspTaskMetadata @Inject constructor( @TaskAction fun execute(inputChanges: InputChanges) { - val args = K2MetadataCompilerArguments().apply { + val args = KotlinMetadataCompilerArguments().apply { // Common - useK2 = false - incrementalCompilation = false - pluginClasspaths = pluginClasspath.files.map { it.absolutePath }.toTypedArray() - apiVersion = this@KspTaskMetadata.kotlinApiVersion.orNull - languageVersion = this@KspTaskMetadata.kotlinLanguageVersion.orNull - verbose = this@KspTaskMetadata.verbose.get() - - addPluginOptions(options.get()) + fromTask(this@KspTaskMetadata) // Metadata - destination = this@KspTaskMetadata.destination.absolutePath - classpath = this@KspTaskMetadata.libraries.joinToString(":") - multiPlatform = true + destination = this@KspTaskMetadata.destination + libraries = this@KspTaskMetadata.libraries.files.toList() + friendPaths = this@KspTaskMetadata.friendPaths.files.toList() expectActualLinker = true - friendPaths = this@KspTaskMetadata.friendPaths.map { it.absolutePath }.toTypedArray() } // Clean outputs. Backups will be copied back if incremental. @@ -774,23 +695,15 @@ abstract class KspTaskNative @Inject constructor( @TaskAction fun execute(inputChanges: InputChanges) { - val args = K2NativeCompilerArguments().apply { + val args = KotlinNativeCompilerArguments().apply { // Common - useK2 = false - incrementalCompilation = false - pluginClasspaths = pluginClasspath.files.map { it.absolutePath }.toTypedArray() - apiVersion = this@KspTaskNative.kotlinApiVersion.orNull - languageVersion = this@KspTaskNative.kotlinLanguageVersion.orNull - verbose = this@KspTaskNative.verbose.get() - - addPluginOptions(options.get()) + fromTask(this@KspTaskNative) // Native destination = this@KspTaskNative.destination - libraries = this@KspTaskNative.libraries.map { it.absolutePath }.toTypedArray() - multiPlatform = true + libraries = this@KspTaskNative.libraries.files.toList() expectActualLinker = true - friendModules = this@KspTaskNative.friendPaths.asPath + friendPaths = this@KspTaskNative.friendPaths.files.toList() target = this@KspTaskNative.target.get() }