Update Kotlin Java toolchain code to use compiler options

^KT-27301 In Progress
This commit is contained in:
Yahor Berdnikau
2022-08-01 17:56:42 +02:00
parent 732ba96667
commit 228fff555d
4 changed files with 18 additions and 63 deletions
@@ -550,8 +550,8 @@ class KotlinJavaToolchainTest : KGPBaseTest() {
""" """
tasks.named("compileKotlin") { tasks.named("compileKotlin") {
doLast { doLast {
def actualJvmTarget = filteredArgumentsMap['jvmTarget'] def actualJvmTarget = compilerOptions.jvmTarget.orNull
if (actualJvmTarget != "null") { if (actualJvmTarget != null) {
//noinspection GroovyAssignabilityCheck //noinspection GroovyAssignabilityCheck
throw new GradleException("Expected `jvmTarget` value is 'null' but the actual value was ${'$'}actualJvmTarget") throw new GradleException("Expected `jvmTarget` value is 'null' but the actual value was ${'$'}actualJvmTarget")
} }
@@ -113,7 +113,6 @@ abstract class KaptGenerateStubsTask @Inject constructor(
(compilerOptions as CompilerJvmOptionsDefault).fillCompilerArguments(args) (compilerOptions as CompilerJvmOptionsDefault).fillCompilerArguments(args)
// Copied from KotlinCompile // Copied from KotlinCompile
defaultKotlinJavaToolchain.get().updateJvmTarget(this, args)
if (reportingSettings().buildReportMode == BuildReportMode.VERBOSE) { if (reportingSettings().buildReportMode == BuildReportMode.VERBOSE) {
args.reportPerf = true args.reportPerf = true
} }
@@ -15,8 +15,7 @@ import org.gradle.api.provider.Provider
import org.gradle.api.tasks.Internal import org.gradle.api.tasks.Internal
import org.gradle.internal.jvm.Jvm import org.gradle.internal.jvm.Jvm
import org.gradle.jvm.toolchain.* import org.gradle.jvm.toolchain.*
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl
import org.jetbrains.kotlin.gradle.utils.chainedFinalizeValueOnRead import org.jetbrains.kotlin.gradle.utils.chainedFinalizeValueOnRead
import org.jetbrains.kotlin.gradle.utils.property import org.jetbrains.kotlin.gradle.utils.property
import org.jetbrains.kotlin.gradle.utils.propertyWithConvention import org.jetbrains.kotlin.gradle.utils.propertyWithConvention
@@ -35,9 +34,6 @@ internal abstract class DefaultKotlinJavaToolchain @Inject constructor(
.property(Jvm.current()) .property(Jvm.current())
.chainedFinalizeValueOnRead() .chainedFinalizeValueOnRead()
@get:Internal
internal var providedJvmExplicitlySet = false
@get:Internal @get:Internal
internal val providedJvm: Property<Jvm> = objects internal val providedJvm: Property<Jvm> = objects
.propertyWithConvention(currentJvm) .propertyWithConvention(currentJvm)
@@ -109,74 +105,38 @@ internal abstract class DefaultKotlinJavaToolchain @Inject constructor(
final override val jdk: KotlinJavaToolchain.JdkSetter = DefaultJdkSetter( final override val jdk: KotlinJavaToolchain.JdkSetter = DefaultJdkSetter(
providedJvm, providedJvm,
objects, objects,
{ providedJvmExplicitlySet = true },
kotlinCompileTaskProvider kotlinCompileTaskProvider
) )
final override val toolchain: KotlinJavaToolchain.JavaToolchainSetter = final override val toolchain: KotlinJavaToolchain.JavaToolchainSetter =
DefaultJavaToolchainSetter(providedJvm, kotlinCompileTaskProvider) DefaultJavaToolchainSetter(providedJvm, kotlinCompileTaskProvider)
/**
* Updates [task] 'jvmTarget' if user has configured toolchain and not 'jvmTarget'.
*
* Should be called on execution state to ensure 'jvmTarget' is set to correct value even on
* reusing configuration cache.
*
* Should be called on task execution phase!
*/
internal fun updateJvmTarget(
task: KotlinCompile,
args: K2JVMCompilerArguments
) {
if (providedJvmExplicitlySet) {
val jdkVersion = javaVersion.get()
// parentKotlinOptionsImpl is set from 'kotlin-android' plugin
val appliedJvmTargets = listOfNotNull(task.kotlinOptions, task.parentKotlinOptions.orNull)
.mapNotNull { (it as KotlinJvmOptionsImpl).jvmTarget }
if (appliedJvmTargets.isEmpty()) {
// For Java 9 and Java 10 JavaVersion returns "1.9" or "1.10" accordingly
// that is not accepted by Kotlin compiler
val toolchainJvmTarget = when (jdkVersion) {
JavaVersion.VERSION_1_9 -> "9"
JavaVersion.VERSION_1_10 -> "10"
else -> jdkVersion.toString()
}
task.kotlinOptions.jvmTarget = toolchainJvmTarget
args.jvmTarget = toolchainJvmTarget
}
}
}
private abstract class JvmTargetUpdater( private abstract class JvmTargetUpdater(
private val kotlinCompileTaskProvider: () -> KotlinCompile? private val kotlinCompileTaskProvider: () -> KotlinCompile?
) { ) {
fun updateJvmTarget( fun updateJvmTarget(
jdkVersion: JavaVersion jdkVersion: Provider<JavaVersion>
) { ) {
kotlinCompileTaskProvider()?.let { task -> kotlinCompileTaskProvider()?.let { task ->
// parentKotlinOptionsImpl is set from 'kotlin-android' plugin task.compilerOptions.jvmTarget.convention(
val appliedJvmTargets = listOfNotNull(task.kotlinOptions, task.parentKotlinOptions.orNull) jdkVersion.map { version ->
.mapNotNull { (it as KotlinJvmOptionsImpl).jvmTarget } // For Java 9 and Java 10 JavaVersion returns "1.9" or "1.10" accordingly
// that is not accepted by Kotlin compiler
if (appliedJvmTargets.isEmpty()) { val normalizedVersion = when (version) {
// For Java 9 and Java 10 JavaVersion returns "1.9" or "1.10" accordingly JavaVersion.VERSION_1_9 -> "9"
// that is not accepted by Kotlin compiler JavaVersion.VERSION_1_10 -> "10"
task.kotlinOptions.jvmTarget = when (jdkVersion) { else -> version.toString()
JavaVersion.VERSION_1_9 -> "9" }
JavaVersion.VERSION_1_10 -> "10" JvmTarget.fromTarget(normalizedVersion)
else -> jdkVersion.toString()
} }
} )
} }
} }
} }
private class DefaultJdkSetter( private inner class DefaultJdkSetter(
private val providedJvm: Property<Jvm>, private val providedJvm: Property<Jvm>,
private val objects: ObjectFactory, private val objects: ObjectFactory,
private val updateProvidedJdkCallback: () -> Unit,
kotlinCompileTaskProvider: () -> KotlinCompile? kotlinCompileTaskProvider: () -> KotlinCompile?
) : JvmTargetUpdater(kotlinCompileTaskProvider), ) : JvmTargetUpdater(kotlinCompileTaskProvider),
KotlinJavaToolchain.JdkSetter { KotlinJavaToolchain.JdkSetter {
@@ -192,10 +152,9 @@ internal abstract class DefaultKotlinJavaToolchain @Inject constructor(
"Supplied jdkHomeLocation does not exist. You supplied: $jdkHomeLocation" "Supplied jdkHomeLocation does not exist. You supplied: $jdkHomeLocation"
} }
updateProvidedJdkCallback.invoke() updateJvmTarget(javaVersion)
providedJvm.set( providedJvm.set(
objects.providerWithLazyConvention { objects.providerWithLazyConvention {
updateJvmTarget(jdkVersion)
Jvm.discovered(jdkHomeLocation, null, jdkVersion) Jvm.discovered(jdkHomeLocation, null, jdkVersion)
} }
) )
@@ -210,12 +169,11 @@ internal abstract class DefaultKotlinJavaToolchain @Inject constructor(
override fun use( override fun use(
javaLauncher: Provider<JavaLauncher> javaLauncher: Provider<JavaLauncher>
) { ) {
providedJvmExplicitlySet = true updateJvmTarget(javaVersion)
providedJvm.set( providedJvm.set(
javaLauncher.map { javaLauncher.map {
val metadata = javaLauncher.get().metadata val metadata = javaLauncher.get().metadata
val javaVersion = JavaVersion.toVersion(metadata.languageVersion.asInt()) val javaVersion = JavaVersion.toVersion(metadata.languageVersion.asInt())
updateJvmTarget(javaVersion)
Jvm.discovered( Jvm.discovered(
metadata.installationPath.asFile, metadata.installationPath.asFile,
null, null,
@@ -696,8 +696,6 @@ abstract class KotlinCompile @Inject constructor(
) )
) )
defaultKotlinJavaToolchain.get().updateJvmTarget(this, args)
if (reportingSettings().buildReportMode == BuildReportMode.VERBOSE) { if (reportingSettings().buildReportMode == BuildReportMode.VERBOSE) {
args.reportPerf = true args.reportPerf = true
} }