[Gradle] KotlinCompileCommon: Implement KotlinCompilerArgumentsProducer

KTIJ-24976
This commit is contained in:
Sebastian Sellmair
2023-03-21 11:21:31 +01:00
committed by Space Team
parent ff0b070398
commit 16cce7516e
6 changed files with 147 additions and 23 deletions
@@ -104,13 +104,9 @@ internal open class GradleCompilerRunner(
* @see [GradleKotlinCompilerWork]
*/
fun runMetadataCompilerAsync(
kotlinSources: List<File>,
kotlinCommonSources: List<File>,
args: K2MetadataCompilerArguments,
environment: GradleCompilerEnvironment
): WorkQueue? {
args.freeArgs += kotlinSources.map { it.absolutePath }
args.commonSources = kotlinCommonSources.map { it.absolutePath }.toTypedArray()
return runCompilerAsync(KotlinCompilerClass.METADATA, args, environment)
}
@@ -222,14 +222,13 @@ abstract class Kotlin2JsCompile @Inject constructor(
contribute(KotlinCompilerArgumentsProducer.ArgumentType.DependencyClasspath) { args ->
args.friendModules = friendDependencies.files.joinToString(File.pathSeparator) { it.absolutePath }
val dependencies = libraries
.filter { it.exists() && libraryFilter(it) }
.map { it.normalize().absolutePath }
args.libraries = dependencies.distinct().let {
if (it.isNotEmpty())
it.joinToString(File.pathSeparator) else
null
args.libraries = tryLenient {
libraries
.filter { it.exists() && libraryFilter(it) }
.map { it.normalize().absolutePath }
.toSet()
.takeIf { it.isNotEmpty() }
?.joinToString(File.pathSeparator)
}
}
@@ -17,11 +17,13 @@
package org.jetbrains.kotlin.gradle.tasks
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.FileCollection
import org.gradle.api.model.ObjectFactory
import org.gradle.api.tasks.*
import org.gradle.work.InputChanges
import org.gradle.work.NormalizeLineEndings
import org.gradle.workers.WorkerExecutor
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.K2MetadataCompilerArguments
import org.jetbrains.kotlin.compilerRunner.GradleCompilerEnvironment
import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl
@@ -29,7 +31,12 @@ import org.jetbrains.kotlin.gradle.dsl.*
import org.jetbrains.kotlin.gradle.internal.tasks.allOutputFiles
import org.jetbrains.kotlin.gradle.logging.GradleErrorMessageCollector
import org.jetbrains.kotlin.gradle.logging.GradlePrintingMessageCollector
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilerArgumentsProducer
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilerArgumentsProducer.CreateCompilerArgumentsContext
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilerArgumentsProducer.CreateCompilerArgumentsContext.Companion.create
import org.jetbrains.kotlin.gradle.report.BuildReportMode
import org.jetbrains.kotlin.gradle.tasks.internal.KotlinMultiplatformCommonOptionsCompat
import org.jetbrains.kotlin.gradle.utils.toPathsArray
import java.io.File
import javax.inject.Inject
@@ -40,6 +47,7 @@ abstract class KotlinCompileCommon @Inject constructor(
objectFactory: ObjectFactory
) : AbstractKotlinCompile<K2MetadataCompilerArguments>(objectFactory, workerExecutor),
KotlinCompilationTask<KotlinMultiplatformCommonCompilerOptions>,
KotlinCompilerArgumentsProducer,
KotlinCommonCompile {
init {
@@ -76,10 +84,14 @@ abstract class KotlinCompileCommon @Inject constructor(
if (defaultsOnly) return
val classpathList = libraries.files.filter { it.exists() }.toMutableList()
val classpathList = try {
libraries.files.filter { it.exists() }.toMutableList()
} catch (t: Throwable) {
if (ignoreClasspathResolutionErrors) null else throw t
}
with(args) {
classpath = classpathList.joinToString(File.pathSeparator)
classpath = classpathList?.joinToString(File.pathSeparator)
destination = destinationDirectory.get().asFile.normalize().absolutePath
friendPaths = this@KotlinCompileCommon.friendPaths.files.map { it.absolutePath }.toTypedArray()
@@ -94,6 +106,51 @@ abstract class KotlinCompileCommon @Inject constructor(
}
}
override fun createCompilerArguments(context: CreateCompilerArgumentsContext) = context.create<K2MetadataCompilerArguments> {
contribute(KotlinCompilerArgumentsProducer.ArgumentType.Primitive) { args ->
args.multiPlatform = multiPlatformEnabled.get()
args.moduleName = this@KotlinCompileCommon.moduleName.get()
args.pluginOptions = (pluginOptions.toSingleCompilerPluginOptions() + kotlinPluginData?.orNull?.options)
.arguments.toTypedArray()
if (reportingSettings().buildReportMode == BuildReportMode.VERBOSE) {
args.reportPerf = true
}
args.expectActualLinker = expectActualLinker.get()
args.destination = destinationDirectory.get().asFile.normalize().absolutePath
KotlinCommonCompilerOptionsHelper.fillCompilerArguments(compilerOptions, args)
val localExecutionTimeFreeCompilerArgs = executionTimeFreeCompilerArgs
if (localExecutionTimeFreeCompilerArgs != null) {
args.freeArgs = localExecutionTimeFreeCompilerArgs
}
}
contribute(KotlinCompilerArgumentsProducer.ArgumentType.PluginClasspath) { args ->
args.pluginClasspaths = tryLenient {
listOfNotNull(
pluginClasspath, kotlinPluginData?.orNull?.classpath
).reduce(FileCollection::plus).toPathsArray()
}
}
contribute(KotlinCompilerArgumentsProducer.ArgumentType.DependencyClasspath) { args ->
args.classpath = tryLenient { libraries.files.filter { it.exists() }.joinToString(File.pathSeparator) }
args.friendPaths = tryLenient { this@KotlinCompileCommon.friendPaths.files.toPathsArray() }
args.refinesPaths = refinesMetadataPaths.toPathsArray()
}
contribute(KotlinCompilerArgumentsProducer.ArgumentType.Sources) { args ->
args.freeArgs += sources.asFileTree.map { it.absolutePath }
args.commonSources = commonSourceSet.asFileTree.toPathsArray()
}
}
@get:PathSensitive(PathSensitivity.RELATIVE)
@get:IgnoreEmptyDirectories
@get:InputFiles
@@ -118,12 +175,7 @@ abstract class KotlinCompileCommon @Inject constructor(
reportingSettings = reportingSettings(),
outputFiles = allOutputFiles()
)
compilerRunner.runMetadataCompilerAsync(
kotlinSources.toList(),
commonSourceSet.files.toList(),
args,
environment
)
compilerRunner.runMetadataCompilerAsync(args, environment)
compilerRunner.errorsFile?.also { gradleMessageCollector.flush(it) }
}
}
@@ -13,17 +13,22 @@ import org.jetbrains.kotlin.gradle.dependencyResolutionTests.mavenCentralCacheRe
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.internal.prepareCompilerArguments
import org.jetbrains.kotlin.gradle.plugin.CreateCompilerArgumentsContext
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilerArgumentsProducer
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilerArgumentsProducer.ArgumentType
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilerArgumentsProducer.CreateCompilerArgumentsContext.Companion.default
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilerArgumentsProducer.CreateCompilerArgumentsContext.Companion.lenient
import org.jetbrains.kotlin.gradle.plugin.KotlinJsCompilerType
import org.jetbrains.kotlin.gradle.util.buildProjectWithMPP
import org.jetbrains.kotlin.gradle.util.main
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFails
import kotlin.test.assertNull
class JsCompilerArgumentTests {
class Kotlin2JsCompileArgumentsTest {
@Suppress("DEPRECATION")
@Test
fun `test - simple project`() {
fun `test - simple project - old CompilerArgumentsAware and new CompilerArgumentsProducer - return same arguments`() {
val project = buildProjectWithMPP {
repositories {
mavenLocal()
@@ -50,4 +55,18 @@ class JsCompilerArgumentTests {
ArgumentUtils.convertArgumentsToStringList(argumentsFromCompilerArgumentsProducer),
)
}
@Test
fun `test - simple project - failing dependency - lenient`() {
val project = buildProjectWithMPP()
val kotlin = project.multiplatformExtension
val jsTarget = kotlin.js()
kotlin.sourceSets.getByName("commonMain").dependencies { implementation("not-a:dependency:1.0.0") }
project.evaluate()
val jsMainCompileTask = jsTarget.compilations.main.compileTaskProvider.get()
assertNull(jsMainCompileTask.createCompilerArguments(lenient).libraries)
assertFails { jsMainCompileTask.createCompilerArguments(default) }
}
}
@@ -28,7 +28,7 @@ import kotlin.reflect.full.findAnnotation
import kotlin.test.*
class JvmCompilerArgumentsTest {
class KotlinCompileArgumentsTest {
@Suppress("DEPRECATION")
@Test
@@ -0,0 +1,58 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@file:Suppress("FunctionName")
package org.jetbrains.kotlin.gradle.unitTests.compilerArgumetns
import org.jetbrains.kotlin.compilerRunner.ArgumentUtils
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.internal.prepareCompilerArguments
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilerArgumentsProducer.CreateCompilerArgumentsContext
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilerArgumentsProducer.CreateCompilerArgumentsContext.Companion.lenient
import org.jetbrains.kotlin.gradle.tasks.KotlinCompileCommon
import org.jetbrains.kotlin.gradle.util.buildProjectWithMPP
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFails
import kotlin.test.assertNull
class KotlinCompileCommonArgumentsTest {
@Test
@Suppress("DEPRECATION")
fun `test - simple project - old CompilerArgumentsAware and new CompilerArgumentsProducer - return same arguments`() {
val project = buildProjectWithMPP()
project.repositories.mavenLocal()
val kotlin = project.multiplatformExtension
kotlin.jvm()
kotlin.linuxX64()
project.evaluate()
val commonMainCompilation = kotlin.metadata().compilations.getByName("commonMain")
val commonMainCompileTask = commonMainCompilation.compileTaskProvider.get() as KotlinCompileCommon
val argumentsFromCompilerArgumentsProducer = commonMainCompileTask.createCompilerArguments(lenient)
val argumentsFromCompilerArgumentsAware = commonMainCompileTask.prepareCompilerArguments(true)
assertEquals(
ArgumentUtils.convertArgumentsToStringList(argumentsFromCompilerArgumentsAware),
ArgumentUtils.convertArgumentsToStringList(argumentsFromCompilerArgumentsProducer)
)
}
@Test
fun `test - simple project - failing dependency - lenient`() {
val project = buildProjectWithMPP()
val kotlin = project.multiplatformExtension
kotlin.jvm()
kotlin.linuxX64()
kotlin.sourceSets.getByName("commonMain").dependencies { implementation("not-a:dependency:1.0.0") }
project.evaluate()
val commonMainCompileTask = kotlin.metadata().compilations.getByName("commonMain").compileTaskProvider.get() as KotlinCompileCommon
assertNull(commonMainCompileTask.createCompilerArguments(lenient).classpath)
assertFails { commonMainCompileTask.createCompilerArguments(CreateCompilerArgumentsContext.default) }
}
}