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
This commit is contained in:
Yahor Berdnikau
2021-07-21 11:49:14 +02:00
committed by Space
parent e3b219b68f
commit 1e758c6767
8 changed files with 121 additions and 9 deletions
@@ -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( private fun BuildResult.assertJdkHomeIsUsingJdk(
javaexecPath: String javaexecPath: String
) = assertOutputContains("[KOTLIN] Kotlin compilation 'jdkHome' argument: $javaexecPath") ) = assertOutputContains("[KOTLIN] Kotlin compilation 'jdkHome' argument: $javaexecPath")
@@ -20,4 +20,8 @@ interface TestVersions {
val CURRENT val CURRENT
get() = System.getProperty("kotlinVersion") ?: error("Required to specify kotlinVersion system property for tests") get() = System.getProperty("kotlinVersion") ?: error("Required to specify kotlinVersion system property for tests")
} }
object AGP {
const val AGP_42 = "4.2.2"
}
} }
@@ -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'
}
}
@@ -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")
}
}
}
}
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapplication">
<application
android:name="example.App">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
@@ -0,0 +1,9 @@
package example;
import android.app.Application;
class App extends Application {
public App() {
super();
}
}
@@ -0,0 +1,7 @@
package example
import android.app.Activity
class MainActivity : Activity() {
}
@@ -17,8 +17,7 @@ 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.gradle.util.GradleVersion
import org.jetbrains.kotlin.gradle.dsl.KotlinCompile as KotlinCompileTask import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsBase
import org.jetbrains.kotlin.gradle.tasks.KotlinJavaToolchain.Companion.TOOLCHAIN_SUPPORTED_VERSION 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
@@ -31,7 +30,7 @@ internal abstract class DefaultKotlinJavaToolchain @Inject constructor(
private val objects: ObjectFactory, private val objects: ObjectFactory,
projectLayout: ProjectLayout, projectLayout: ProjectLayout,
gradle: Gradle, gradle: Gradle,
kotlinCompileTaskProvider: () -> KotlinCompileTask<KotlinJvmOptionsBase>? kotlinCompileTaskProvider: () -> KotlinCompile?
) : KotlinJavaToolchain { ) : KotlinJavaToolchain {
private val currentGradleVersion = GradleVersion.version(gradle.gradleVersion) 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") ?: throw GradleException("Toolchain support is available from $TOOLCHAIN_SUPPORTED_VERSION")
private abstract class JvmTargetUpdater( private abstract class JvmTargetUpdater(
private val kotlinCompileTaskProvider: () -> KotlinCompileTask<KotlinJvmOptionsBase>? private val kotlinCompileTaskProvider: () -> KotlinCompile?
) { ) {
fun updateJvmTarget( fun updateJvmTarget(
jdkVersion: JavaVersion jdkVersion: JavaVersion
) { ) {
kotlinCompileTaskProvider()?.kotlinOptions { kotlinCompileTaskProvider()?.let { task ->
if (jvmTargetField == null) { // 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 // 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" "9"
} else { } else {
jdkVersion.toString() jdkVersion.toString()
@@ -141,7 +144,7 @@ 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 currentGradleVersion: GradleVersion,
kotlinCompileTaskProvider: () -> KotlinCompileTask<KotlinJvmOptionsBase>? kotlinCompileTaskProvider: () -> KotlinCompile?
) : JvmTargetUpdater(kotlinCompileTaskProvider), ) : JvmTargetUpdater(kotlinCompileTaskProvider),
KotlinJavaToolchain.JdkSetter { KotlinJavaToolchain.JdkSetter {
@@ -174,7 +177,7 @@ internal abstract class DefaultKotlinJavaToolchain @Inject constructor(
private inner class DefaultJavaToolchainSetter( private inner class DefaultJavaToolchainSetter(
private val providedJvm: Property<Jvm>, private val providedJvm: Property<Jvm>,
kotlinCompileTaskProvider: () -> KotlinCompileTask<KotlinJvmOptionsBase>? kotlinCompileTaskProvider: () -> KotlinCompile?
) : JvmTargetUpdater(kotlinCompileTaskProvider), ) : JvmTargetUpdater(kotlinCompileTaskProvider),
KotlinJavaToolchain.JavaToolchainSetter { KotlinJavaToolchain.JavaToolchainSetter {
override fun use( override fun use(