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(
javaexecPath: String
) = assertOutputContains("[KOTLIN] Kotlin compilation 'jdkHome' argument: $javaexecPath")
@@ -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"
}
}
@@ -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.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<KotlinJvmOptionsBase>?
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<KotlinJvmOptionsBase>?
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<Jvm>,
private val currentGradleVersion: GradleVersion,
kotlinCompileTaskProvider: () -> KotlinCompileTask<KotlinJvmOptionsBase>?
kotlinCompileTaskProvider: () -> KotlinCompile?
) : JvmTargetUpdater(kotlinCompileTaskProvider),
KotlinJavaToolchain.JdkSetter {
@@ -174,7 +177,7 @@ internal abstract class DefaultKotlinJavaToolchain @Inject constructor(
private inner class DefaultJavaToolchainSetter(
private val providedJvm: Property<Jvm>,
kotlinCompileTaskProvider: () -> KotlinCompileTask<KotlinJvmOptionsBase>?
kotlinCompileTaskProvider: () -> KotlinCompile?
) : JvmTargetUpdater(kotlinCompileTaskProvider),
KotlinJavaToolchain.JavaToolchainSetter {
override fun use(