[Gradle] KaptGenerateStubsTask: Implement KotlinCompilerArgumentsProducer

KTIJ-24976
This commit is contained in:
Sebastian Sellmair
2023-03-22 10:22:35 +01:00
committed by Space Team
parent 6455f602a0
commit e76f3fb925
5 changed files with 45 additions and 163 deletions
@@ -1,103 +0,0 @@
/*
* Copyright 2010-2020 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.
*/
package org.jetbrains.kotlin.gradle.internal
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompilerOptionsHelper
import org.jetbrains.kotlin.gradle.logging.kotlinDebug
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
import org.jetbrains.kotlin.gradle.tasks.KotlinCompileArgumentsProvider
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompilerArgumentsProvider
import org.jetbrains.kotlin.gradle.utils.toPathsArray
import org.jetbrains.kotlin.incremental.classpathAsList
import org.jetbrains.kotlin.incremental.destinationAsFile
internal interface CompilerArgumentsContributor<in T : CommonToolArguments> {
fun contributeArguments(
args: T,
flags: Collection<CompilerArgumentsConfigurationFlag>
)
}
internal interface CompilerArgumentsConfigurationFlag
internal object DefaultsOnly : CompilerArgumentsConfigurationFlag
internal object IgnoreClasspathResolutionErrors : CompilerArgumentsConfigurationFlag
internal fun compilerArgumentsConfigurationFlags(defaultsOnly: Boolean, ignoreClasspathResolutionErrors: Boolean) =
mutableSetOf<CompilerArgumentsConfigurationFlag>().apply {
if (defaultsOnly) add(DefaultsOnly)
if (ignoreClasspathResolutionErrors) add(IgnoreClasspathResolutionErrors)
}
/** The primary purpose of this class is to encapsulate compiler arguments setup done by the AbstractKotlinCompiler tasks,
* but outside the tasks, so that this state & logic can be reused without referencing the task directly. */
internal open class AbstractKotlinCompileArgumentsContributor<T : CommonCompilerArguments>(
// Don't save this reference into a property! That would be hostile to Gradle instant execution
taskProvider: KotlinCompileArgumentsProvider<out AbstractKotlinCompile<T>>
) : CompilerArgumentsContributor<T> {
protected val logger = taskProvider.logger
private val isMultiplatform = taskProvider.isMultiplatform
private val pluginClasspath = taskProvider.pluginClasspath
private val pluginOptions = taskProvider.pluginOptions
override fun contributeArguments(
args: T,
flags: Collection<CompilerArgumentsConfigurationFlag>
) {
args.multiPlatform = isMultiplatform
setupPlugins(args)
}
internal fun setupPlugins(compilerArgs: T) {
compilerArgs.pluginClasspaths = pluginClasspath.toPathsArray()
compilerArgs.pluginOptions = pluginOptions.arguments.toTypedArray()
}
}
internal open class KotlinJvmCompilerArgumentsContributor(
// Don't save this reference into a property! That would be hostile to Gradle instant execution. Only map it to the task properties.
taskProvider: KotlinJvmCompilerArgumentsProvider
) : AbstractKotlinCompileArgumentsContributor<K2JVMCompilerArguments>(taskProvider) {
private val taskName = taskProvider.taskName
private val friendPaths = taskProvider.friendPaths
private val compileClasspath = taskProvider.compileClasspath
private val destinationDir = taskProvider.destinationDir
private val compilerOptions = taskProvider.compilerOptions
override fun contributeArguments(
args: K2JVMCompilerArguments,
flags: Collection<CompilerArgumentsConfigurationFlag>
) {
KotlinJvmCompilerOptionsHelper.fillDefaultValues(args)
super.contributeArguments(args, flags)
args.moduleName = compilerOptions.moduleName.orNull
logger.kotlinDebug { "$taskName | args.moduleName = ${args.moduleName}" }
args.friendPaths = friendPaths.files.map { it.absolutePath }.toTypedArray()
logger.kotlinDebug { "$taskName | args.friendPaths = ${args.friendPaths?.joinToString() ?: "[]"}" }
if (DefaultsOnly in flags) return
args.allowNoSourceFiles = true
args.classpathAsList = try {
compileClasspath.toList().filter { it.exists() }
} catch (e: Exception) {
if (IgnoreClasspathResolutionErrors in flags) emptyList() else throw(e)
}
args.destinationAsFile = destinationDir
KotlinJvmCompilerOptionsHelper.fillCompilerArguments(compilerOptions, args)
logger.kotlinDebug { "$taskName | args.moduleName = ${args.moduleName} (w/ compilerOptions applied)" }
}
}
@@ -25,12 +25,17 @@ import org.gradle.work.Incremental
import org.gradle.work.NormalizeLineEndings
import org.gradle.workers.WorkerExecutor
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompilerOptions
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompilerOptionsDefault
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompilerOptionsHelper
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.KaptGenerateStubs
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jetbrains.kotlin.gradle.tasks.toSingleCompilerPluginOptions
import org.jetbrains.kotlin.gradle.utils.toPathsArray
import org.jetbrains.kotlin.incremental.classpathAsList
import org.jetbrains.kotlin.incremental.destinationAsFile
import javax.inject.Inject
@@ -94,39 +99,48 @@ abstract class KaptGenerateStubsTask @Inject constructor(
)
@get:Internal
internal abstract val compileKotlinArgumentsContributor: Property<CompilerArgumentsContributor<K2JVMCompilerArguments>>
internal abstract val compileTaskCompilerOptions: Property<KotlinJvmCompilerOptions>
override fun setupCompilerArgs(
args: K2JVMCompilerArguments,
defaultsOnly: Boolean,
ignoreClasspathResolutionErrors: Boolean
) {
compileKotlinArgumentsContributor.get().contributeArguments(
args,
compilerArgumentsConfigurationFlags(
defaultsOnly,
ignoreClasspathResolutionErrors
)
)
override fun createCompilerArguments(context: CreateCompilerArgumentsContext) = context.create<K2JVMCompilerArguments> {
contribute(KotlinCompilerArgumentsProducer.ArgumentType.Primitive) { args ->
args.allowNoSourceFiles = true
KotlinJvmCompilerOptionsHelper.fillCompilerArguments(compileTaskCompilerOptions.get(), args)
// Workaround for freeCompiler args duplication when they were configured for both this task
// and linked KotlinCompile task with the same values. For now linked KotlinCompile task
// freeCompilerArgs is used as convention for this task freeCompilerArgs
args.freeArgs = emptyList()
// Also use KotlinOptions configuration that was directly set to this task
// as 'compileKotlinArgumentsContributor' has KotlinOptions from linked KotlinCompile task
KotlinJvmCompilerOptionsHelper.fillCompilerArguments(compilerOptions, args)
// Workaround for freeCompiler args duplication when they were configured for both this task
// and linked KotlinCompile task with the same values. For now linked KotlinCompile task
// freeCompilerArgs is used as convention for this task freeCompilerArgs
args.freeArgs = emptyList()
KotlinJvmCompilerOptionsHelper.fillCompilerArguments(compilerOptions, args)
// Copied from KotlinCompile
if (reportingSettings().buildReportMode == BuildReportMode.VERBOSE) {
args.reportPerf = true
// Copied from KotlinCompile
if (reportingSettings().buildReportMode == BuildReportMode.VERBOSE) {
args.reportPerf = true
}
val pluginOptionsWithKapt = pluginOptions.toSingleCompilerPluginOptions()
.withWrappedKaptOptions(withApClasspath = kaptClasspath)
args.pluginOptions = (pluginOptionsWithKapt.arguments).toTypedArray()
args.verbose = verbose.get()
args.destinationAsFile = destinationDirectory.get().asFile
}
val pluginOptionsWithKapt = pluginOptions.toSingleCompilerPluginOptions().withWrappedKaptOptions(withApClasspath = kaptClasspath)
args.pluginOptions = (pluginOptionsWithKapt.arguments).toTypedArray()
contribute(KotlinCompilerArgumentsProducer.ArgumentType.PluginClasspath) { args ->
args.pluginClasspaths = tryLenient {
listOfNotNull(
pluginClasspath, kotlinPluginData?.orNull?.classpath
).reduce(FileCollection::plus).toPathsArray()
}
}
args.verbose = verbose.get()
args.classpathAsList = this.libraries.filter { it.exists() }.toList()
args.destinationAsFile = this.destinationDirectory.get().asFile
contribute(KotlinCompilerArgumentsProducer.ArgumentType.DependencyClasspath) { args ->
args.classpathAsList = tryLenient { libraries.toList().filter { it.exists() } }.orEmpty()
args.friendPaths = friendPaths.toPathsArray()
}
contribute(KotlinCompilerArgumentsProducer.ArgumentType.Sources) { args ->
args.freeArgs += (scriptSources.asFileTree.files + javaSources.files + sources.asFileTree.files).map { it.absolutePath }
}
}
}
@@ -32,8 +32,6 @@ import org.jetbrains.kotlin.compilerRunner.UsesCompilerSystemPropertiesService
import org.jetbrains.kotlin.daemon.common.MultiModuleICSettings
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonCompilerOptions
import org.jetbrains.kotlin.gradle.incremental.UsesIncrementalModuleInfoBuildService
import org.jetbrains.kotlin.gradle.internal.AbstractKotlinCompileArgumentsContributor
import org.jetbrains.kotlin.gradle.internal.compilerArgumentsConfigurationFlags
import org.jetbrains.kotlin.gradle.internal.tasks.allOutputFiles
import org.jetbrains.kotlin.gradle.logging.GradleKotlinLogger
import org.jetbrains.kotlin.gradle.logging.kotlinDebug
@@ -354,21 +352,4 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> @Inject constr
inputChanges: InputChanges,
taskOutputsBackup: TaskOutputsBackup?
)
@get:Internal
internal val abstractKotlinCompileArgumentsContributor by lazy {
AbstractKotlinCompileArgumentsContributor(
KotlinCompileArgumentsProvider(this)
)
}
override fun setupCompilerArgs(args: T, defaultsOnly: Boolean, ignoreClasspathResolutionErrors: Boolean) {
abstractKotlinCompileArgumentsContributor.contributeArguments(
args,
compilerArgumentsConfigurationFlags(defaultsOnly, ignoreClasspathResolutionErrors)
)
if (reportingSettings().buildReportMode == BuildReportMode.VERBOSE) {
args.reportPerf = true
}
}
}
@@ -33,9 +33,6 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompilerOptions
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompilerOptionsHelper
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
import org.jetbrains.kotlin.gradle.dsl.usesK2
import org.jetbrains.kotlin.gradle.internal.CompilerArgumentsContributor
import org.jetbrains.kotlin.gradle.internal.KotlinJvmCompilerArgumentsContributor
import org.jetbrains.kotlin.gradle.internal.compilerArgumentsConfigurationFlags
import org.jetbrains.kotlin.gradle.internal.tasks.allOutputFiles
import org.jetbrains.kotlin.gradle.logging.GradleErrorMessageCollector
import org.jetbrains.kotlin.gradle.logging.GradlePrintingMessageCollector
@@ -220,11 +217,6 @@ abstract class KotlinCompile @Inject constructor(
@get:Internal
internal var executionTimeFreeCompilerArgs: List<String>? = null
@get:Internal
internal val compilerArgumentsContributor: CompilerArgumentsContributor<K2JVMCompilerArguments> by lazy {
KotlinJvmCompilerArgumentsContributor(KotlinJvmCompilerArgumentsProvider(this))
}
override fun createCompilerArguments(
context: KotlinCompilerArgumentsProducer.CreateCompilerArgumentsContext
): K2JVMCompilerArguments = context.create<K2JVMCompilerArguments> {
@@ -41,7 +41,7 @@ internal class KaptGenerateStubsConfig : BaseKotlinCompileConfig<KaptGenerateStu
task.useModuleDetection.value(kotlinCompileTask.useModuleDetection).disallowChanges()
task.moduleName.value(kotlinCompileTask.moduleName).disallowChanges()
task.libraries.from({ kotlinCompileTask.libraries - project.files(kaptClassesDir) })
task.compileKotlinArgumentsContributor.set(providers.provider { kotlinCompileTask.compilerArgumentsContributor })
task.compileTaskCompilerOptions.set(providers.provider { kotlinCompileTask.compilerOptions })
task.pluginOptions.addAll(kotlinCompileTask.pluginOptions)
task.compilerOptions.moduleName.convention(kotlinCompileTask.compilerOptions.moduleName)
task.compilerOptions.freeCompilerArgs.convention(kotlinCompileTask.compilerOptions.freeCompilerArgs)
@@ -74,10 +74,8 @@ internal class KaptGenerateStubsConfig : BaseKotlinCompileConfig<KaptGenerateStu
constructor(project: Project, ext: KotlinTopLevelExtension, kaptExtension: KaptExtension) : super(project, ext) {
configureFromExtension(kaptExtension)
configureTask { task ->
task.compileKotlinArgumentsContributor.set(
providers.provider {
KotlinJvmCompilerArgumentsContributor(KotlinJvmCompilerArgumentsProvider(task))
}
task.compileTaskCompilerOptions.set(
providers.provider { task.compilerOptions }
)
}
}