[Gradle] deprecate android and introduce androidTarget preset

Android preset needs to be removed in favor of Android Pluggable Target

Changes were originally introduced by commit:
becf50ee0f
but then, unfortunately, reverted due to binary compatibility issues

^KT-59049 Verification Pending
^KT-57903 Verification Pending
This commit is contained in:
Anton Lakotka
2023-06-02 18:55:25 +02:00
committed by Space Team
parent 5a8b6e9603
commit e5d35f7d1a
4 changed files with 131 additions and 42 deletions
@@ -20,9 +20,7 @@ private val presetsProperty = KotlinTargetsContainerWithPresets::presets.name
private fun generateKotlinTargetContainerWithPresetFunctionsInterface() {
// Generate KotlinMultiplatformExtension subclass with member functions for the presets:
val functions = allPresetEntries.map { kotlinPreset ->
// magic indent is needed to make the result look pretty
val funPrefix = kotlinPreset.deprecation?.let { "\n $it\n @Suppress(\"DEPRECATION_ERROR\")\n " } ?: ""
generatePresetFunctions(kotlinPreset, presetsProperty, "configureOrCreate", funPrefix)
generatePresetFunctions(kotlinPreset, presetsProperty, "configureOrCreate")
}
val parentInterfaceName =
@@ -45,10 +43,13 @@ private fun generateKotlinTargetContainerWithPresetFunctionsInterface() {
val generatedCodeWarning = "// DO NOT EDIT MANUALLY! Generated by ${object {}.javaClass.enclosingClass.name}"
val extraTopLevelDeclarations = allPresetEntries.flatMap { it.extraTopLevelDeclarations }.joinToString("\n")
val code = listOf(
"package ${className.packageName()}",
imports,
generatedCodeWarning,
extraTopLevelDeclarations,
"interface ${className.renderShort()} : ${parentInterfaceName.renderShort()} {",
functions.joinToString("\n\n") { it.indented(4) },
"}"
@@ -62,23 +63,59 @@ private fun generatePresetFunctions(
presetEntry: KotlinPresetEntry,
getPresetsExpression: String,
configureOrCreateFunctionName: String,
funPrefix: String = ""
): String {
fun deprecated(replaceWithArguments: List<String>? = null): String {
val deprecation = presetEntry.deprecation ?: return ""
val deprecationAnnotation = if (deprecation.replaceWithOtherPreset != null && replaceWithArguments != null) {
val replaceWith = "ReplaceWith(\"${deprecation.replaceWithOtherPreset}(${replaceWithArguments.joinToString(",")})\")"
"@Deprecated(${deprecation.message}, level = DeprecationLevel.${deprecation.level.name}, replaceWith = $replaceWith)"
} else {
"@Deprecated(${deprecation.message}, level = DeprecationLevel.${deprecation.level.name})"
}
// magic indent is needed to make the result look pretty
return "\n $deprecationAnnotation\n "
}
val suppress = if (presetEntry.deprecation != null) {
val suppressDeprecationId = when (presetEntry.deprecation.level) {
DeprecationLevel.WARNING -> "DEPRECATION"
DeprecationLevel.ERROR -> "DEPRECATION_ERROR"
DeprecationLevel.HIDDEN -> "DEPRECATION_HIDDEN"
}
"@Suppress(\"$suppressDeprecationId\")\n "
} else {
""
}
val alsoBlockAfterConfiguration = if (presetEntry.alsoBlockAfterConfiguration != null) {
"""
.also {
${presetEntry.alsoBlockAfterConfiguration.indented(16, skipFirstLine = true)}
}
""".trimIndent().indented(8, skipFirstLine = true)
} else {
""
}
val presetName = presetEntry.presetName
val entityName = presetEntry.entityName
return """
${funPrefix}fun $presetName(
name: String = "$presetName",
${deprecated()}fun $presetName(
name: String = "$entityName",
configure: ${presetEntry.targetType.renderShort()}.() -> Unit = { }
): ${presetEntry.targetType.renderShort()} =
$configureOrCreateFunctionName(
name,
$getPresetsExpression.getByName("$presetName") as ${presetEntry.presetType.renderShort()},
$getPresetsExpression.getByName("$entityName") as ${presetEntry.presetType.renderShort()},
configure
)
)$alsoBlockAfterConfiguration
${funPrefix}fun $presetName() = $presetName("$presetName") { }
${funPrefix}fun $presetName(name: String) = $presetName(name) { }
${funPrefix}fun $presetName(name: String, configure: Action<${presetEntry.targetType.renderShort()}>) = $presetName(name) { configure.execute(this) }
${funPrefix}fun $presetName(configure: Action<${presetEntry.targetType.renderShort()}>) = $presetName { configure.execute(this) }
${deprecated(emptyList())}${suppress}fun $presetName() = $presetName("$entityName") { }
${deprecated(listOf("name"))}${suppress}fun $presetName(name: String) = $presetName(name) { }
${deprecated()}${suppress}fun $presetName(name: String, configure: Action<${presetEntry.targetType.renderShort()}>) = $presetName(name) { configure.execute(this) }
${deprecated()}${suppress}fun $presetName(configure: Action<${presetEntry.targetType.renderShort()}>) = $presetName { configure.execute(this) }
""".trimIndent()
}
@@ -15,8 +15,19 @@ internal class KotlinPresetEntry(
val presetName: String,
val presetType: TypeName,
val targetType: TypeName,
val deprecation: String? = null
)
val deprecation: Deprecation? = null,
val entityName: String = presetName,
// Adds `.also { $alsoBlockAfterConfiguration }` after configureOrCreate(...)
val alsoBlockAfterConfiguration: String? = null,
// Extra declarations will be inserted before functions are generated
val extraTopLevelDeclarations: List<String> = emptyList(),
) {
class Deprecation(
val message: String,
val level: DeprecationLevel,
val replaceWithOtherPreset: String? = null // when set, it will generate ReplaceWith with related argument names
)
}
internal fun KotlinPresetEntry.typeNames(): Set<TypeName> = setOf(presetType, targetType)
@@ -42,10 +53,34 @@ internal val jvmPresetEntry = KotlinPresetEntry(
typeName("org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget")
)
internal val androidTargetPresetEntry = KotlinPresetEntry(
"androidTarget",
typeName("$MPP_PACKAGE.KotlinAndroidTargetPreset"),
typeName("$MPP_PACKAGE.KotlinAndroidTarget"),
entityName = "android",
)
internal val androidPresetEntry = KotlinPresetEntry(
"android",
typeName("$MPP_PACKAGE.KotlinAndroidTargetPreset"),
typeName("$MPP_PACKAGE.KotlinAndroidTarget")
typeName("$MPP_PACKAGE.KotlinAndroidTarget"),
deprecation = KotlinPresetEntry.Deprecation(
message = "ANDROID_TARGET_MIGRATION_MESSAGE",
level = DeprecationLevel.WARNING,
replaceWithOtherPreset = "androidTarget"
),
extraTopLevelDeclarations = listOf(
"private const val ANDROID_TARGET_MIGRATION_MESSAGE" +
" = \"Please use androidTarget() instead. Learn more here: https://kotl.in/android-target-dsl\""
),
alsoBlockAfterConfiguration = """
it.project.logger.warn(
""${'"'}
w: Please use `androidTarget` function instead of `android` to configure android target inside `kotlin { }` block.
See the details here: https://kotl.in/android-target-dsl
""${'"'}.trimIndent()
)
""".trimIndent()
)
// Note: modifying these sets should also be reflected in the MPP plugin code, see 'setupDefaultPresets'
@@ -75,12 +110,16 @@ internal val nativePresetEntries = HostManager().targets
else ->
Presets.simple to Targets.base
}
val deprecation = "@Deprecated(DEPRECATED_TARGET_MESSAGE, level = DeprecationLevel.ERROR)".takeIf { target in KonanTarget.deprecatedTargets }
val deprecation = KotlinPresetEntry.Deprecation(
message = "DEPRECATED_TARGET_MESSAGE",
level = DeprecationLevel.ERROR
).takeIf { target in KonanTarget.deprecatedTargets }
KotlinPresetEntry(target.presetName, typeName(presetType), typeName(targetType), deprecation)
}
internal val allPresetEntries = listOf(
jvmPresetEntry,
androidTargetPresetEntry,
androidPresetEntry
) + nativePresetEntries
@@ -6,8 +6,6 @@
package org.jetbrains.kotlin.gradle.dsl
import org.gradle.api.*
import org.gradle.api.internal.plugins.DslObject
import org.gradle.api.logging.Logger
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle.Stage.AfterFinaliseDsl
@@ -163,20 +161,4 @@ internal fun <T : KotlinTarget> KotlinTargetsContainerWithPresets.configureOrCre
)
}
}
}
internal fun KotlinTargetsContainerWithPresets.configureOrCreateAndroidTargetAndReportDeprecation(
targetName: String,
configure: KotlinAndroidTarget.() -> Unit,
): KotlinAndroidTarget {
val targetPreset = presets.getByName("android") as KotlinAndroidTargetPreset
val result = configureOrCreate(targetName, targetPreset, configure)
result.project.logger.warn(
"""
w: Please use `androidTarget` function instead of `android` to configure android target inside `kotlin { }` block.
See the details here: https://kotl.in/android-target-dsl
""".trimIndent()
)
return result
}
@@ -16,6 +16,8 @@ import org.jetbrains.kotlin.konan.target.DEPRECATED_TARGET_MESSAGE
// DO NOT EDIT MANUALLY! Generated by org.jetbrains.kotlin.generators.gradle.dsl.MppPresetFunctionsCodegenKt
private const val ANDROID_TARGET_MIGRATION_MESSAGE = "Please use androidTarget() instead. Learn more here: https://kotl.in/android-target-dsl"
interface KotlinTargetContainerWithPresetFunctions : KotlinTargetsContainerWithPresets {
fun jvm(
@@ -33,7 +35,7 @@ interface KotlinTargetContainerWithPresetFunctions : KotlinTargetsContainerWithP
fun jvm(name: String, configure: Action<KotlinJvmTarget>) = jvm(name) { configure.execute(this) }
fun jvm(configure: Action<KotlinJvmTarget>) = jvm { configure.execute(this) }
fun android(
fun androidTarget(
name: String = "android",
configure: KotlinAndroidTarget.() -> Unit = { }
): KotlinAndroidTarget =
@@ -43,9 +45,45 @@ interface KotlinTargetContainerWithPresetFunctions : KotlinTargetsContainerWithP
configure
)
fun androidTarget() = androidTarget("android") { }
fun androidTarget(name: String) = androidTarget(name) { }
fun androidTarget(name: String, configure: Action<KotlinAndroidTarget>) = androidTarget(name) { configure.execute(this) }
fun androidTarget(configure: Action<KotlinAndroidTarget>) = androidTarget { configure.execute(this) }
@Deprecated(ANDROID_TARGET_MIGRATION_MESSAGE, level = DeprecationLevel.WARNING)
fun android(
name: String = "android",
configure: KotlinAndroidTarget.() -> Unit = { }
): KotlinAndroidTarget =
configureOrCreate(
name,
presets.getByName("android") as KotlinAndroidTargetPreset,
configure
).also {
it.project.logger.warn(
"""
w: Please use `androidTarget` function instead of `android` to configure android target inside `kotlin { }` block.
See the details here: https://kotl.in/android-target-dsl
""".trimIndent()
)
}
@Deprecated(ANDROID_TARGET_MIGRATION_MESSAGE, level = DeprecationLevel.WARNING, replaceWith = ReplaceWith("androidTarget()"))
@Suppress("DEPRECATION")
fun android() = android("android") { }
@Deprecated(ANDROID_TARGET_MIGRATION_MESSAGE, level = DeprecationLevel.WARNING, replaceWith = ReplaceWith("androidTarget(name)"))
@Suppress("DEPRECATION")
fun android(name: String) = android(name) { }
@Deprecated(ANDROID_TARGET_MIGRATION_MESSAGE, level = DeprecationLevel.WARNING)
@Suppress("DEPRECATION")
fun android(name: String, configure: Action<KotlinAndroidTarget>) = android(name) { configure.execute(this) }
@Deprecated(ANDROID_TARGET_MIGRATION_MESSAGE, level = DeprecationLevel.WARNING)
@Suppress("DEPRECATION")
fun android(configure: Action<KotlinAndroidTarget>) = android { configure.execute(this) }
fun androidNativeX64(
@@ -110,7 +148,6 @@ interface KotlinTargetContainerWithPresetFunctions : KotlinTargetsContainerWithP
@Deprecated(DEPRECATED_TARGET_MESSAGE, level = DeprecationLevel.ERROR)
@Suppress("DEPRECATION_ERROR")
fun iosArm32(
name: String = "iosArm32",
configure: KotlinNativeTarget.() -> Unit = { }
@@ -215,7 +252,6 @@ interface KotlinTargetContainerWithPresetFunctions : KotlinTargetsContainerWithP
@Deprecated(DEPRECATED_TARGET_MESSAGE, level = DeprecationLevel.ERROR)
@Suppress("DEPRECATION_ERROR")
fun watchosX86(
name: String = "watchosX86",
configure: KotlinNativeTargetWithSimulatorTests.() -> Unit = { }
@@ -350,7 +386,6 @@ interface KotlinTargetContainerWithPresetFunctions : KotlinTargetsContainerWithP
@Deprecated(DEPRECATED_TARGET_MESSAGE, level = DeprecationLevel.ERROR)
@Suppress("DEPRECATION_ERROR")
fun mingwX86(
name: String = "mingwX86",
configure: KotlinNativeTarget.() -> Unit = { }
@@ -440,7 +475,6 @@ interface KotlinTargetContainerWithPresetFunctions : KotlinTargetsContainerWithP
@Deprecated(DEPRECATED_TARGET_MESSAGE, level = DeprecationLevel.ERROR)
@Suppress("DEPRECATION_ERROR")
fun linuxArm32Hfp(
name: String = "linuxArm32Hfp",
configure: KotlinNativeTarget.() -> Unit = { }
@@ -470,7 +504,6 @@ interface KotlinTargetContainerWithPresetFunctions : KotlinTargetsContainerWithP
@Deprecated(DEPRECATED_TARGET_MESSAGE, level = DeprecationLevel.ERROR)
@Suppress("DEPRECATION_ERROR")
fun linuxMips32(
name: String = "linuxMips32",
configure: KotlinNativeTarget.() -> Unit = { }
@@ -500,7 +533,6 @@ interface KotlinTargetContainerWithPresetFunctions : KotlinTargetsContainerWithP
@Deprecated(DEPRECATED_TARGET_MESSAGE, level = DeprecationLevel.ERROR)
@Suppress("DEPRECATION_ERROR")
fun linuxMipsel32(
name: String = "linuxMipsel32",
configure: KotlinNativeTarget.() -> Unit = { }
@@ -530,7 +562,6 @@ interface KotlinTargetContainerWithPresetFunctions : KotlinTargetsContainerWithP
@Deprecated(DEPRECATED_TARGET_MESSAGE, level = DeprecationLevel.ERROR)
@Suppress("DEPRECATION_ERROR")
fun wasm32(
name: String = "wasm32",
configure: KotlinNativeTarget.() -> Unit = { }