From 1e758c67673671447163d87e21bcb17fe6a23b5e Mon Sep 17 00:00:00 2001 From: Yahor Berdnikau Date: Wed, 21 Jul 2021 11:49:14 +0200 Subject: [PATCH] Toolchain takes into account kotlin options set via Android extension. This extension updates not common task kotlin options, but special field in the task. Toolchain will also check this field to decide whether it should set 'jvmTarget' or not. ^KT-47754 Fixed --- .../kotlin/gradle/KotlinJavaToolchainTest.kt | 18 ++++++++++ .../kotlin/gradle/testbase/TestVersions.kt | 4 +++ .../android/build.gradle | 34 +++++++++++++++++++ .../android/settings.gradle | 21 ++++++++++++ .../android/src/main/AndroidManifest.xml | 16 +++++++++ .../android/src/main/java/example/App.java | 9 +++++ .../src/main/java/example/MainActivity.kt | 7 ++++ .../tasks/DefaultKotlinJavaToolchain.kt | 21 +++++++----- 8 files changed, 121 insertions(+), 9 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-java-toolchain/android/build.gradle create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-java-toolchain/android/settings.gradle create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-java-toolchain/android/src/main/AndroidManifest.xml create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-java-toolchain/android/src/main/java/example/App.java create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-java-toolchain/android/src/main/java/example/MainActivity.kt diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinJavaToolchainTest.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinJavaToolchainTest.kt index 8d70e6c449d..bba1d195d1d 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinJavaToolchainTest.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinJavaToolchainTest.kt @@ -653,6 +653,24 @@ class KotlinJavaToolchainTest : KGPBaseTest() { } } + @DisplayName("Toolchain should take into account kotlin options that are set via android extension") + @GradleTestVersions(minVersion = "6.7.1") + @GradleTest + internal fun kotlinOptionsAndroidAndToolchain(gradleVersion: GradleVersion) { + project("android".fullProjectName, gradleVersion) { + useToolchainExtension(11) + + //language=properties + gradleProperties.append( + """ + kotlin.jvm.target.validation.mode = error + """.trimIndent() + ) + + build("assembleDebug", "-Pagp_version=${TestVersions.AGP.AGP_42}") + } + } + private fun BuildResult.assertJdkHomeIsUsingJdk( javaexecPath: String ) = assertOutputContains("[KOTLIN] Kotlin compilation 'jdkHome' argument: $javaexecPath") diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/TestVersions.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/TestVersions.kt index 6a34be63e96..842b639ec9c 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/TestVersions.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/TestVersions.kt @@ -20,4 +20,8 @@ interface TestVersions { val CURRENT get() = System.getProperty("kotlinVersion") ?: error("Required to specify kotlinVersion system property for tests") } + + object AGP { + const val AGP_42 = "4.2.2" + } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-java-toolchain/android/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-java-toolchain/android/build.gradle new file mode 100644 index 00000000000..fac044f0ac2 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-java-toolchain/android/build.gradle @@ -0,0 +1,34 @@ +plugins { + id 'com.android.application' + id 'org.jetbrains.kotlin.android' +} + +repositories { + mavenLocal() + google() + mavenCentral() +} + +android { + compileSdkVersion 30 + defaultConfig { + applicationId "com.example.myapplication" + minSdkVersion 30 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = '1.8' + } +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-java-toolchain/android/settings.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-java-toolchain/android/settings.gradle new file mode 100644 index 00000000000..bbe0b104ba1 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-java-toolchain/android/settings.gradle @@ -0,0 +1,21 @@ +pluginManagement { + repositories { + mavenLocal() + mavenCentral() + google() + } + + plugins { + id "org.jetbrains.kotlin.jvm" version "$kotlin_version" + id "org.jetbrains.kotlin.android" version "$kotlin_version" + id "org.jetbrains.kotlin.kapt" version "$kotlin_version" + } + + resolutionStrategy { + eachPlugin { + if (requested.id.id == "com.android.application") { + useModule("com.android.tools.build:gradle:$agp_version") + } + } + } +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-java-toolchain/android/src/main/AndroidManifest.xml b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-java-toolchain/android/src/main/AndroidManifest.xml new file mode 100644 index 00000000000..551a58ce9a4 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-java-toolchain/android/src/main/AndroidManifest.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-java-toolchain/android/src/main/java/example/App.java b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-java-toolchain/android/src/main/java/example/App.java new file mode 100644 index 00000000000..b27ed3a4650 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-java-toolchain/android/src/main/java/example/App.java @@ -0,0 +1,9 @@ +package example; + +import android.app.Application; + +class App extends Application { + public App() { + super(); + } +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-java-toolchain/android/src/main/java/example/MainActivity.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-java-toolchain/android/src/main/java/example/MainActivity.kt new file mode 100644 index 00000000000..a7ff49d298c --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-java-toolchain/android/src/main/java/example/MainActivity.kt @@ -0,0 +1,7 @@ +package example + +import android.app.Activity + +class MainActivity : Activity() { + +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/DefaultKotlinJavaToolchain.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/DefaultKotlinJavaToolchain.kt index 4242587b6c1..2ae4f445bb5 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/DefaultKotlinJavaToolchain.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/DefaultKotlinJavaToolchain.kt @@ -17,8 +17,7 @@ import org.gradle.api.tasks.Internal import org.gradle.internal.jvm.Jvm import org.gradle.jvm.toolchain.* import org.gradle.util.GradleVersion -import org.jetbrains.kotlin.gradle.dsl.KotlinCompile as KotlinCompileTask -import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsBase +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.property @@ -31,7 +30,7 @@ internal abstract class DefaultKotlinJavaToolchain @Inject constructor( private val objects: ObjectFactory, projectLayout: ProjectLayout, gradle: Gradle, - kotlinCompileTaskProvider: () -> KotlinCompileTask? + kotlinCompileTaskProvider: () -> KotlinCompile? ) : KotlinJavaToolchain { private val currentGradleVersion = GradleVersion.version(gradle.gradleVersion) @@ -120,15 +119,19 @@ internal abstract class DefaultKotlinJavaToolchain @Inject constructor( ?: throw GradleException("Toolchain support is available from $TOOLCHAIN_SUPPORTED_VERSION") private abstract class JvmTargetUpdater( - private val kotlinCompileTaskProvider: () -> KotlinCompileTask? + private val kotlinCompileTaskProvider: () -> KotlinCompile? ) { fun updateJvmTarget( jdkVersion: JavaVersion ) { - kotlinCompileTaskProvider()?.kotlinOptions { - if (jvmTargetField == null) { + kotlinCompileTaskProvider()?.let { task -> + // parentKotlinOptionsImpl is set from 'kotlin-android' plugin + val appliedJvmTargets = listOfNotNull(task.kotlinOptions, task.parentKotlinOptionsImpl.orNull) + .mapNotNull { (it as KotlinJvmOptionsImpl).jvmTargetField } + + if (appliedJvmTargets.isEmpty()) { // For Java 9 JavaVersion returns "1.9" that is not accepted by Kotlin compiler - jvmTarget = if (jdkVersion == JavaVersion.VERSION_1_9) { + task.kotlinOptions.jvmTarget = if (jdkVersion == JavaVersion.VERSION_1_9) { "9" } else { jdkVersion.toString() @@ -141,7 +144,7 @@ internal abstract class DefaultKotlinJavaToolchain @Inject constructor( private class DefaultJdkSetter( private val providedJvm: Property, private val currentGradleVersion: GradleVersion, - kotlinCompileTaskProvider: () -> KotlinCompileTask? + kotlinCompileTaskProvider: () -> KotlinCompile? ) : JvmTargetUpdater(kotlinCompileTaskProvider), KotlinJavaToolchain.JdkSetter { @@ -174,7 +177,7 @@ internal abstract class DefaultKotlinJavaToolchain @Inject constructor( private inner class DefaultJavaToolchainSetter( private val providedJvm: Property, - kotlinCompileTaskProvider: () -> KotlinCompileTask? + kotlinCompileTaskProvider: () -> KotlinCompile? ) : JvmTargetUpdater(kotlinCompileTaskProvider), KotlinJavaToolchain.JavaToolchainSetter { override fun use(