From c93594331b4d4acca3510a835489575705521bb7 Mon Sep 17 00:00:00 2001 From: Ivan Gavrilovic Date: Fri, 14 Jan 2022 09:44:23 +0000 Subject: [PATCH] [Gradle] Move some of the DSL to the API module DSL exposed in the build scripts in effectively an API, so this change moves it to the kotlin-gradle-plugin-api subproject. ^KT-50869 In Progress --- .../arguments/GenerateGradleOptions.kt | 6 +- .../kotlin/gradle/dsl/KaptExtensionConfig.kt | 121 ++++++++++++++++++ .../kotlin/gradle/dsl/KotlinJsDceOptions.kt | 0 .../kotlin/gradle/dsl/KotlinJsOptions.kt | 0 .../kotlin/gradle/dsl/KotlinJvmOptions.kt | 0 .../dsl/kotlinTopLevelExtensionConfig.kt | 66 ++++++++++ .../gradle/dsl/KotlinProjectExtension.kt | 50 +++----- .../kotlin/gradle/plugin/KaptExtension.kt | 68 +++++----- 8 files changed, 237 insertions(+), 74 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KaptExtensionConfig.kt rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-api}/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinJsDceOptions.kt (100%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-api}/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinJsOptions.kt (100%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-api}/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinJvmOptions.kt (100%) create mode 100644 libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/kotlinTopLevelExtensionConfig.kt diff --git a/generators/tests/org/jetbrains/kotlin/generators/arguments/GenerateGradleOptions.kt b/generators/tests/org/jetbrains/kotlin/generators/arguments/GenerateGradleOptions.kt index 58088b148a9..df6f82eac0f 100644 --- a/generators/tests/org/jetbrains/kotlin/generators/arguments/GenerateGradleOptions.kt +++ b/generators/tests/org/jetbrains/kotlin/generators/arguments/GenerateGradleOptions.kt @@ -73,7 +73,7 @@ fun generateKotlinGradleOptions(withPrinterToFile: (targetFile: File, Printer.() // generate jvm interface val jvmInterfaceFqName = FqName("org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions") val jvmOptions = gradleOptions() - withPrinterToFile(file(srcDir, jvmInterfaceFqName)) { + withPrinterToFile(file(apiSrcDir, jvmInterfaceFqName)) { generateInterface( jvmInterfaceFqName, jvmOptions, @@ -99,7 +99,7 @@ fun generateKotlinGradleOptions(withPrinterToFile: (targetFile: File, Printer.() // generate js interface val jsInterfaceFqName = FqName("org.jetbrains.kotlin.gradle.dsl.KotlinJsOptions") val jsOptions = gradleOptions() - withPrinterToFile(file(srcDir, jsInterfaceFqName)) { + withPrinterToFile(file(apiSrcDir, jsInterfaceFqName)) { generateInterface( jsInterfaceFqName, jsOptions, @@ -124,7 +124,7 @@ fun generateKotlinGradleOptions(withPrinterToFile: (targetFile: File, Printer.() // generate JS DCE interface and implementation val jsDceInterfaceFqName = FqName("org.jetbrains.kotlin.gradle.dsl.KotlinJsDceOptions") val jsDceOptions = gradleOptions() - withPrinterToFile(file(srcDir, jsDceInterfaceFqName)) { + withPrinterToFile(file(apiSrcDir, jsDceInterfaceFqName)) { generateInterface( jsDceInterfaceFqName, jsDceOptions, diff --git a/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KaptExtensionConfig.kt b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KaptExtensionConfig.kt new file mode 100644 index 00000000000..9af85e6ea36 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KaptExtensionConfig.kt @@ -0,0 +1,121 @@ +/* + * Copyright 2010-2021 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.gradle.dsl + +/** + * DSL extension used to configure KAPT stub generation and KAPT annotation processing. + */ +interface KaptExtensionConfig { + + /** + * If `true`, compile classpath should be used to search for annotation processors. + */ + var includeCompileClasspath: Boolean? + + /** + * If `true`, skip body analysis if possible. + */ + var useLightAnalysis: Boolean + + /** + * If `true`, replace generated or error types with ones from the generated sources. + */ + var correctErrorTypes: Boolean + + /** + * If `true`, put initializers on fields when corresponding primary constructor parameters have a default value specified. + */ + var dumpDefaultParameterValues: Boolean + + /** + * If `true`, map diagnostic reported on kapt stubs to original locations in Kotlin sources. + */ + var mapDiagnosticLocations: Boolean + + /** + * If `true`, show errors on incompatibilities during stub generation. + */ + var strictMode: Boolean + + /** + * If `true`, strip @Metadata annotations from stubs. + */ + var stripMetadata: Boolean + + /** + * If `true`, show annotation processor timings. + */ + var showProcessorTimings: Boolean + + /** + * If `true`, detect memory leaks in annotation processors. + */ + var detectMemoryLeaks: String + + /** + * Opt-out switch for Kapt caching. Should be used when annotation processors used by this project are suspected of + * using anything aside from the task inputs in their logic and are not guaranteed to produce the same + * output on subsequent runs without input changes. + */ + var useBuildCache: Boolean + + /** + * If true keeps annotation processors added via `annotationProcessor(..)` configuration for javac java-files compilation + */ + var keepJavacAnnotationProcessors: Boolean + + /** + * Adds annotation processor with the specified [fqName] to the list of processors to run. + */ + fun annotationProcessor(fqName: String) + + /** + * Adds annotation processors with the specified [fqName] to the list of processors to run. + */ + fun annotationProcessors(vararg fqName: String) + + /** + * Configure [KaptArguments] used for annotation processing. + */ + fun arguments(action: KaptArguments.() -> Unit) + + /** + * Configure [KaptJavacOption] used for annotation processing. + */ + fun javacOptions(action: KaptJavacOption.() -> Unit) + + /** + * Gets all javac options used for KAPT. + */ + fun getJavacOptions(): Map +} + +/** + * Interface used to specify arguments that are used during KAPT processing. + */ +interface KaptArguments { + + /** + * Adds argument with the specified name and values. + */ + fun arg(name: Any, vararg values: Any) +} + +/** + * Interface used to specify javac options that are used during KAPT processing. + */ +interface KaptJavacOption { + + /** + * Adds an option with name and value. + */ + fun option(name: Any, value: Any) + + /** + * Adds an option with name only (no value associated). + */ + fun option(name: Any) +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinJsDceOptions.kt b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinJsDceOptions.kt similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinJsDceOptions.kt rename to libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinJsDceOptions.kt diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinJsOptions.kt b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinJsOptions.kt similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinJsOptions.kt rename to libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinJsOptions.kt diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinJvmOptions.kt b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinJvmOptions.kt similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinJvmOptions.kt rename to libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinJvmOptions.kt diff --git a/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/kotlinTopLevelExtensionConfig.kt b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/kotlinTopLevelExtensionConfig.kt new file mode 100644 index 00000000000..14b067ba40c --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/kotlinTopLevelExtensionConfig.kt @@ -0,0 +1,66 @@ +/* + * Copyright 2010-2021 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.gradle.dsl + +/** + * DSL extension that is used to configure Kotlin options for the entire project. + */ +interface KotlinTopLevelExtensionConfig { + val experimental: ExperimentalExtensionConfig + + /** + * Version of the core Kotlin libraries that are added to Kotlin compile classpath, unless there is already a dependency added to this + * project. By default, this version is the same as the version of the used Kotlin Gradle plugin. + */ + var coreLibrariesVersion: String + + /** + * Option that tells the compiler if and how to report issues on all public API declarations without explicit visibility or return type. + */ + var explicitApi: ExplicitApiMode? + + /** + * Sets [explicitApi] option to report issues as errors. + */ + fun explicitApi() + + /** + * Sets [explicitApi] option to report issues as warnings. + */ + fun explicitApiWarning() +} + +interface ExperimentalExtensionConfig { + var coroutines: Coroutines? +} + +/** + * Different modes that can be used to set the level of issue reporting for [KotlinTopLevelExtensionConfig.explicitApi] option. + */ +enum class ExplicitApiMode(private val cliOption: String) { + /** Report issues as errors. */ + Strict("strict"), + + /** Report issues as warnings. */ + Warning("warning"), + + /** Disable issues reporting. */ + Disabled("disable"); + + fun toCompilerArg() = "-Xexplicit-api=$cliOption" +} + +enum class Coroutines { + ENABLE, + WARN, + ERROR, + DEFAULT; + + companion object { + fun byCompilerArgument(argument: String): Coroutines? = + values().firstOrNull { it.name.equals(argument, ignoreCase = true) } + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinProjectExtension.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinProjectExtension.kt index dffea7c826d..a88029b9536 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinProjectExtension.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinProjectExtension.kt @@ -34,9 +34,7 @@ import kotlin.reflect.KClass private const val KOTLIN_PROJECT_EXTENSION_NAME = "kotlin" internal fun Project.createKotlinExtension(extensionClass: KClass): KotlinTopLevelExtension { - val kotlinExt = extensions.create(KOTLIN_PROJECT_EXTENSION_NAME, extensionClass.java, this) - DslObject(kotlinExt).extensions.create("experimental", ExperimentalExtension::class.java, this) - return topLevelExtension + return extensions.create(KOTLIN_PROJECT_EXTENSION_NAME, extensionClass.java, this) } internal val Project.topLevelExtension: KotlinTopLevelExtension @@ -60,11 +58,15 @@ internal val Project.multiplatformExtension: KotlinMultiplatformExtension internal val Project.pm20Extension: KotlinPm20ProjectExtension get() = extensions.getByName(KOTLIN_PROJECT_EXTENSION_NAME).castIsolatedKotlinPluginClassLoaderAware() -open class KotlinTopLevelExtension(internal val project: Project) { - val experimental: ExperimentalExtension - get() = DslObject(this).extensions.getByType(ExperimentalExtension::class.java) +abstract class KotlinTopLevelExtension(internal val project: Project) : KotlinTopLevelExtensionConfig { - lateinit var coreLibrariesVersion: String + override val experimental: ExperimentalExtension = project.objects.newInstance(ExperimentalExtension::class.java, project) + + fun experimental(action: Action) { + action.execute(this.experimental) + } + + override lateinit var coreLibrariesVersion: String private val toolchainSupport = ToolchainSupport.createToolchain(project) @@ -95,18 +97,18 @@ open class KotlinTopLevelExtension(internal val project: Project) { } } - var explicitApi: ExplicitApiMode? = null + override var explicitApi: ExplicitApiMode? = null - fun explicitApi() { + override fun explicitApi() { explicitApi = ExplicitApiMode.Strict } - fun explicitApiWarning() { + override fun explicitApiWarning() { explicitApi = ExplicitApiMode.Warning } } -open class KotlinProjectExtension(project: Project) : KotlinTopLevelExtension(project), KotlinSourceSetContainer { +open class KotlinProjectExtension @Inject constructor(project: Project) : KotlinTopLevelExtension(project), KotlinSourceSetContainer { override var sourceSets: NamedDomainObjectContainer @Suppress("UNCHECKED_CAST") get() = DslObject(this).extensions.getByName("sourceSets") as NamedDomainObjectContainer @@ -291,8 +293,8 @@ open class KotlinAndroidProjectExtension(project: Project) : KotlinSingleTargetE open class ExperimentalExtension @Inject constructor( private val project: Project -) { - var coroutines: Coroutines? = null +) : ExperimentalExtensionConfig { + override var coroutines: Coroutines? = null set(value) { SingleWarningPerBuild.show( project, @@ -305,18 +307,6 @@ open class ExperimentalExtension @Inject constructor( } } -enum class Coroutines { - ENABLE, - WARN, - ERROR, - DEFAULT; - - companion object { - fun byCompilerArgument(argument: String): Coroutines? = - Coroutines.values().firstOrNull { it.name.equals(argument, ignoreCase = true) } - } -} - enum class NativeCacheKind(val produce: String?, val outputKind: CompilerOutputKind?) { NONE(null, null), DYNAMIC("dynamic_cache", CompilerOutputKind.DYNAMIC_CACHE), @@ -326,12 +316,4 @@ enum class NativeCacheKind(val produce: String?, val outputKind: CompilerOutputK fun byCompilerArgument(argument: String): NativeCacheKind? = NativeCacheKind.values().firstOrNull { it.name.equals(argument, ignoreCase = true) } } -} - -enum class ExplicitApiMode(private val cliOption: String) { - Strict("strict"), - Warning("warning"), - Disabled("disable"); - - fun toCompilerArg() = "-Xexplicit-api=$cliOption" -} +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KaptExtension.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KaptExtension.kt index a659f49aeab..18cb52b28bb 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KaptExtension.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KaptExtension.kt @@ -18,84 +18,78 @@ package org.jetbrains.kotlin.gradle.plugin import groovy.lang.Closure import org.gradle.api.Project +import org.jetbrains.kotlin.gradle.dsl.KaptArguments +import org.jetbrains.kotlin.gradle.dsl.KaptExtensionConfig +import org.jetbrains.kotlin.gradle.dsl.KaptJavacOption import java.util.* -open class KaptExtension { +open class KaptExtension: KaptExtensionConfig { open var generateStubs: Boolean = false open var inheritedAnnotations: Boolean = true - open var useLightAnalysis: Boolean = true + override var useLightAnalysis: Boolean = true - open var correctErrorTypes: Boolean = false + override var correctErrorTypes: Boolean = false - open var dumpDefaultParameterValues: Boolean = false + override var dumpDefaultParameterValues: Boolean = false - open var mapDiagnosticLocations: Boolean = false + override var mapDiagnosticLocations: Boolean = false - open var strictMode: Boolean = false + override var strictMode: Boolean = false - open var stripMetadata: Boolean = false + override var stripMetadata: Boolean = false - open var showProcessorTimings: Boolean = false + override var showProcessorTimings: Boolean = false - open var detectMemoryLeaks: String = "default" + override var detectMemoryLeaks: String = "default" - open var includeCompileClasspath: Boolean? = null + override var includeCompileClasspath: Boolean? = null @Deprecated("Use `annotationProcessor()` and `annotationProcessors()` instead") open var processors: String = "" - /** - * If true keeps annotation processors added via `annotationProcessor(..)` configuration for javac java-files compilation - */ - open var keepJavacAnnotationProcessors: Boolean = false + override var keepJavacAnnotationProcessors: Boolean = false - /** Opt-out switch for Kapt caching. Should be used when annotation processors used by this project are suspected of - * using anything aside from the task inputs in their logic and are not guaranteed to produce the same - * output on subsequent runs without input changes. */ - var useBuildCache: Boolean = true + override var useBuildCache: Boolean = true private val apOptionsActions = - mutableListOf<(KaptAnnotationProcessorOptions) -> Unit>() + mutableListOf<(KaptArguments) -> Unit>() private val javacOptionsActions = - mutableListOf<(KaptJavacOptionsDelegate) -> Unit>() - - private var apOptionsClosure: Closure<*>? = null - private var javacOptionsClosure: Closure<*>? = null + mutableListOf<(KaptJavacOption) -> Unit>() @Suppress("DEPRECATION") - open fun annotationProcessor(fqName: String) { + override fun annotationProcessor(fqName: String) { val oldProcessors = this.processors this.processors = if (oldProcessors.isEmpty()) fqName else "$oldProcessors,$fqName" } - open fun annotationProcessors(vararg fqName: String) { + override fun annotationProcessors(vararg fqName: String) { fqName.forEach(this::annotationProcessor) } - open fun arguments(closure: Closure<*>) { + fun arguments(closure: Closure<*>) { apOptionsActions += { apOptions -> - apOptions.execute(closure) + apOptions.executeClosure(closure) } } - open fun arguments(action: KaptAnnotationProcessorOptions.() -> Unit) { + override fun arguments(action: KaptArguments.() -> Unit) { apOptionsActions += action } open fun javacOptions(closure: Closure<*>) { - this.javacOptionsActions += { javacOptions -> - javacOptions.execute(closure) + javacOptionsActions += { javacOptions -> + javacOptions.executeClosure(closure) } } - open fun javacOptions(action: KaptJavacOptionsDelegate.() -> Unit) { + override fun javacOptions(action: KaptJavacOption.() -> Unit) { javacOptionsActions += action } - fun getJavacOptions(): Map { + override fun getJavacOptions(): Map { val result = KaptJavacOptionsDelegate() javacOptionsActions.forEach { it(result) } return result.options @@ -123,25 +117,25 @@ open class KaptAnnotationProcessorOptions( @Suppress("unused") open val project: Project, @Suppress("unused") open val variant: Any?, @Suppress("unused") open val android: Any? -) { +): KaptArguments { internal val options = LinkedHashMap() @Suppress("unused") - open fun arg(name: Any, vararg values: Any) { + override fun arg(name: Any, vararg values: Any) { options.put(name.toString(), values.joinToString(" ")) } fun execute(closure: Closure<*>) = executeClosure(closure) } -open class KaptJavacOptionsDelegate { +open class KaptJavacOptionsDelegate: KaptJavacOption { internal val options = LinkedHashMap() - open fun option(name: Any, value: Any) { + override fun option(name: Any, value: Any) { options.put(name.toString(), value.toString()) } - open fun option(name: Any) { + override fun option(name: Any) { options.put(name.toString(), "") }