From 6842842827ea0cfbc8e5fdb62c37654350818684 Mon Sep 17 00:00:00 2001 From: Yahor Berdnikau Date: Wed, 3 Aug 2022 17:37:35 +0200 Subject: [PATCH] Generate KotlinVersion Gradle DSL object To avoid exposing compiler internal types inside Gradle DSL public api. ApiVersion and LanguageVersion in terms of compiler api is almost the same. Actually ApiVersion is generated based on LanguageVersion. To reduce user confusion what enum to use and what is the difference - in Gradle DSL they are now exposed as single enum - KotlinVersion. Mark KotlinVersion with DeprecationLevel.ERROR if related LanguageVersion is unsupported and with DeprecationLevel.WARNING if related LanguageVersion is deprecated. ^KT-27301 In Progress --- .../arguments/GenerateGradleOptions.kt | 9 ++-- .../arguments/kotlinVersionGenerator.kt | 48 +++++++++++++++++++ .../kotlin/gradle/dsl/KotlinVersion.kt | 23 +++++++++ 3 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 generators/tests/org/jetbrains/kotlin/generators/arguments/kotlinVersionGenerator.kt create mode 100644 libraries/tools/kotlin-gradle-plugin-api/src/common/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinVersion.kt diff --git a/generators/tests/org/jetbrains/kotlin/generators/arguments/GenerateGradleOptions.kt b/generators/tests/org/jetbrains/kotlin/generators/arguments/GenerateGradleOptions.kt index 1e8d20a56b2..25b49062ff9 100644 --- a/generators/tests/org/jetbrains/kotlin/generators/arguments/GenerateGradleOptions.kt +++ b/generators/tests/org/jetbrains/kotlin/generators/arguments/GenerateGradleOptions.kt @@ -32,6 +32,9 @@ fun generateKotlinGradleOptions(withPrinterToFile: (targetFile: File, Printer.() val apiSrcDir = File("libraries/tools/kotlin-gradle-plugin-api/src/common/kotlin") val srcDir = File("libraries/tools/kotlin-gradle-plugin/src/common/kotlin") + // specific Gradle types from internal compiler types + generateKotlinVersion(apiSrcDir, withPrinterToFile) + // common interface val commonInterfaceFqName = FqName("org.jetbrains.kotlin.gradle.dsl.KotlinCommonToolOptions") val commonOptions = gradleOptions() @@ -181,7 +184,7 @@ private inline fun List>.filterToBeDeleted() private inline fun gradleOptions(): List> = T::class.declaredMemberProperties.filter { it.findAnnotation() != null }.filterToBeDeleted().sortedBy { it.name } -private fun file(baseDir: File, fqName: FqName): File { +internal fun file(baseDir: File, fqName: FqName): File { val fileRelativePath = fqName.asString().replace(".", "/") + ".kt" return File(baseDir, fileRelativePath) } @@ -255,7 +258,7 @@ private fun Printer.generateImpl( println("}") } -private fun Printer.generateDeclaration( +internal fun Printer.generateDeclaration( modifiers: String, type: FqName, afterType: String? = null, @@ -303,7 +306,7 @@ private fun Printer.generateDoc(property: KProperty1<*, *>) { println(" */") } -private inline fun Printer.withIndent(fn: Printer.() -> Unit) { +internal inline fun Printer.withIndent(fn: Printer.() -> Unit) { pushIndent() fn() popIndent() diff --git a/generators/tests/org/jetbrains/kotlin/generators/arguments/kotlinVersionGenerator.kt b/generators/tests/org/jetbrains/kotlin/generators/arguments/kotlinVersionGenerator.kt new file mode 100644 index 00000000000..bc1c473c842 --- /dev/null +++ b/generators/tests/org/jetbrains/kotlin/generators/arguments/kotlinVersionGenerator.kt @@ -0,0 +1,48 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.generators.arguments + +import org.jetbrains.kotlin.config.LanguageVersion +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.utils.Printer +import java.io.File + +/** + * ApiVersion and LanguageVersion are almost the same in the compiler api, so Gradle DSL options + * exposes KotlinVersion that covers both of them. + */ +internal fun generateKotlinVersion( + apiDir: File, + filePrinter: (targetFile: File, Printer.() -> Unit) -> Unit +) { + val kotlinVersionFqName = FqName("org.jetbrains.kotlin.gradle.dsl.KotlinVersion") + filePrinter(file(apiDir, kotlinVersionFqName)) { + generateDeclaration("enum class", kotlinVersionFqName, afterType = "(val version: String)") { + val languageVersions = LanguageVersion.values() + + val lastIndex = languageVersions.size - 1 + languageVersions.forEachIndexed { index, languageVersion -> + val lastChar = if (index == lastIndex) ";" else "," + val prefix = when { + languageVersion.isUnsupported -> "@Deprecated(\"Unsupported\", level = DeprecationLevel.ERROR) " + languageVersion.isDeprecated -> "@Deprecated(\"Will be removed soon\") " + else -> "" + } + + println("${prefix}KOTLIN_${languageVersion.major}_${languageVersion.minor}(\"${languageVersion.versionString}\")$lastChar") + } + + println() + println("companion object {") + withIndent { + println("fun fromVersion(version: String): KotlinVersion =") + println(" KotlinVersion.values().firstOrNull { it.version == version }") + println(" ?: throw IllegalArgumentException(\"Unknown Kotlin version: ${'$'}version\")") + } + println("}") + } + } +} diff --git a/libraries/tools/kotlin-gradle-plugin-api/src/common/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinVersion.kt b/libraries/tools/kotlin-gradle-plugin-api/src/common/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinVersion.kt new file mode 100644 index 00000000000..7e1ba7ff3fd --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-api/src/common/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinVersion.kt @@ -0,0 +1,23 @@ +// DO NOT EDIT MANUALLY! +// Generated by org/jetbrains/kotlin/generators/arguments/GenerateGradleOptions.kt +package org.jetbrains.kotlin.gradle.dsl + +@Suppress("DEPRECATION") +enum class KotlinVersion (val version: String) { + @Deprecated("Unsupported", level = DeprecationLevel.ERROR) KOTLIN_1_0("1.0"), + @Deprecated("Unsupported", level = DeprecationLevel.ERROR) KOTLIN_1_1("1.1"), + @Deprecated("Unsupported", level = DeprecationLevel.ERROR) KOTLIN_1_2("1.2"), + @Deprecated("Will be removed soon") KOTLIN_1_3("1.3"), + @Deprecated("Will be removed soon") KOTLIN_1_4("1.4"), + KOTLIN_1_5("1.5"), + KOTLIN_1_6("1.6"), + KOTLIN_1_7("1.7"), + KOTLIN_1_8("1.8"), + KOTLIN_1_9("1.9"); + + companion object { + fun fromVersion(version: String): KotlinVersion = + KotlinVersion.values().firstOrNull { it.version == version } + ?: throw IllegalArgumentException("Unknown Kotlin version: $version") + } +}