[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
This commit is contained in:
Ivan Gavrilovic
2022-01-14 09:44:23 +00:00
committed by teamcity
parent bb4f996467
commit c93594331b
8 changed files with 237 additions and 74 deletions
@@ -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<K2JVMCompilerArguments>()
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<K2JSCompilerArguments>()
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<K2JSDceArguments>()
withPrinterToFile(file(srcDir, jsDceInterfaceFqName)) {
withPrinterToFile(file(apiSrcDir, jsDceInterfaceFqName)) {
generateInterface(
jsDceInterfaceFqName,
jsDceOptions,
@@ -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<String, String>
}
/**
* 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)
}
@@ -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) }
}
}
@@ -34,9 +34,7 @@ import kotlin.reflect.KClass
private const val KOTLIN_PROJECT_EXTENSION_NAME = "kotlin"
internal fun Project.createKotlinExtension(extensionClass: KClass<out KotlinTopLevelExtension>): 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<ExperimentalExtension>) {
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<KotlinSourceSet>
@Suppress("UNCHECKED_CAST")
get() = DslObject(this).extensions.getByName("sourceSets") as NamedDomainObjectContainer<KotlinSourceSet>
@@ -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"
}
}
@@ -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<String, String> {
override fun getJavacOptions(): Map<String, String> {
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<String, String>()
@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<String, String>()
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(), "")
}