Cleanup JVM toolchain implementation

Remove support for <Gradle 6.7 and fix extension method to accept
'JavaToolchainSpec' instead of 'Any'.

^KT-47924 Fixed
This commit is contained in:
Yahor Berdnikau
2022-02-10 16:40:31 +01:00
committed by Space
parent 016143328a
commit ff3a08de6e
8 changed files with 30 additions and 78 deletions
+2
View File
@@ -51,12 +51,14 @@ fun Project.configureJvmToolchain(
if (shouldOverrideObsoleteJdk(jdkVersion)) { if (shouldOverrideObsoleteJdk(jdkVersion)) {
kotlinExtension.jvmToolchain { kotlinExtension.jvmToolchain {
@Suppress("USELESS_CAST") // Remove after boostrap update
(this as JavaToolchainSpec).languageVersion (this as JavaToolchainSpec).languageVersion
.set(JavaLanguageVersion.of(jdkVersion.overrideMajorVersion!!)) .set(JavaLanguageVersion.of(jdkVersion.overrideMajorVersion!!))
} }
updateJvmTarget(jdkVersion.targetName) updateJvmTarget(jdkVersion.targetName)
} else { } else {
kotlinExtension.jvmToolchain { kotlinExtension.jvmToolchain {
@Suppress("USELESS_CAST") // Remove after boostrap update
(this as JavaToolchainSpec).languageVersion (this as JavaToolchainSpec).languageVersion
.set(JavaLanguageVersion.of(jdkVersion.majorVersion)) .set(JavaLanguageVersion.of(jdkVersion.majorVersion))
} }
@@ -74,8 +74,4 @@ interface KotlinJavaToolchain {
javaLauncher: Provider<JavaLauncher> javaLauncher: Provider<JavaLauncher>
) )
} }
companion object {
val TOOLCHAIN_SUPPORTED_VERSION: GradleVersion = GradleVersion.version("6.7")
}
} }
@@ -19,7 +19,7 @@ import java.io.File
@DisplayName("Kotlin Java Toolchain support") @DisplayName("Kotlin Java Toolchain support")
class KotlinJavaToolchainTest : KGPBaseTest() { class KotlinJavaToolchainTest : KGPBaseTest() {
@GradleTestVersions(additionalVersions = [TestVersions.Gradle.G_6_7]) @GradleTestVersions
@GradleTest @GradleTest
@DisplayName("Should use by default same jvm as Gradle daemon for jdkHome") @DisplayName("Should use by default same jvm as Gradle daemon for jdkHome")
internal fun byDefaultShouldUseGradleJDK(gradleVersion: GradleVersion) { internal fun byDefaultShouldUseGradleJDK(gradleVersion: GradleVersion) {
@@ -102,7 +102,7 @@ class KotlinJavaToolchainTest : KGPBaseTest() {
} }
@DisplayName("Kotlin compile task should reuse build cache when toolchain is set and build is happening on different JDKs") @DisplayName("Kotlin compile task should reuse build cache when toolchain is set and build is happening on different JDKs")
@GradleTestVersions(minVersion = TestVersions.Gradle.G_6_7) @GradleTestVersions
@GradleTest @GradleTest
internal fun differentBuildJDKBuildCacheHit(gradleVersion: GradleVersion) { internal fun differentBuildJDKBuildCacheHit(gradleVersion: GradleVersion) {
val buildCache = workingDir.resolve("custom-jdk-build-cache") val buildCache = workingDir.resolve("custom-jdk-build-cache")
@@ -331,7 +331,7 @@ class KotlinJavaToolchainTest : KGPBaseTest() {
} }
@DisplayName("Should allow to set JDK version for tasks via Java toolchain") @DisplayName("Should allow to set JDK version for tasks via Java toolchain")
@GradleTestVersions(minVersion = TestVersions.Gradle.G_6_7) @GradleTestVersions
@GradleTest @GradleTest
internal fun setJdkUsingJavaToolchain(gradleVersion: GradleVersion) { internal fun setJdkUsingJavaToolchain(gradleVersion: GradleVersion) {
project( project(
@@ -346,7 +346,7 @@ class KotlinJavaToolchainTest : KGPBaseTest() {
} }
@DisplayName("Should allow to set Java toolchain via extension") @DisplayName("Should allow to set Java toolchain via extension")
@GradleTestVersions(minVersion = TestVersions.Gradle.G_6_7) @GradleTestVersions
@GradleTest @GradleTest
internal fun setJdkUsingJavaToolchainViaExtension(gradleVersion: GradleVersion) { internal fun setJdkUsingJavaToolchainViaExtension(gradleVersion: GradleVersion) {
project( project(
@@ -361,7 +361,7 @@ class KotlinJavaToolchainTest : KGPBaseTest() {
} }
@DisplayName("Toolchain should be correctly supported in multiplatform plugin jvm targets") @DisplayName("Toolchain should be correctly supported in multiplatform plugin jvm targets")
@GradleTestVersions(minVersion = TestVersions.Gradle.G_6_7) @GradleTestVersions
@GradleTest @GradleTest
internal fun toolchainCorrectlySupportedInMPPlugin(gradleVersion: GradleVersion) { internal fun toolchainCorrectlySupportedInMPPlugin(gradleVersion: GradleVersion) {
project( project(
@@ -419,7 +419,7 @@ class KotlinJavaToolchainTest : KGPBaseTest() {
} }
@DisplayName("Should set 'jvmTarget' option if user does not specify it explicitly via toolchain setter") @DisplayName("Should set 'jvmTarget' option if user does not specify it explicitly via toolchain setter")
@GradleTestVersions(minVersion = TestVersions.Gradle.G_6_7) @GradleTestVersions
@GradleTest @GradleTest
internal fun shouldSetJvmTargetNonSpecifiedByUserViaToolchain(gradleVersion: GradleVersion) { internal fun shouldSetJvmTargetNonSpecifiedByUserViaToolchain(gradleVersion: GradleVersion) {
project( project(
@@ -437,7 +437,7 @@ class KotlinJavaToolchainTest : KGPBaseTest() {
} }
@DisplayName("Should not override user specified 'jvmTarget' option via toolchain setter") @DisplayName("Should not override user specified 'jvmTarget' option via toolchain setter")
@GradleTestVersions(minVersion = "6.7.1") @GradleTestVersions
@GradleTest @GradleTest
internal fun shouldNotOverrideUserSpecifiedJvmTargetViaToolchain(gradleVersion: GradleVersion) { internal fun shouldNotOverrideUserSpecifiedJvmTargetViaToolchain(gradleVersion: GradleVersion) {
project( project(
@@ -456,7 +456,7 @@ class KotlinJavaToolchainTest : KGPBaseTest() {
} }
@DisplayName("Setting toolchain via java extension should also affect Kotlin compilations") @DisplayName("Setting toolchain via java extension should also affect Kotlin compilations")
@GradleTestVersions(minVersion = TestVersions.Gradle.G_6_7) @GradleTestVersions
@GradleTest @GradleTest
internal fun settingToolchainViaJavaShouldAlsoWork(gradleVersion: GradleVersion) { internal fun settingToolchainViaJavaShouldAlsoWork(gradleVersion: GradleVersion) {
project( project(
@@ -487,8 +487,8 @@ class KotlinJavaToolchainTest : KGPBaseTest() {
} }
} }
@DisplayName("Build should not produce warninings when '-no-jdk' option is present") @DisplayName("Build should not produce warnings when '-no-jdk' option is present")
@GradleTestVersions(minVersion = TestVersions.Gradle.G_6_7) @GradleTestVersions
@GradleTest @GradleTest
internal fun noWarningOnNoJdkOptionPresent(gradleVersion: GradleVersion) { internal fun noWarningOnNoJdkOptionPresent(gradleVersion: GradleVersion) {
project( project(
@@ -520,7 +520,7 @@ class KotlinJavaToolchainTest : KGPBaseTest() {
} }
@DisplayName("Toolchain should take into account kotlin options that are set via android extension") @DisplayName("Toolchain should take into account kotlin options that are set via android extension")
@GradleTestVersions(minVersion = TestVersions.Gradle.G_6_7) @GradleTestVersions
@GradleTest @GradleTest
internal fun kotlinOptionsAndroidAndToolchain(gradleVersion: GradleVersion) { internal fun kotlinOptionsAndroidAndToolchain(gradleVersion: GradleVersion) {
project("android".fullProjectName, gradleVersion) { project("android".fullProjectName, gradleVersion) {
@@ -544,7 +544,7 @@ class KotlinJavaToolchainTest : KGPBaseTest() {
} }
@DisplayName("Toolchain should not make an exception when build is running on JDK 11, but toolchain is set to JDK 1.8") @DisplayName("Toolchain should not make an exception when build is running on JDK 11, but toolchain is set to JDK 1.8")
@GradleTestVersions(minVersion = TestVersions.Gradle.G_6_7) @GradleTestVersions
@GradleTest @GradleTest
internal fun shouldNotRaiseErrorOnJDK11withJDK1_8Toolchain(gradleVersion: GradleVersion) { internal fun shouldNotRaiseErrorOnJDK11withJDK1_8Toolchain(gradleVersion: GradleVersion) {
project( project(
@@ -559,7 +559,7 @@ class KotlinJavaToolchainTest : KGPBaseTest() {
} }
@DisplayName("JVM target shouldn't be changed when toolchain is not configured") @DisplayName("JVM target shouldn't be changed when toolchain is not configured")
@GradleTestVersions(minVersion = TestVersions.Gradle.G_6_7) @GradleTestVersions
@GradleTest @GradleTest
internal fun shouldNotChangeJvmTargetWithNoToolchain(gradleVersion: GradleVersion) { internal fun shouldNotChangeJvmTargetWithNoToolchain(gradleVersion: GradleVersion) {
project( project(
@@ -586,7 +586,7 @@ class KotlinJavaToolchainTest : KGPBaseTest() {
} }
@DisplayName("Kotlin toolchain should support configuration cache") @DisplayName("Kotlin toolchain should support configuration cache")
@GradleTestVersions(minVersion = TestVersions.Gradle.G_6_7) @GradleTestVersions
@GradleTest @GradleTest
internal fun testConfigurationCache(gradleVersion: GradleVersion) { internal fun testConfigurationCache(gradleVersion: GradleVersion) {
project( project(
@@ -77,9 +77,9 @@ abstract class KotlinTopLevelExtension(internal val project: Project) : KotlinTo
/** /**
* Configures [Java toolchain](https://docs.gradle.org/current/userguide/toolchains.html) both for Kotlin JVM and Java tasks. * Configures [Java toolchain](https://docs.gradle.org/current/userguide/toolchains.html) both for Kotlin JVM and Java tasks.
* *
* @param action - action to configure [JavaToolchainSpec]. You could safely cast `Any` into `JavaToolchainSpec`. * @param action - action to configure [JavaToolchainSpec]
*/ */
fun jvmToolchain(action: Action<Any>) { fun jvmToolchain(action: Action<JavaToolchainSpec>) {
toolchainSupport.applyToolchain(action) toolchainSupport.applyToolchain(action)
} }
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.gradle.dsl package org.jetbrains.kotlin.gradle.dsl
import org.gradle.api.Action import org.gradle.api.Action
import org.gradle.api.GradleException
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.plugins.ExtensionContainer import org.gradle.api.plugins.ExtensionContainer
import org.gradle.api.plugins.JavaPluginExtension import org.gradle.api.plugins.JavaPluginExtension
@@ -14,41 +13,27 @@ import org.gradle.api.plugins.PluginContainer
import org.gradle.api.tasks.TaskContainer import org.gradle.api.tasks.TaskContainer
import org.gradle.jvm.toolchain.JavaToolchainService import org.gradle.jvm.toolchain.JavaToolchainService
import org.gradle.jvm.toolchain.JavaToolchainSpec import org.gradle.jvm.toolchain.JavaToolchainSpec
import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.gradle.tasks.KotlinJavaToolchain.Companion.TOOLCHAIN_SUPPORTED_VERSION
import org.jetbrains.kotlin.gradle.tasks.UsesKotlinJavaToolchain import org.jetbrains.kotlin.gradle.tasks.UsesKotlinJavaToolchain
import org.jetbrains.kotlin.gradle.tasks.withType import org.jetbrains.kotlin.gradle.tasks.withType
import org.jetbrains.kotlin.gradle.utils.newInstance import org.jetbrains.kotlin.gradle.utils.newInstance
import javax.inject.Inject import javax.inject.Inject
internal interface ToolchainSupport { internal interface ToolchainSupport {
fun applyToolchain(action: Action<Any>) fun applyToolchain(action: Action<JavaToolchainSpec>)
companion object { companion object {
internal fun createToolchain( internal fun createToolchain(
project: Project project: Project
): ToolchainSupport { ): ToolchainSupport {
val currentVersion = GradleVersion.version(project.gradle.gradleVersion) return project.objects.newInstance<DefaultToolchainSupport>(
return when { project.extensions,
currentVersion < TOOLCHAIN_SUPPORTED_VERSION -> project.objects.newInstance<NonExistingToolchainSupport>() project.tasks,
else -> project.objects.newInstance<DefaultToolchainSupport>( project.plugins
project.extensions, )
project.tasks,
project.plugins
)
}
} }
} }
} }
internal abstract class NonExistingToolchainSupport : ToolchainSupport {
override fun applyToolchain(
action: Action<Any>
) {
throw GradleException("JavaToolchain support is only available from Gradle 6.7")
}
}
internal abstract class DefaultToolchainSupport @Inject constructor( internal abstract class DefaultToolchainSupport @Inject constructor(
private val extensions: ExtensionContainer, private val extensions: ExtensionContainer,
private val tasks: TaskContainer, private val tasks: TaskContainer,
@@ -64,7 +49,7 @@ internal abstract class DefaultToolchainSupport @Inject constructor(
} }
override fun applyToolchain( override fun applyToolchain(
action: Action<Any> action: Action<JavaToolchainSpec>
) { ) {
action.execute(toolchainSpec) action.execute(toolchainSpec)
configureToolchain() configureToolchain()
@@ -123,10 +123,7 @@ abstract class KaptTask @Inject constructor(
@get:Internal @get:Internal
internal val defaultKotlinJavaToolchain: Provider<DefaultKotlinJavaToolchain> = objectFactory internal val defaultKotlinJavaToolchain: Provider<DefaultKotlinJavaToolchain> = objectFactory
.propertyWithNewInstance( .propertyWithNewInstance({ null })
project.gradle,
{ null }
)
final override val kotlinJavaToolchainProvider: Provider<KotlinJavaToolchain> = defaultKotlinJavaToolchain.cast() final override val kotlinJavaToolchainProvider: Provider<KotlinJavaToolchain> = defaultKotlinJavaToolchain.cast()
@@ -9,34 +9,27 @@ import org.gradle.api.GradleException
import org.gradle.api.JavaVersion import org.gradle.api.JavaVersion
import org.gradle.api.file.ProjectLayout import org.gradle.api.file.ProjectLayout
import org.gradle.api.file.RegularFileProperty import org.gradle.api.file.RegularFileProperty
import org.gradle.api.invocation.Gradle
import org.gradle.api.model.ObjectFactory import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Property import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider 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.gradle.util.GradleVersion
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.KotlinJvmOptionsImpl
import org.jetbrains.kotlin.gradle.tasks.KotlinJavaToolchain.Companion.TOOLCHAIN_SUPPORTED_VERSION
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
import org.jetbrains.kotlin.gradle.utils.providerWithLazyConvention import org.jetbrains.kotlin.gradle.utils.providerWithLazyConvention
import java.io.File import java.io.File
import javax.inject.Inject import javax.inject.Inject
import kotlin.reflect.full.functions
internal abstract class DefaultKotlinJavaToolchain @Inject constructor( internal abstract class DefaultKotlinJavaToolchain @Inject constructor(
private val objects: ObjectFactory, private val objects: ObjectFactory,
projectLayout: ProjectLayout, projectLayout: ProjectLayout,
gradle: Gradle,
kotlinCompileTaskProvider: () -> KotlinCompile? kotlinCompileTaskProvider: () -> KotlinCompile?
) : KotlinJavaToolchain { ) : KotlinJavaToolchain {
private val currentGradleVersion = GradleVersion.version(gradle.gradleVersion)
@get:Internal @get:Internal
internal val currentJvm: Provider<Jvm> = objects internal val currentJvm: Provider<Jvm> = objects
.property(Jvm.current()) .property(Jvm.current())
@@ -116,23 +109,13 @@ internal abstract class DefaultKotlinJavaToolchain @Inject constructor(
final override val jdk: KotlinJavaToolchain.JdkSetter = DefaultJdkSetter( final override val jdk: KotlinJavaToolchain.JdkSetter = DefaultJdkSetter(
providedJvm, providedJvm,
currentGradleVersion,
objects, objects,
{ providedJvmExplicitlySet = true }, { providedJvmExplicitlySet = true },
kotlinCompileTaskProvider kotlinCompileTaskProvider
) )
private val defaultJavaToolchainSetter by lazy(LazyThreadSafetyMode.NONE) { final override val toolchain: KotlinJavaToolchain.JavaToolchainSetter =
if (currentGradleVersion >= TOOLCHAIN_SUPPORTED_VERSION) { DefaultJavaToolchainSetter(providedJvm, kotlinCompileTaskProvider)
DefaultJavaToolchainSetter(providedJvm, kotlinCompileTaskProvider)
} else {
null
}
}
final override val toolchain: KotlinJavaToolchain.JavaToolchainSetter
get() = defaultJavaToolchainSetter
?: throw GradleException("Toolchain support is available from $TOOLCHAIN_SUPPORTED_VERSION")
/** /**
* Updates [task] 'jvmTarget' if user has configured toolchain and not 'jvmTarget'. * Updates [task] 'jvmTarget' if user has configured toolchain and not 'jvmTarget'.
@@ -197,7 +180,6 @@ internal abstract class DefaultKotlinJavaToolchain @Inject constructor(
private class DefaultJdkSetter( private class DefaultJdkSetter(
private val providedJvm: Property<Jvm>, private val providedJvm: Property<Jvm>,
private val currentGradleVersion: GradleVersion,
private val objects: ObjectFactory, private val objects: ObjectFactory,
private val updateProvidedJdkCallback: () -> Unit, private val updateProvidedJdkCallback: () -> Unit,
kotlinCompileTaskProvider: () -> KotlinCompile? kotlinCompileTaskProvider: () -> KotlinCompile?
@@ -219,14 +201,7 @@ internal abstract class DefaultKotlinJavaToolchain @Inject constructor(
providedJvm.set( providedJvm.set(
objects.providerWithLazyConvention { objects.providerWithLazyConvention {
updateJvmTarget(jdkVersion) updateJvmTarget(jdkVersion)
if (currentGradleVersion < GradleVersion.version("6.2.0")) { Jvm.discovered(jdkHomeLocation, null, jdkVersion)
// Before Gradle 6.2.0 'Jvm.discovered' does not have 'implementationJavaVersion' parameter
Jvm::class.functions
.first { it.name == "discovered" }
.call(jdkHomeLocation, jdkVersion) as Jvm
} else {
Jvm.discovered(jdkHomeLocation, null, jdkVersion)
}
} }
) )
} }
@@ -678,10 +678,7 @@ abstract class KotlinCompile @Inject constructor(
@get:Internal @get:Internal
internal val defaultKotlinJavaToolchain: Provider<DefaultKotlinJavaToolchain> = objects internal val defaultKotlinJavaToolchain: Provider<DefaultKotlinJavaToolchain> = objects
.propertyWithNewInstance( .propertyWithNewInstance({ this })
project.gradle,
{ this }
)
final override val kotlinJavaToolchainProvider: Provider<KotlinJavaToolchain> = defaultKotlinJavaToolchain.cast() final override val kotlinJavaToolchainProvider: Provider<KotlinJavaToolchain> = defaultKotlinJavaToolchain.cast()