Update KotlinCompile task to use compiler options

For Android extension temporary solution via KotlinJvmOptions is
provided.

^KT-27301 In Progress
This commit is contained in:
Yahor Berdnikau
2022-09-11 13:38:18 +02:00
parent 0c189de77f
commit b2f03f6224
13 changed files with 134 additions and 157 deletions
@@ -25,7 +25,11 @@ interface KotlinJvmFactory {
/** Instance of DSL object that should be used to configure Kotlin compilation pipeline. */ /** Instance of DSL object that should be used to configure Kotlin compilation pipeline. */
val kotlinExtension: KotlinTopLevelExtensionConfig val kotlinExtension: KotlinTopLevelExtensionConfig
/** Creates instance of DSL object that should be used to configure JVM/android specific compilation. */ /**
* Creates instance of DSL object that should be used to configure JVM/android specific compilation.
*
* Note: [CompilerJvmOptions] instance inside [KotlinJvmOptions] is not the same as returned by [createCompilerJvmOptions]
*/
@Deprecated( @Deprecated(
message = "Replaced by compilerJvmOptions", message = "Replaced by compilerJvmOptions",
replaceWith = ReplaceWith("createCompilerJvmOptions()") replaceWith = ReplaceWith("createCompilerJvmOptions()")
@@ -78,7 +78,7 @@ class SimpleKotlinGradleIT : KGPBaseTest() {
fun testJvmTarget(gradleVersion: GradleVersion) { fun testJvmTarget(gradleVersion: GradleVersion) {
project("jvmTarget", gradleVersion) { project("jvmTarget", gradleVersion) {
buildAndFail("build") { buildAndFail("build") {
assertOutputContains("Unknown JVM target version: 1.7") assertOutputContains("Unknown Kotlin JVM target: 1.7")
} }
} }
} }
@@ -16,47 +16,28 @@
package org.jetbrains.kotlin.gradle.internal package org.jetbrains.kotlin.gradle.internal
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Internal import org.gradle.api.tasks.Internal
import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments
import org.jetbrains.kotlin.compilerRunner.ArgumentUtils import org.jetbrains.kotlin.compilerRunner.ArgumentUtils
interface CompilerArgumentAware<T : CommonToolArguments> { interface CompilerArgumentAware<T : CommonToolArguments> {
@get:Internal
val serializedCompilerArguments: List<String> val serializedCompilerArguments: List<String>
get() = ArgumentUtils.convertArgumentsToStringList(prepareCompilerArguments()) get() = ArgumentUtils.convertArgumentsToStringList(prepareCompilerArguments())
@get:Internal
val serializedCompilerArgumentsIgnoreClasspathIssues: List<String> val serializedCompilerArgumentsIgnoreClasspathIssues: List<String>
get() = ArgumentUtils.convertArgumentsToStringList(prepareCompilerArguments(ignoreClasspathResolutionErrors = true)) get() = ArgumentUtils.convertArgumentsToStringList(prepareCompilerArguments(ignoreClasspathResolutionErrors = true))
@get:Internal
val defaultSerializedCompilerArguments: List<String> val defaultSerializedCompilerArguments: List<String>
get() = createCompilerArgs() get() = createCompilerArgs()
.also { setupCompilerArgs(it, defaultsOnly = true) } .also { setupCompilerArgs(it, defaultsOnly = true) }
.let(ArgumentUtils::convertArgumentsToStringList) .let(ArgumentUtils::convertArgumentsToStringList)
val filteredArgumentsMap: Map<String, String>
get() = CompilerArgumentsGradleInput.createInputsMap(prepareCompilerArguments())
fun createCompilerArgs(): T fun createCompilerArgs(): T
fun setupCompilerArgs(args: T, defaultsOnly: Boolean = false, ignoreClasspathResolutionErrors: Boolean = false) fun setupCompilerArgs(args: T, defaultsOnly: Boolean = false, ignoreClasspathResolutionErrors: Boolean = false)
} }
internal fun <T : CommonToolArguments> CompilerArgumentAware<T>.prepareCompilerArguments(ignoreClasspathResolutionErrors: Boolean = false) = internal fun <T : CommonToolArguments> CompilerArgumentAware<T>.prepareCompilerArguments(ignoreClasspathResolutionErrors: Boolean = false) =
createCompilerArgs().also { setupCompilerArgs(it, ignoreClasspathResolutionErrors = ignoreClasspathResolutionErrors) } createCompilerArgs().also { setupCompilerArgs(it, ignoreClasspathResolutionErrors = ignoreClasspathResolutionErrors) }
interface CompilerArgumentAwareWithInput<T : CommonToolArguments> : CompilerArgumentAware<T> {
@get:Internal
override val serializedCompilerArguments: List<String>
get() = super.serializedCompilerArguments
@get:Internal
override val defaultSerializedCompilerArguments: List<String>
get() = super.defaultSerializedCompilerArguments
@get:Internal
override val serializedCompilerArgumentsIgnoreClasspathIssues: List<String>
get() = super.serializedCompilerArgumentsIgnoreClasspathIssues
@get:Input
override val filteredArgumentsMap: Map<String, String>
get() = super.filteredArgumentsMap
}
@@ -8,8 +8,7 @@ package org.jetbrains.kotlin.gradle.internal
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl import org.jetbrains.kotlin.gradle.dsl.CompilerJvmOptionsDefault
import org.jetbrains.kotlin.gradle.dsl.fillDefaultValues
import org.jetbrains.kotlin.gradle.logging.kotlinDebug import org.jetbrains.kotlin.gradle.logging.kotlinDebug
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
import org.jetbrains.kotlin.gradle.tasks.KotlinCompileArgumentsProvider import org.jetbrains.kotlin.gradle.tasks.KotlinCompileArgumentsProvider
@@ -52,10 +51,6 @@ internal open class AbstractKotlinCompileArgumentsContributor<T : CommonCompiler
args: T, args: T,
flags: Collection<CompilerArgumentsConfigurationFlag> flags: Collection<CompilerArgumentsConfigurationFlag>
) { ) {
if (logger.isDebugEnabled) {
args.verbose = true
}
args.multiPlatform = isMultiplatform args.multiPlatform = isMultiplatform
setupPlugins(args) setupPlugins(args)
@@ -76,13 +71,13 @@ internal open class KotlinJvmCompilerArgumentsContributor(
private val friendPaths = taskProvider.friendPaths private val friendPaths = taskProvider.friendPaths
private val compileClasspath = taskProvider.compileClasspath private val compileClasspath = taskProvider.compileClasspath
private val destinationDir = taskProvider.destinationDir private val destinationDir = taskProvider.destinationDir
private val kotlinOptions = taskProvider.kotlinOptions private val compilerOptions = taskProvider.compilerOptions
override fun contributeArguments( override fun contributeArguments(
args: K2JVMCompilerArguments, args: K2JVMCompilerArguments,
flags: Collection<CompilerArgumentsConfigurationFlag> flags: Collection<CompilerArgumentsConfigurationFlag>
) { ) {
args.fillDefaultValues() (compilerOptions as CompilerJvmOptionsDefault).fillDefaultValues(args)
super.contributeArguments(args, flags) super.contributeArguments(args, flags)
@@ -102,6 +97,6 @@ internal open class KotlinJvmCompilerArgumentsContributor(
} }
args.destinationAsFile = destinationDir args.destinationAsFile = destinationDir
kotlinOptions.forEach { it.updateArguments(args) } compilerOptions.fillCompilerArguments(args)
} }
} }
@@ -1,84 +0,0 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* 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 org.jetbrains.kotlin.gradle.internal
import org.jetbrains.kotlin.cli.common.arguments.*
import kotlin.reflect.KProperty
import kotlin.reflect.KProperty1
internal object CompilerArgumentsGradleInput {
fun <T : CommonToolArguments> createInputsMap(args: T): Map<String, String> {
@Suppress("UNCHECKED_CAST")
val argumentProperties =
args::class.members.mapNotNull { member ->
(member as? KProperty1<T, *>)?.takeIf { it.annotations.any { ann -> ann is Argument } }
} +
(CommonToolArguments::freeArgs as KProperty1<T, *>)
val filteredProperties = argumentProperties.filterNot { it in ignoredProperties }
fun inputItem(property: KProperty1<out T, *>): Pair<String, String> {
@Suppress("UNCHECKED_CAST")
val value = (property as KProperty1<T, *>).get(args)
return property.name to if (value is Array<*>)
value.asList().toString()
else
value.toString()
}
return filteredProperties.associate(::inputItem).toSortedMap()
}
// We ignore some file properties e.g. to instead include their values into the Gradle file property checks,
// which, unlike String checks, run with specified path sensitivity;
private val ignoredProperties = setOf<KProperty<*>>(
// debug should not lead to rebuild (should include all subclasses where this property is)
CommonToolArguments::verbose,
CommonCompilerArguments::verbose,
K2MetadataCompilerArguments::verbose,
K2JSCompilerArguments::verbose,
K2JVMCompilerArguments::verbose,
CommonCompilerArguments::reportPerf,
K2MetadataCompilerArguments::reportPerf,
K2JSCompilerArguments::reportPerf,
K2JVMCompilerArguments::reportPerf,
K2JVMCompilerArguments::destination, // handled by destinationDir
K2JVMCompilerArguments::classpath, // handled by classpath of the Gradle tasks
K2JVMCompilerArguments::friendPaths, // is part of the classpath
K2JVMCompilerArguments::jdkHome, // Gradle takes care of running Kotlin compilation with user specified JDK
K2JVMCompilerArguments::buildFile, // in Gradle build, these XMLs are transient and provide no useful info
K2JVMCompilerArguments::pluginOptions, // handled specially in the task
K2JVMCompilerArguments::pluginClasspaths, // handled in the task as classpath
K2JVMCompilerArguments::javaSourceRoots, // handled in inputs
K2JSCompilerArguments::outputFile, // already handled by Gradle task property
K2JSCompilerArguments::libraries, // defined by by classpath and friendDependency of the Gradle task
K2JSCompilerArguments::sourceMapBaseDirs, // defined by sources
K2JSCompilerArguments::friendModules, // handled by Gradle task friendDependency property
K2JSCompilerArguments::pluginOptions, // handled specially in the task
K2JSCompilerArguments::pluginClasspaths, // handled in the task as classpath
K2MetadataCompilerArguments::classpath, // handled by classpath of the Gradle task
K2MetadataCompilerArguments::destination, // handled by destinationDir
K2MetadataCompilerArguments::pluginOptions, // handled specially in the task
K2MetadataCompilerArguments::pluginClasspaths, // handled in the task as classpath
K2JSDceArguments::outputDirectory // handled by destinationDir
)
}
@@ -25,15 +25,13 @@ import org.gradle.work.Incremental
import org.gradle.work.NormalizeLineEndings import org.gradle.work.NormalizeLineEndings
import org.gradle.workers.WorkerExecutor import org.gradle.workers.WorkerExecutor
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl import org.jetbrains.kotlin.gradle.dsl.CompilerJvmOptionsDefault
import org.jetbrains.kotlin.gradle.report.BuildReportMode import org.jetbrains.kotlin.gradle.report.BuildReportMode
import org.jetbrains.kotlin.gradle.tasks.KaptGenerateStubs import org.jetbrains.kotlin.gradle.tasks.KaptGenerateStubs
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jetbrains.kotlin.gradle.tasks.toSingleCompilerPluginOptions import org.jetbrains.kotlin.gradle.tasks.toSingleCompilerPluginOptions
import org.jetbrains.kotlin.gradle.utils.isParentOf
import org.jetbrains.kotlin.incremental.classpathAsList import org.jetbrains.kotlin.incremental.classpathAsList
import org.jetbrains.kotlin.incremental.destinationAsFile import org.jetbrains.kotlin.incremental.destinationAsFile
import java.io.File
import javax.inject.Inject import javax.inject.Inject
@CacheableTask @CacheableTask
@@ -41,7 +39,7 @@ abstract class KaptGenerateStubsTask @Inject constructor(
workerExecutor: WorkerExecutor, workerExecutor: WorkerExecutor,
objectFactory: ObjectFactory objectFactory: ObjectFactory
) : KotlinCompile( ) : KotlinCompile(
KotlinJvmOptionsImpl(), objectFactory.newInstance(CompilerJvmOptionsDefault::class.java),
workerExecutor, workerExecutor,
objectFactory objectFactory
), KaptGenerateStubs { ), KaptGenerateStubs {
@@ -112,11 +110,7 @@ abstract class KaptGenerateStubsTask @Inject constructor(
// Also use KotlinOptions configuration that was directly set to this task // Also use KotlinOptions configuration that was directly set to this task
// as 'compileKotlinArgumentsContributor' has KotlinOptions from linked KotlinCompile task // as 'compileKotlinArgumentsContributor' has KotlinOptions from linked KotlinCompile task
listOfNotNull(kotlinOptions, parentKotlinOptions.orNull) (compilerOptions as CompilerJvmOptionsDefault).fillCompilerArguments(args)
.map { it as KotlinJvmOptionsImpl }
.forEach {
it.updateArguments(args)
}
// Copied from KotlinCompile // Copied from KotlinCompile
defaultKotlinJavaToolchain.get().updateJvmTarget(this, args) defaultKotlinJavaToolchain.get().updateJvmTarget(this, args)
@@ -9,12 +9,12 @@ import org.gradle.api.Project
import org.gradle.api.file.FileCollection import org.gradle.api.file.FileCollection
import org.gradle.api.provider.Provider import org.gradle.api.provider.Provider
import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.TaskProvider
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions import org.jetbrains.kotlin.gradle.dsl.*
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl import org.jetbrains.kotlin.gradle.dsl.CompilerJvmOptionsDefault
import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension
import org.jetbrains.kotlin.gradle.internal.KaptGenerateStubsTask import org.jetbrains.kotlin.gradle.internal.KaptGenerateStubsTask
import org.jetbrains.kotlin.gradle.internal.KaptWithoutKotlincTask import org.jetbrains.kotlin.gradle.internal.KaptWithoutKotlincTask
import org.jetbrains.kotlin.gradle.tasks.* import org.jetbrains.kotlin.gradle.tasks.*
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
import org.jetbrains.kotlin.gradle.tasks.configuration.KaptGenerateStubsConfig import org.jetbrains.kotlin.gradle.tasks.configuration.KaptGenerateStubsConfig
import org.jetbrains.kotlin.gradle.tasks.configuration.KaptWithoutKotlincConfig import org.jetbrains.kotlin.gradle.tasks.configuration.KaptWithoutKotlincConfig
import org.jetbrains.kotlin.gradle.tasks.configuration.KotlinCompileConfig import org.jetbrains.kotlin.gradle.tasks.configuration.KotlinCompileConfig
@@ -42,8 +42,16 @@ abstract class KotlinBaseApiPlugin : DefaultKotlinBasePlugin(), KotlinJvmFactory
return myProject.configurations.getByName(PLUGIN_CLASSPATH_CONFIGURATION_NAME) return myProject.configurations.getByName(PLUGIN_CLASSPATH_CONFIGURATION_NAME)
} }
override fun createCompilerJvmOptions(): CompilerJvmOptions {
return myProject.objects.newInstance(CompilerJvmOptionsDefault::class.java)
}
@Suppress("DEPRECATION")
@Deprecated("Replaced by compilerJvmOptions", replaceWith = ReplaceWith("createCompilerJvmOptions()"))
override fun createKotlinJvmOptions(): KotlinJvmOptions { override fun createKotlinJvmOptions(): KotlinJvmOptions {
return KotlinJvmOptionsImpl() return object : KotlinJvmOptions {
override val options: CompilerJvmOptions = createCompilerJvmOptions()
}
} }
override val kotlinExtension: KotlinProjectExtension by lazy { override val kotlinExtension: KotlinProjectExtension by lazy {
@@ -56,7 +64,10 @@ abstract class KotlinBaseApiPlugin : DefaultKotlinBasePlugin(), KotlinJvmFactory
override fun registerKotlinJvmCompileTask(taskName: String): TaskProvider<out KotlinJvmCompile> { override fun registerKotlinJvmCompileTask(taskName: String): TaskProvider<out KotlinJvmCompile> {
return taskCreator.registerKotlinJVMTask( return taskCreator.registerKotlinJVMTask(
myProject, taskName, KotlinJvmOptionsImpl(), KotlinCompileConfig(myProject, kotlinExtension) myProject,
taskName,
createCompilerJvmOptions(),
KotlinCompileConfig(myProject, kotlinExtension)
) )
} }
@@ -173,7 +173,12 @@ internal class Kotlin2JvmSourceSetProcessor(
override fun doRegisterTask(project: Project, taskName: String): TaskProvider<out KotlinCompile> { override fun doRegisterTask(project: Project, taskName: String): TaskProvider<out KotlinCompile> {
val configAction = KotlinCompileConfig(kotlinCompilation) val configAction = KotlinCompileConfig(kotlinCompilation)
applyStandardTaskConfiguration(configAction) applyStandardTaskConfiguration(configAction)
return tasksProvider.registerKotlinJVMTask(project, taskName, kotlinCompilation.kotlinOptions, configAction) return tasksProvider.registerKotlinJVMTask(
project,
taskName,
kotlinCompilation.compilerOptions.options as CompilerJvmOptions,
configAction
)
} }
override fun doTargetSpecificProcessing() { override fun doTargetSpecificProcessing() {
@@ -25,8 +25,7 @@ import org.gradle.api.tasks.TaskProvider
import org.gradle.api.tasks.bundling.AbstractArchiveTask import org.gradle.api.tasks.bundling.AbstractArchiveTask
import org.gradle.api.tasks.compile.AbstractCompile import org.gradle.api.tasks.compile.AbstractCompile
import org.gradle.api.tasks.compile.JavaCompile import org.gradle.api.tasks.compile.JavaCompile
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl import org.jetbrains.kotlin.gradle.dsl.*
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin
import org.jetbrains.kotlin.gradle.internal.checkAndroidAnnotationProcessorDependencyUsage import org.jetbrains.kotlin.gradle.internal.checkAndroidAnnotationProcessorDependencyUsage
import org.jetbrains.kotlin.gradle.logging.kotlinDebug import org.jetbrains.kotlin.gradle.logging.kotlinDebug
@@ -45,6 +44,7 @@ import org.jetbrains.kotlin.gradle.tooling.includeKotlinToolingMetadataInApk
import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation
import org.jetbrains.kotlin.gradle.utils.androidPluginIds import org.jetbrains.kotlin.gradle.utils.androidPluginIds
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
import org.jetbrains.kotlin.gradle.utils.newInstance
import java.io.File import java.io.File
import java.io.ObjectInputStream import java.io.ObjectInputStream
import java.io.ObjectOutputStream import java.io.ObjectOutputStream
@@ -62,8 +62,12 @@ internal class AndroidProjectHandler(
applyKotlinAndroidSourceSetLayout(kotlinAndroidTarget) applyKotlinAndroidSourceSetLayout(kotlinAndroidTarget)
val kotlinOptions = KotlinJvmOptionsImpl() val androidExtensionCompilerOptions = project.objects.newInstance<CompilerJvmOptionsDefault>()
kotlinOptions.noJdk = true androidExtensionCompilerOptions.noJdk.value(true).finalizeValueOnRead()
@Suppress("DEPRECATION") val kotlinOptions = object : KotlinJvmOptions {
override val options: CompilerJvmOptions
get() = androidExtensionCompilerOptions
}
ext.addExtension(KOTLIN_OPTIONS_DSL_NAME, kotlinOptions) ext.addExtension(KOTLIN_OPTIONS_DSL_NAME, kotlinOptions)
val plugin = androidPluginIds val plugin = androidPluginIds
@@ -83,8 +87,12 @@ internal class AndroidProjectHandler(
// handlers might break when fired on a compilation that is not yet properly configured (e.g. KT-29964): // handlers might break when fired on a compilation that is not yet properly configured (e.g. KT-29964):
compilationFactory.create(variantName).let { compilation -> compilationFactory.create(variantName).let { compilation ->
setUpDependencyResolution(variant, compilation) setUpDependencyResolution(variant, compilation)
project.wireExtensionOptionsToCompilation(
androidExtensionCompilerOptions,
compilation.compilerOptions.options as CompilerJvmOptions
)
preprocessVariant(variant, compilation, project, kotlinOptions, kotlinConfigurationTools.kotlinTasksProvider) preprocessVariant(variant, compilation, project, kotlinConfigurationTools.kotlinTasksProvider)
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
(kotlinAndroidTarget.compilations as NamedDomainObjectCollection<in KotlinJvmAndroidCompilation>).add(compilation) (kotlinAndroidTarget.compilations as NamedDomainObjectCollection<in KotlinJvmAndroidCompilation>).add(compilation)
@@ -110,6 +118,38 @@ internal class AndroidProjectHandler(
addAndroidUnitTestTasksAsDependenciesToAllTest(project) addAndroidUnitTestTasksAsDependenciesToAllTest(project)
} }
private fun Project.wireExtensionOptionsToCompilation(
extensionCompilerOptions: CompilerJvmOptions,
compilationCompilerOptions: CompilerJvmOptions
) {
// CompilerCommonToolOptions
compilationCompilerOptions.allWarningsAsErrors.convention(extensionCompilerOptions.allWarningsAsErrors)
compilationCompilerOptions.suppressWarnings.convention(extensionCompilerOptions.suppressWarnings)
compilationCompilerOptions.verbose.convention(extensionCompilerOptions.verbose)
compilationCompilerOptions.freeCompilerArgs.addAll(extensionCompilerOptions.freeCompilerArgs)
// CompilerCommonOptions
compilationCompilerOptions.apiVersion.convention(extensionCompilerOptions.apiVersion)
compilationCompilerOptions.languageVersion.convention(extensionCompilerOptions.languageVersion)
compilationCompilerOptions.useK2.convention(extensionCompilerOptions.useK2)
// CompilerJvmOptions
compilationCompilerOptions.javaParameters.convention(extensionCompilerOptions.javaParameters)
compilationCompilerOptions.noJdk.value(extensionCompilerOptions.noJdk).finalizeValue()
// Special handling of jvmTarget to correctly override convention set by DefaultJavaToolchainSetter
// plus for 'moduleName' which could be overriden either by compilation or by task itself
// TODO: fix it once proper extension DSL will be available
afterEvaluate {
if (extensionCompilerOptions.jvmTarget.isPresent) {
compilationCompilerOptions.jvmTarget.set(extensionCompilerOptions.jvmTarget)
}
if (extensionCompilerOptions.moduleName.isPresent) {
compilationCompilerOptions.moduleName.set(extensionCompilerOptions.moduleName)
}
}
}
/** /**
* The Android variants have their configurations extendsFrom relation set up in a way that only some of the configurations of the * The Android variants have their configurations extendsFrom relation set up in a way that only some of the configurations of the
* variants propagate the dependencies from production variants to test ones. To make this dependency propagation work for the Kotlin * variants propagate the dependencies from production variants to test ones. To make this dependency propagation work for the Kotlin
@@ -178,7 +218,6 @@ internal class AndroidProjectHandler(
variantData: BaseVariant, variantData: BaseVariant,
compilation: KotlinJvmAndroidCompilation, compilation: KotlinJvmAndroidCompilation,
project: Project, project: Project,
rootKotlinOptions: KotlinJvmOptionsImpl,
tasksProvider: KotlinTasksProvider tasksProvider: KotlinTasksProvider
) { ) {
// This function is called before the variantData is completely filled by the Android plugin. // This function is called before the variantData is completely filled by the Android plugin.
@@ -190,13 +229,17 @@ internal class AndroidProjectHandler(
val configAction = KotlinCompileConfig(compilation) val configAction = KotlinCompileConfig(compilation)
configAction.configureTask { task -> configAction.configureTask { task ->
task.parentKotlinOptions.value(rootKotlinOptions).disallowChanges()
task.useModuleDetection.value(true).disallowChanges() task.useModuleDetection.value(true).disallowChanges()
// store kotlin classes in separate directory. They will serve as class-path to java compiler // store kotlin classes in separate directory. They will serve as class-path to java compiler
task.destinationDirectory.set(project.layout.buildDirectory.dir("tmp/kotlin-classes/$variantDataName")) task.destinationDirectory.set(project.layout.buildDirectory.dir("tmp/kotlin-classes/$variantDataName"))
task.description = "Compiles the $variantDataName kotlin." task.description = "Compiles the $variantDataName kotlin."
} }
tasksProvider.registerKotlinJVMTask(project, compilation.compileKotlinTaskName, compilation.kotlinOptions, configAction) tasksProvider.registerKotlinJVMTask(
project,
compilation.compileKotlinTaskName,
compilation.compilerOptions.options as CompilerJvmOptions,
configAction
)
// Register the source only after the task is created, because the task is required for that: // Register the source only after the task is created, because the task is required for that:
compilation.source(defaultSourceSet) compilation.source(defaultSourceSet)
@@ -78,7 +78,7 @@ abstract class AbstractKotlinCompileTool<T : CommonToolArguments> @Inject constr
objectFactory: ObjectFactory objectFactory: ObjectFactory
) : DefaultTask(), ) : DefaultTask(),
KotlinCompileTool, KotlinCompileTool,
CompilerArgumentAwareWithInput<T>, CompilerArgumentAware<T>,
TaskWithLocalState { TaskWithLocalState {
private val patternFilterable = PatternSet() private val patternFilterable = PatternSet()
@@ -512,10 +512,7 @@ class KotlinJvmCompilerArgumentsProvider
val friendPaths: FileCollection = taskProvider.friendPaths val friendPaths: FileCollection = taskProvider.friendPaths
val compileClasspath: Iterable<File> = taskProvider.libraries val compileClasspath: Iterable<File> = taskProvider.libraries
val destinationDir: File = taskProvider.destinationDirectory.get().asFile val destinationDir: File = taskProvider.destinationDirectory.get().asFile
internal val kotlinOptions: List<KotlinJvmOptionsImpl> = listOfNotNull( internal val compilerOptions: CompilerJvmOptions = taskProvider.compilerOptions
taskProvider.parentKotlinOptions.orNull as? KotlinJvmOptionsImpl,
taskProvider.kotlinOptions as KotlinJvmOptionsImpl
)
} }
internal inline val <reified T : Task> T.thisTaskProvider: TaskProvider<out T> internal inline val <reified T : Task> T.thisTaskProvider: TaskProvider<out T>
@@ -523,13 +520,32 @@ internal inline val <reified T : Task> T.thisTaskProvider: TaskProvider<out T>
@CacheableTask @CacheableTask
abstract class KotlinCompile @Inject constructor( abstract class KotlinCompile @Inject constructor(
override val kotlinOptions: KotlinJvmOptions, override val compilerOptions: CompilerJvmOptions,
workerExecutor: WorkerExecutor, workerExecutor: WorkerExecutor,
private val objectFactory: ObjectFactory objectFactory: ObjectFactory
) : AbstractKotlinCompile<K2JVMCompilerArguments>(objectFactory, workerExecutor), ) : AbstractKotlinCompile<K2JVMCompilerArguments>(objectFactory, workerExecutor),
@Suppress("TYPEALIAS_EXPANSION_DEPRECATION") KotlinJvmCompileDsl, @Suppress("TYPEALIAS_EXPANSION_DEPRECATION") KotlinJvmCompileDsl,
KotlinCompilationTask<CompilerJvmOptions>,
UsesKotlinJavaToolchain { UsesKotlinJavaToolchain {
init {
compilerOptions.moduleName.convention(moduleName)
compilerOptions.verbose.convention(logger.isDebugEnabled)
}
@Suppress("DEPRECATION")
@Deprecated("Replaced by compilerOptions input", replaceWith = ReplaceWith("compilerOptions"))
final override val kotlinOptions: KotlinJvmOptions = object : KotlinJvmOptions {
override val options: CompilerJvmOptions
get() = compilerOptions
}
@Suppress("DEPRECATION")
@Deprecated("Configure compilerOptions directly", replaceWith = ReplaceWith("compilerOptions"))
override val parentKotlinOptions: Property<KotlinJvmOptions> = objectFactory
.property(kotlinOptions)
.chainedDisallowChanges()
/** A package prefix that is used for locating Java sources in a directory structure with non-full-depth packages. /** A package prefix that is used for locating Java sources in a directory structure with non-full-depth packages.
* *
* Example: a Java source file with `package com.example.my.package` is located in directory `src/main/java/my/package`. * Example: a Java source file with `package com.example.my.package` is located in directory `src/main/java/my/package`.
@@ -22,6 +22,7 @@ import org.gradle.api.UnknownTaskException
import org.gradle.api.tasks.TaskCollection import org.gradle.api.tasks.TaskCollection
import org.gradle.api.tasks.TaskContainer import org.gradle.api.tasks.TaskContainer
import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.TaskProvider
import org.jetbrains.kotlin.gradle.dsl.CompilerJvmOptions
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrLink import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrLink
import org.jetbrains.kotlin.gradle.tasks.configuration.* import org.jetbrains.kotlin.gradle.tasks.configuration.*
@@ -98,9 +99,12 @@ internal inline fun <reified T : Task> Project.locateOrRegisterTask(
internal open class KotlinTasksProvider { internal open class KotlinTasksProvider {
open fun registerKotlinJVMTask( open fun registerKotlinJVMTask(
project: Project, taskName: String, kotlinOptions: KotlinCommonOptions, configuration: KotlinCompileConfig project: Project,
taskName: String,
compilerOptions: CompilerJvmOptions,
configuration: KotlinCompileConfig
): TaskProvider<out KotlinCompile> { ): TaskProvider<out KotlinCompile> {
return project.registerTask(taskName, KotlinCompile::class.java, constructorArgs = listOf(kotlinOptions)).also { return project.registerTask(taskName, KotlinCompile::class.java, constructorArgs = listOf(compilerOptions)).also {
configuration.execute(it) configuration.execute(it)
} }
} }
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.gradle.tasks.configuration
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.attributes.Attribute import org.gradle.api.attributes.Attribute
import org.gradle.api.provider.Provider import org.gradle.api.provider.Provider
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions import org.jetbrains.kotlin.gradle.dsl.CompilerJvmOptions
import org.jetbrains.kotlin.gradle.dsl.KotlinTopLevelExtension import org.jetbrains.kotlin.gradle.dsl.KotlinTopLevelExtension
import org.jetbrains.kotlin.gradle.internal.transforms.ClasspathEntrySnapshotTransform import org.jetbrains.kotlin.gradle.internal.transforms.ClasspathEntrySnapshotTransform
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmAndroidCompilation import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmAndroidCompilation
@@ -40,7 +40,7 @@ internal open class BaseKotlinCompileConfig<TASK : KotlinCompile> : AbstractKotl
task.incremental = propertiesProvider.incrementalJvm ?: true task.incremental = propertiesProvider.incrementalJvm ?: true
if (propertiesProvider.useK2 == true) { if (propertiesProvider.useK2 == true) {
task.kotlinOptions.useK2 = true task.compilerOptions.useK2.value(true)
} }
task.usePreciseJavaTracking = propertiesProvider.usePreciseJavaTracking ?: true task.usePreciseJavaTracking = propertiesProvider.usePreciseJavaTracking ?: true
task.jvmTargetValidationMode.set(propertiesProvider.jvmTargetValidationMode) task.jvmTargetValidationMode.set(propertiesProvider.jvmTargetValidationMode)
@@ -60,12 +60,11 @@ internal open class BaseKotlinCompileConfig<TASK : KotlinCompile> : AbstractKotl
} }
} }
@Suppress("ConvertSecondaryConstructorToPrimary")
constructor(compilation: KotlinCompilationData<*>) : super(compilation) { constructor(compilation: KotlinCompilationData<*>) : super(compilation) {
val javaTaskProvider = when (compilation) { val javaTaskProvider = when (compilation) {
is KotlinJvmCompilation -> compilation.compileJavaTaskProvider is KotlinJvmCompilation -> compilation.compileJavaTaskProvider
is KotlinJvmAndroidCompilation -> compilation.compileJavaTaskProvider is KotlinJvmAndroidCompilation -> compilation.compileJavaTaskProvider
is KotlinWithJavaCompilation<*> -> compilation.compileJavaTaskProvider is KotlinWithJavaCompilation<*, *> -> compilation.compileJavaTaskProvider
else -> null else -> null
} }
@@ -76,10 +75,9 @@ internal open class BaseKotlinCompileConfig<TASK : KotlinCompile> : AbstractKotl
task.associatedJavaCompileTaskSources.from(javaTaskProvider.map { it.source }) task.associatedJavaCompileTaskSources.from(javaTaskProvider.map { it.source })
task.associatedJavaCompileTaskName.value(javaTaskProvider.name) task.associatedJavaCompileTaskName.value(javaTaskProvider.name)
} }
task.ownModuleName.value(providers.provider { task.ownModuleName.value(
(compilation.kotlinOptions as? KotlinJvmOptions)?.moduleName ?: task.parentKotlinOptions.orNull?.moduleName (compilation.compilerOptions.options as CompilerJvmOptions).moduleName.convention(compilation.ownModuleName)
?: compilation.ownModuleName )
})
} }
} }
} }
@@ -83,6 +83,16 @@ internal fun <PropType : Any?, T : ListProperty<PropType>> T.chainedFinalizeValu
finalizeValueOnRead() finalizeValueOnRead()
} }
internal fun <PropType : Any?, T: Property<PropType>> T.chainedFinalizeValue(): T =
apply {
finalizeValue()
}
internal fun <PropType : Any?, T: Property<PropType>> T.chainedDisallowChanges(): T =
apply {
disallowChanges()
}
// Before 5.0 fileProperty is created via ProjectLayout // Before 5.0 fileProperty is created via ProjectLayout
// https://docs.gradle.org/current/javadoc/org/gradle/api/model/ObjectFactory.html#fileProperty-- // https://docs.gradle.org/current/javadoc/org/gradle/api/model/ObjectFactory.html#fileProperty--
internal fun Project.newFileProperty(initialize: (() -> File)? = null): RegularFileProperty { internal fun Project.newFileProperty(initialize: (() -> File)? = null): RegularFileProperty {