[Gradle] Sync ListProperty, SetProperty and MapProperty types as non-convention

Such approach, while does not conform conceptually, ensures
compatibility with existing user build scripts and works more logically
for external users: https://github.com/gradle/gradle/issues/18352

^KT-59056 Fixed
This commit is contained in:
Yahor Berdnikau
2023-06-04 23:04:41 +02:00
committed by Space Team
parent 48484368c7
commit 67090ff10a
7 changed files with 101 additions and 37 deletions
@@ -720,9 +720,24 @@ private fun Printer.generateCompilerOptionsHelper(
}
println(") {")
withIndent {
val multiValuesReturnTypes = setOf(
"org.gradle.api.provider.ListProperty",
"org.gradle.api.provider.SetProperty",
)
if (parentHelperName != null) println("$parentHelperName.syncOptionsAsConvention(from, into)")
for (property in properties) {
println("into.${property.name}.convention(from.${property.name})")
// Behaviour of ListProperty, SetProperty, MapProperty append operators in regard to convention value
// is confusing for users: https://github.com/gradle/gradle/issues/18352
// To make it less confusing for such types instead of wiring them via ".convention()" we updating
// current value
val gradleLazyReturnType = property.gradleLazyReturnType
val mapper = when {
multiValuesReturnTypes.any { gradleLazyReturnType.startsWith(it) } -> "addAll"
gradleLazyReturnType.startsWith("org.gradle.api.provider.MapProperty") -> "putAll"
else -> "convention"
}
println("into.${property.name}.$mapper(from.${property.name})")
}
}
println("}")
@@ -151,32 +151,16 @@ class CompilerOptionsProjectIT : KGPBaseTest() {
build("compileKotlin") {
assertTasksExecuted(":compileKotlin")
val compilationArgs = output.lineSequence().first { it.contains("Kotlin compiler args:") }
assertCompilerArguments(
":compileKotlin",
"-language-version 1.9",
"-api-version 1.9",
"-Xdebug",
"-opt-in my.custom.OptInAnnotation,another.CustomOptInAnnotation",
"-XXLanguage:+UnitConversionsOnArbitraryExpressions"
)
assert(compilationArgs.contains("-language-version 1.9")) {
printBuildOutput()
"Compiler arguments does not contain '-language-version 1.9': $compilationArgs"
}
assert(compilationArgs.contains("-api-version 1.9")) {
printBuildOutput()
"Compiler arguments does not contain '-api-version 2.0': $compilationArgs"
}
assert(!compilationArgs.contains("-progressive")) {
printBuildOutput()
"Compiler arguments contains '-progressive': $compilationArgs"
}
assert(compilationArgs.contains("-opt-in another.CustomOptInAnnotation")) {
printBuildOutput()
"Compiler arguments does not contain '-opt-in another.CustomOptInAnnotation': $compilationArgs"
}
assert(compilationArgs.contains("-XXLanguage:+UnitConversionsOnArbitraryExpressions")) {
printBuildOutput()
"Compiler arguments does not contain '-XXLanguage:+UnitConversionsOnArbitraryExpressions': $compilationArgs"
}
assertNoCompilerArgument(":compileKotlin", "-progressive")
}
}
}
@@ -268,6 +252,58 @@ class CompilerOptionsProjectIT : KGPBaseTest() {
}
}
@DisplayName("KT-59056: freeCompilerArgs are combined with android.kotlinOptions.freeCompilerArgs")
@AndroidGradlePluginTests
@GradleAndroidTest
fun kotlinOptionsFreeCompilerArgs(
gradleVersion: GradleVersion,
agpVersion: String,
jdk: JdkVersions.ProvidedJdk
) {
project(
"AndroidIncrementalMultiModule",
gradleVersion,
buildOptions = defaultBuildOptions.copy(
androidVersion = agpVersion,
logLevel = LogLevel.DEBUG
),
buildJdk = jdk.location
) {
buildGradle.appendText(
//language=groovy
"""
|
|subprojects {
| tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile.class).configureEach {
| compilerOptions {
| freeCompilerArgs.addAll("-progressive")
| }
| }
|}
""".trimMargin()
)
subProject("libAndroid").buildGradle.appendText(
//language=groovy
"""
|
|android {
| kotlinOptions {
| freeCompilerArgs += ["-opt-in=com.example.roo.requiresOpt.FunTests"]
| }
|}
""".trimMargin()
)
build(":libAndroid:compileDebugKotlin") {
assertTasksExecuted(":libAndroid:compileDebugKotlin")
assertCompilerArgument(":libAndroid:compileDebugKotlin", "-progressive")
assertCompilerArgument(":libAndroid:compileDebugKotlin", "-opt-in=com.example.roo.requiresOpt.FunTests")
}
}
}
@DisplayName("KT-57688: task moduleName input overrides project level moduleName")
@JvmGradlePluginTests
@GradleTest
@@ -253,6 +253,27 @@ fun BuildResult.assertCompilerArgument(
}
}
fun BuildResult.assertCompilerArguments(
taskPath: String,
vararg expectedArguments: String,
) {
val taskOutput = getOutputForTask(taskPath)
val compilerArguments = taskOutput.lines().first {
it.contains("Kotlin compiler args:")
}.substringAfter("Kotlin compiler args:")
val nonExistingArguments = expectedArguments
.filter {
!compilerArguments.contains(it)
}
assert(nonExistingArguments.isEmpty()) {
printBuildOutput()
"$taskPath task compiler arguments don't contain ${nonExistingArguments.joinToString()}. Actual content: $compilerArguments"
}
}
fun BuildResult.assertNoCompilerArgument(
taskPath: String,
notExpectedArgument: String,
@@ -26,7 +26,7 @@ internal object KotlinCommonCompilerOptionsHelper {
org.jetbrains.kotlin.gradle.dsl.KotlinCommonCompilerToolOptionsHelper.syncOptionsAsConvention(from, into)
into.apiVersion.convention(from.apiVersion)
into.languageVersion.convention(from.languageVersion)
into.optIn.convention(from.optIn)
into.optIn.addAll(from.optIn)
into.progressiveMode.convention(from.progressiveMode)
into.useK2.convention(from.useK2)
}
@@ -24,6 +24,6 @@ internal object KotlinCommonCompilerToolOptionsHelper {
into.allWarningsAsErrors.convention(from.allWarningsAsErrors)
into.suppressWarnings.convention(from.suppressWarnings)
into.verbose.convention(from.verbose)
into.freeCompilerArgs.convention(from.freeCompilerArgs)
into.freeCompilerArgs.addAll(from.freeCompilerArgs)
}
}
@@ -118,7 +118,6 @@ internal class DefaultLanguageSettingsBuilder : LanguageSettingsBuilder {
internal fun applyLanguageSettingsToCompilerOptions(
languageSettingsBuilder: LanguageSettings,
compilerOptions: KotlinCommonCompilerOptions,
addFreeCompilerArgsAsConvention: Boolean = true,
) = with(compilerOptions) {
val languageSettingsBuilderDefault = languageSettingsBuilder as DefaultLanguageSettingsBuilder
languageSettingsBuilderDefault.languageVersion?.let {
@@ -139,11 +138,7 @@ internal fun applyLanguageSettingsToCompilerOptions(
freeArgs.addAll(languageSettingsBuilderDefault.freeCompilerArgsForNonImport)
if (freeArgs.isNotEmpty()) {
if (addFreeCompilerArgsAsConvention) {
freeCompilerArgs.convention(freeArgs)
} else {
freeCompilerArgs.addAll(freeArgs)
}
freeCompilerArgs.addAll(freeArgs)
}
}
@@ -56,9 +56,6 @@ internal abstract class AbstractKotlinCompileConfig<TASK : AbstractKotlinCompile
applyLanguageSettingsToCompilerOptions(
languageSettings.get(),
(it as org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask<*>).compilerOptions,
// KotlinJsIrTarget and KotlinJsIrTargetConfigurator add additional freeCompilerArgs essentially
// always overwriting convention value
addFreeCompilerArgsAsConvention = it !is Kotlin2JsCompile
)
}
}