Expose statically-typed kotlinOptions and compileKotlinTask in DSL

To simplify configuring a `KotlinCompilation` with Gradle Kotlin DSL, it
is essential to expose statically-known types where possible.

This commit parametrizes `KotlinCompilation` with its Kotlin options
type (a subtype of `KotlinCommonOptions`) and adds `kotlinOptions` and
`compileKotlinTask` to `KotlinCompilation`.

(minor) Also reduce the visibility of `attachClassesDir` and
`setupPlugins` to internal, since this API is not for external use.
This commit is contained in:
Sergey Igushkin
2018-11-12 17:02:36 +03:00
parent 1e2436b1c1
commit 581b161611
27 changed files with 157 additions and 114 deletions
@@ -32,7 +32,7 @@ class ExampleSubplugin : KotlinGradleSubplugin<AbstractCompile> {
javaCompile: AbstractCompile?,
variantData: Any?,
androidProjectHandler: Any?,
kotlinCompilation: KotlinCompilation?
kotlinCompilation: KotlinCompilation<*>?
): List<SubpluginOption> {
println("ExampleSubplugin loaded")
return listOf(SubpluginOption("exampleKey", "exampleValue"))
@@ -55,7 +55,7 @@ class AllOpenKotlinGradleSubplugin : KotlinGradleSubplugin<AbstractCompile> {
javaCompile: AbstractCompile?,
variantData: Any?,
androidProjectHandler: Any?,
kotlinCompilation: KotlinCompilation?
kotlinCompilation: KotlinCompilation<*>?
): List<SubpluginOption> {
if (!AllOpenGradleSubplugin.isEnabled(project)) return emptyList()
@@ -9,9 +9,9 @@ import groovy.lang.Closure
import org.gradle.api.Action
import org.gradle.api.Named
import org.gradle.api.file.FileCollection
import org.gradle.api.tasks.SourceSetOutput
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
interface CInteropSettings: Named {
interface CInteropSettings : Named {
interface IncludeDirectories {
fun allHeaders(vararg includeDirs: Any)
@@ -22,7 +22,7 @@ interface CInteropSettings: Named {
}
// TODO: Provide an interface for native compilations.
val compilation: KotlinCompilation
val compilation: KotlinCompilation<KotlinCommonOptions>
val dependencyConfigurationName: String
var dependencyFiles: FileCollection
@@ -9,6 +9,9 @@ import org.gradle.api.Named
import org.gradle.api.attributes.HasAttributes
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.FileCollection
import org.gradle.util.ConfigureUtil
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
import org.jetbrains.kotlin.gradle.dsl.KotlinCompile
import java.io.File
interface KotlinCompilationOutput {
@@ -19,7 +22,7 @@ interface KotlinCompilationOutput {
val allOutputs: FileCollection
}
interface KotlinCompilation: Named, HasAttributes, HasKotlinDependencies {
interface KotlinCompilation<out T : KotlinCommonOptions> : Named, HasAttributes, HasKotlinDependencies {
val target: KotlinTarget
val compilationName: String
@@ -36,6 +39,12 @@ interface KotlinCompilation: Named, HasAttributes, HasKotlinDependencies {
val compileKotlinTaskName: String
val compileKotlinTask: KotlinCompile<T>
val kotlinOptions: T
fun kotlinOptions(configure: T.() -> Unit)
val compileAllTaskName: String
companion object {
@@ -51,7 +60,7 @@ interface KotlinCompilation: Named, HasAttributes, HasKotlinDependencies {
get() = super.relatedConfigurationNames + compileDependencyConfigurationName
}
interface KotlinCompilationToRunnableFiles : KotlinCompilation {
interface KotlinCompilationToRunnableFiles<T : KotlinCommonOptions> : KotlinCompilation<T> {
val runtimeDependencyConfigurationName: String
var runtimeDependencyFiles: FileCollection
@@ -60,6 +69,6 @@ interface KotlinCompilationToRunnableFiles : KotlinCompilation {
get() = super.relatedConfigurationNames + runtimeDependencyConfigurationName
}
interface KotlinCompilationWithResources : KotlinCompilation {
interface KotlinCompilationWithResources<T : KotlinCommonOptions> : KotlinCompilation<T> {
val processResourcesTaskName: String
}
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.gradle.plugin
import org.gradle.api.Project
import org.gradle.api.tasks.compile.AbstractCompile
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
import java.io.File
open class SubpluginOption(val key: String, val value: String)
@@ -56,7 +57,7 @@ interface KotlinGradleSubplugin<in KotlinCompile : AbstractCompile> {
javaCompile: AbstractCompile?,
variantData: Any?,
androidProjectHandler: Any?,
kotlinCompilation: KotlinCompilation?
kotlinCompilation: KotlinCompilation<KotlinCommonOptions>?
): List<SubpluginOption>
fun getSubpluginKotlinTasks(
@@ -14,19 +14,21 @@ import org.gradle.api.attributes.HasAttributes
import org.gradle.api.component.SoftwareComponent
import org.gradle.api.internal.component.UsageContext
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.util.ConfigureUtil
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
interface KotlinTargetComponent : SoftwareComponent {
val target: KotlinTarget
val publishable: Boolean
}
interface KotlinTarget: Named, HasAttributes {
interface KotlinTarget : Named, HasAttributes {
val targetName: String
val disambiguationClassifier: String? get() = targetName
val platformType: KotlinPlatformType
val compilations: NamedDomainObjectContainer<out KotlinCompilation>
val compilations: NamedDomainObjectContainer<out KotlinCompilation<KotlinCommonOptions>>
val project: Project
@@ -47,7 +47,8 @@ open class KotlinProjectExtension {
}
open class KotlinSingleJavaTargetExtension : KotlinProjectExtension() {
internal lateinit var target: KotlinWithJavaTarget
// TODO define subtypes with proper type arguments for each of the option types once the new model is available in old projects
internal lateinit var target: KotlinWithJavaTarget<*>
}
open class KotlinJvmProjectExtension : KotlinSingleJavaTargetExtension() {
@@ -105,7 +105,7 @@ class AndroidSubplugin : KotlinGradleSubplugin<KotlinCompile> {
javaCompile: AbstractCompile?,
variantData: Any?,
androidProjectHandler: Any?,
kotlinCompilation: KotlinCompilation?
kotlinCompilation: KotlinCompilation<*>?
): List<SubpluginOption> {
val androidExtension = project.extensions.getByName("android") as? BaseExtension ?: return emptyList()
val androidExtensionsExtension = project.extensions.getByType(AndroidExtensionsExtension::class.java)
@@ -165,7 +165,7 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
val javaCompile: AbstractCompile?,
val kaptVariantData: KaptVariantData<*>?,
val sourceSetName: String,
val kotlinCompilation: KotlinCompilation?,
val kotlinCompilation: KotlinCompilation<*>?,
val kaptExtension: KaptExtension,
val kaptClasspathConfigurations: List<Configuration>
) {
@@ -180,7 +180,7 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
javaCompile: AbstractCompile?,
variantData: Any?,
androidProjectHandler: Any?,
kotlinCompilation: KotlinCompilation?
kotlinCompilation: KotlinCompilation<*>?
): List<SubpluginOption> {
assert((variantData != null) xor (kotlinCompilation != null))
@@ -50,14 +50,14 @@ class KotlinJsDcePlugin : Plugin<Project> {
}
}
private fun processCompilation(project: Project, kotlinCompilation: KotlinCompilation) {
private fun processCompilation(project: Project, kotlinCompilation: KotlinCompilation<*>) {
val kotlinTaskName = kotlinCompilation.compileKotlinTaskName
val kotlinTask = project.tasks.findByName(kotlinTaskName) as? Kotlin2JsCompile ?: return
val dceTaskName = lowerCamelCaseName(
DCE_TASK_PREFIX,
kotlinCompilation.target.disambiguationClassifier,
kotlinCompilation.name.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME },
if (kotlinCompilation.target is KotlinWithJavaTarget) TASK_SUFFIX else MPP_TASK_SUFFIX
if (kotlinCompilation.target is KotlinWithJavaTarget<*>) TASK_SUFFIX else MPP_TASK_SUFFIX
)
val dceTask = project.tasks.create(dceTaskName, KotlinJsDce::class.java).also {
it.dependsOn(kotlinTask)
@@ -21,6 +21,7 @@ import org.gradle.api.tasks.compile.AbstractCompile
import org.gradle.api.tasks.compile.JavaCompile
import org.gradle.jvm.tasks.Jar
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl
import org.jetbrains.kotlin.gradle.dsl.KotlinSingleJavaTargetExtension
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
@@ -50,7 +51,7 @@ internal abstract class KotlinSourceSetProcessor<T : AbstractKotlinCompile<*>>(
val project: Project,
val tasksProvider: KotlinTasksProvider,
val taskDescription: String,
val kotlinCompilation: KotlinCompilation
val kotlinCompilation: KotlinCompilation<*>
) {
protected abstract fun doTargetSpecificProcessing()
protected val logger = Logging.getLogger(this.javaClass)!!
@@ -63,7 +64,7 @@ internal abstract class KotlinSourceSetProcessor<T : AbstractKotlinCompile<*>>(
protected val kotlinTask: T = createKotlinCompileTask()
protected val javaSourceSet: SourceSet? = (kotlinCompilation as? KotlinWithJavaCompilation)?.javaSourceSet
protected val javaSourceSet: SourceSet? = (kotlinCompilation as? KotlinWithJavaCompilation<*>)?.javaSourceSet
protected open val defaultKotlinDestinationDir: File
get() {
@@ -95,7 +96,7 @@ internal abstract class KotlinSourceSetProcessor<T : AbstractKotlinCompile<*>>(
addKotlinDirectoriesToJavaSourceSet()
doTargetSpecificProcessing()
if (kotlinCompilation is KotlinWithJavaCompilation) {
if (kotlinCompilation is KotlinWithJavaCompilation<*>) {
createAdditionalClassesTaskForIdeRunner()
}
}
@@ -147,7 +148,7 @@ internal abstract class KotlinSourceSetProcessor<T : AbstractKotlinCompile<*>>(
internal class Kotlin2JvmSourceSetProcessor(
project: Project,
tasksProvider: KotlinTasksProvider,
kotlinCompilation: KotlinCompilation,
kotlinCompilation: KotlinCompilation<*>,
private val kotlinPluginVersion: String
) : KotlinSourceSetProcessor<KotlinCompile>(
project, tasksProvider, "Compiles the $kotlinCompilation.", kotlinCompilation
@@ -242,7 +243,7 @@ internal fun KotlinCompilationOutput.tryAddClassesDir(
internal class Kotlin2JsSourceSetProcessor(
project: Project,
tasksProvider: KotlinTasksProvider,
kotlinCompilation: KotlinCompilation,
kotlinCompilation: KotlinCompilation<*>,
private val kotlinPluginVersion: String
) : KotlinSourceSetProcessor<Kotlin2JsCompile>(
project, tasksProvider, taskDescription = "Compiles the Kotlin sources in $kotlinCompilation to JavaScript.",
@@ -256,7 +257,7 @@ internal class Kotlin2JsSourceSetProcessor(
createCleanSourceMapTask()
if (kotlinCompilation is KotlinWithJavaCompilation) {
if (kotlinCompilation is KotlinWithJavaCompilation<*>) {
kotlinCompilation.javaSourceSet.clearJavaSrcDirs()
}
@@ -280,7 +281,7 @@ internal class Kotlin2JsSourceSetProcessor(
kotlinTask.destinationDir = outputDir
if (!isSeparateClassesDirSupported && kotlinCompilation is KotlinWithJavaCompilation) {
if (!isSeparateClassesDirSupported && kotlinCompilation is KotlinWithJavaCompilation<*>) {
kotlinCompilation.javaSourceSet.output.setClassesDirCompatible(kotlinTask.destinationDir)
}
@@ -303,7 +304,7 @@ internal class Kotlin2JsSourceSetProcessor(
internal class KotlinCommonSourceSetProcessor(
project: Project,
compilation: KotlinCompilation,
compilation: KotlinCompilation<*>,
tasksProvider: KotlinTasksProvider,
private val kotlinPluginVersion: String
) : KotlinSourceSetProcessor<KotlinCompileCommon>(
@@ -340,7 +341,7 @@ internal abstract class AbstractKotlinPlugin(
internal abstract fun buildSourceSetProcessor(
project: Project,
compilation: KotlinCompilation,
compilation: KotlinCompilation<*>,
kotlinPluginVersion: String
): KotlinSourceSetProcessor<*>
@@ -366,8 +367,8 @@ internal abstract class AbstractKotlinPlugin(
}
fun configureTarget(
target: KotlinWithJavaTarget,
buildSourceSetProcessor: (KotlinCompilation) -> KotlinSourceSetProcessor<*>
target: KotlinWithJavaTarget<*>,
buildSourceSetProcessor: (KotlinCompilation<*>) -> KotlinSourceSetProcessor<*>
) {
setUpJavaSourceSets(target)
configureSourceSetDefaults(target, buildSourceSetProcessor)
@@ -393,7 +394,7 @@ internal abstract class AbstractKotlinPlugin(
}
private fun setUpJavaSourceSets(
kotlinTarget: KotlinWithJavaTarget
kotlinTarget: KotlinWithJavaTarget<*>
) {
val project = kotlinTarget.project
val javaSourceSets = project.convention.getPlugin(JavaPluginConvention::class.java).sourceSets
@@ -404,7 +405,7 @@ internal abstract class AbstractKotlinPlugin(
}
// Workaround for indirect mutual recursion between the two `all { ... }` handlers:
val compilationsUnderConstruction = mutableMapOf<String, KotlinWithJavaCompilation>()
val compilationsUnderConstruction = mutableMapOf<String, KotlinWithJavaCompilation<*>>()
javaSourceSets.all { javaSourceSet ->
val kotlinCompilation =
@@ -428,7 +429,7 @@ internal abstract class AbstractKotlinPlugin(
}
private fun configureAttributes(
kotlinTarget: KotlinWithJavaTarget
kotlinTarget: KotlinWithJavaTarget<*>
) {
val project = kotlinTarget.project
@@ -460,7 +461,7 @@ internal abstract class AbstractKotlinPlugin(
private fun configureSourceSetDefaults(
kotlinTarget: KotlinTarget,
buildSourceSetProcessor: (KotlinCompilation) -> KotlinSourceSetProcessor<*>
buildSourceSetProcessor: (KotlinCompilation<*>) -> KotlinSourceSetProcessor<*>
) {
kotlinTarget.compilations.all { compilation ->
buildSourceSetProcessor(compilation).run()
@@ -498,11 +499,11 @@ internal open class KotlinPlugin(
private const val targetName = "" // use empty suffix for the task names
}
override fun buildSourceSetProcessor(project: Project, compilation: KotlinCompilation, kotlinPluginVersion: String) =
override fun buildSourceSetProcessor(project: Project, compilation: KotlinCompilation<*>, kotlinPluginVersion: String) =
Kotlin2JvmSourceSetProcessor(project, tasksProvider, compilation, kotlinPluginVersion)
override fun apply(project: Project) {
val target = KotlinWithJavaTarget(project, KotlinPlatformType.jvm, targetName).apply {
val target = KotlinWithJavaTarget<KotlinCommonOptions>(project, KotlinPlatformType.jvm, targetName).apply {
disambiguationClassifier = null // don't add anything to the task names
}
(project.kotlinExtension as KotlinSingleJavaTargetExtension).target = target
@@ -523,13 +524,13 @@ internal open class KotlinCommonPlugin(
override fun buildSourceSetProcessor(
project: Project,
compilation: KotlinCompilation,
compilation: KotlinCompilation<*>,
kotlinPluginVersion: String
): KotlinSourceSetProcessor<*> =
KotlinCommonSourceSetProcessor(project, compilation, tasksProvider, kotlinPluginVersion)
override fun apply(project: Project) {
val target = KotlinWithJavaTarget(project, KotlinPlatformType.common, targetName)
val target = KotlinWithJavaTarget<KotlinCommonOptions>(project, KotlinPlatformType.common, targetName)
(project.kotlinExtension as KotlinSingleJavaTargetExtension).target = target
super.apply(project)
@@ -547,7 +548,7 @@ internal open class Kotlin2JsPlugin(
override fun buildSourceSetProcessor(
project: Project,
compilation: KotlinCompilation,
compilation: KotlinCompilation<*>,
kotlinPluginVersion: String
): KotlinSourceSetProcessor<*> =
Kotlin2JsSourceSetProcessor(
@@ -555,7 +556,7 @@ internal open class Kotlin2JsPlugin(
)
override fun apply(project: Project) {
val target = KotlinWithJavaTarget(project, KotlinPlatformType.js, targetName)
val target = KotlinWithJavaTarget<KotlinCommonOptions>(project, KotlinPlatformType.js, targetName)
(project.kotlinExtension as KotlinSingleJavaTargetExtension).target = target
super.apply(project)
@@ -759,7 +760,7 @@ abstract class AbstractAndroidProjectHandler<V>(private val kotlinConfigurationT
private fun applySubplugins(
project: Project,
compilation: KotlinCompilation,
compilation: KotlinCompilation<*>,
variantData: V,
subpluginEnvironment: SubpluginEnvironment
) {
@@ -774,7 +775,7 @@ abstract class AbstractAndroidProjectHandler<V>(private val kotlinConfigurationT
.forEach { configureSources(it, variantData, null) }
}
private fun configureSources(compileTask: AbstractCompile, variantData: V, compilation: KotlinCompilation?) {
private fun configureSources(compileTask: AbstractCompile, variantData: V, compilation: KotlinCompilation<*>?) {
val logger = compileTask.project.logger
for (provider in getSourceProviders(variantData)) {
@@ -61,7 +61,7 @@ abstract class AbstractKotlinTargetConfigurator<KotlinTargetType : KotlinTarget>
abstract fun configureArchivesAndComponent(target: KotlinTargetType)
private fun Project.registerOutputsForStaleOutputCleanup(kotlinCompilation: KotlinCompilation) {
private fun Project.registerOutputsForStaleOutputCleanup(kotlinCompilation: KotlinCompilation<*>) {
val cleanTask = tasks.getByName(LifecycleBasePlugin.CLEAN_TASK_NAME) as Delete
cleanTask.delete(kotlinCompilation.output.allOutputs)
}
@@ -133,7 +133,7 @@ abstract class AbstractKotlinTargetConfigurator<KotlinTargetType : KotlinTarget>
}
protected fun configureResourceProcessing(
compilation: KotlinCompilationWithResources,
compilation: KotlinCompilationWithResources<*>,
resourceSet: FileCollection
) {
val project = compilation.target.project
@@ -144,7 +144,7 @@ abstract class AbstractKotlinTargetConfigurator<KotlinTargetType : KotlinTarget>
resourcesTask.from(resourceSet)
}
protected fun createLifecycleTask(compilation: KotlinCompilation) {
protected fun createLifecycleTask(compilation: KotlinCompilation<*>) {
val project = compilation.target.project
compilation.output.classesDirs.from(project.files().builtBy(compilation.compileAllTaskName))
@@ -189,7 +189,7 @@ abstract class AbstractKotlinTargetConfigurator<KotlinTargetType : KotlinTarget>
usesPlatformOf(target)
}
if (mainCompilation is KotlinCompilationToRunnableFiles) {
if (mainCompilation is KotlinCompilationToRunnableFiles<*>) {
val runtimeElementsConfiguration = configurations.maybeCreate(target.runtimeElementsConfigurationName).apply {
description = "Elements of runtime for main."
isVisible = false
@@ -248,7 +248,7 @@ abstract class AbstractKotlinTargetConfigurator<KotlinTargetType : KotlinTarget>
const val testTaskNameSuffix = "test"
fun defineConfigurationsForCompilation(
compilation: KotlinCompilation,
compilation: KotlinCompilation<*>,
target: KotlinTarget,
configurations: ConfigurationContainer
) {
@@ -322,13 +322,13 @@ abstract class AbstractKotlinTargetConfigurator<KotlinTargetType : KotlinTarget>
}
}
internal val KotlinCompilation.deprecatedCompileConfigurationName: String
internal val KotlinCompilation<*>.deprecatedCompileConfigurationName: String
get() = disambiguateName("compile")
internal val KotlinCompilationToRunnableFiles.deprecatedRuntimeConfigurationName: String
internal val KotlinCompilationToRunnableFiles<*>.deprecatedRuntimeConfigurationName: String
get() = disambiguateName("runtime")
open class KotlinTargetConfigurator<KotlinCompilationType : KotlinCompilation>(
open class KotlinTargetConfigurator<KotlinCompilationType : KotlinCompilation<*>>(
createDefaultSourceSets: Boolean,
createTestCompilation: Boolean
) : AbstractKotlinTargetConfigurator<KotlinOnlyTarget<KotlinCompilationType>>(
@@ -359,7 +359,7 @@ open class KotlinTargetConfigurator<KotlinCompilationType : KotlinCompilation>(
addJar(apiElementsConfiguration, jarArtifact)
if (mainCompilation is KotlinCompilationToRunnableFiles) {
if (mainCompilation is KotlinCompilationToRunnableFiles<*>) {
val runtimeConfiguration = project.configurations.getByName(mainCompilation.deprecatedRuntimeConfigurationName)
val runtimeElementsConfiguration = project.configurations.getByName(target.runtimeElementsConfigurationName)
addJar(runtimeConfiguration, jarArtifact)
@@ -43,7 +43,7 @@ internal fun Configuration.setupAsLocalTargetSpecificConfigurationIfSupported(ta
// don't setup in old MPP common modules, as their output configurations with KotlinPlatformType attribute would
// fail to resolve as transitive dependencies of the platform modules, just as we don't mark their
// `api/RuntimeElements` with the KotlinPlatformType
(target !is KotlinWithJavaTarget || target.platformType != KotlinPlatformType.common)
(target !is KotlinWithJavaTarget<*> || target.platformType != KotlinPlatformType.common)
) {
usesPlatformOf(target)
attributes.attribute(ProjectLocalConfigurations.ATTRIBUTE, target.project.path)
@@ -46,7 +46,7 @@ class SubpluginEnvironment(
javaTask: AbstractCompile? = null,
variantData: Any? = null,
androidProjectHandler: AbstractAndroidProjectHandler<out Any?>? = null,
kotlinCompilation: KotlinCompilation? = null
kotlinCompilation: KotlinCompilation<*>? = null
): List<KotlinGradleSubplugin<AbstractKotlinCompile<C>>> = addSubpluginOptions(
project,
kotlinTask,
@@ -64,7 +64,7 @@ class SubpluginEnvironment(
javaTask: AbstractCompile? = null,
variantData: Any? = null,
androidProjectHandler: AbstractAndroidProjectHandler<out Any?>? = null,
kotlinCompilation: KotlinCompilation? = null
kotlinCompilation: KotlinCompilation<*>? = null
): List<KotlinGradleSubplugin<AbstractKotlinCompile<C>>> {
val appliedSubplugins = subplugins.filter { it.isApplicable(project, kotlinTask) }
for (subplugin in appliedSubplugins) {
@@ -8,9 +8,10 @@ package org.jetbrains.kotlin.gradle.plugin.mpp
import org.gradle.api.NamedDomainObjectFactory
import org.gradle.api.Project
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
interface KotlinCompilationFactory<T : KotlinCompilation> : NamedDomainObjectFactory<T> {
interface KotlinCompilationFactory<T : KotlinCompilation<*>> : NamedDomainObjectFactory<T> {
val itemClass: Class<T>
}
@@ -34,15 +35,16 @@ class KotlinJvmCompilationFactory(
KotlinJvmCompilation(target, name)
}
class KotlinWithJavaCompilationFactory(
class KotlinWithJavaCompilationFactory<KotlinOptionsType : KotlinCommonOptions>(
val project: Project,
val target: KotlinWithJavaTarget
) : KotlinCompilationFactory<KotlinWithJavaCompilation> {
val target: KotlinWithJavaTarget<KotlinOptionsType>
) : KotlinCompilationFactory<KotlinWithJavaCompilation<KotlinOptionsType>> {
override val itemClass: Class<KotlinWithJavaCompilation>
get() = KotlinWithJavaCompilation::class.java
override val itemClass: Class<KotlinWithJavaCompilation<KotlinOptionsType>>
@Suppress("UNCHECKED_CAST")
get() = KotlinWithJavaCompilation::class.java as Class<KotlinWithJavaCompilation<KotlinOptionsType>>
override fun create(name: String): KotlinWithJavaCompilation {
override fun create(name: String): KotlinWithJavaCompilation<KotlinOptionsType> {
val result = KotlinWithJavaCompilation(target, name)
return result
}
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.gradle.plugin.mpp
import groovy.lang.Closure
import org.gradle.api.NamedDomainObjectCollection
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.attributes.Attribute
@@ -24,6 +23,7 @@ import org.gradle.internal.reflect.Instantiator
import org.gradle.jvm.tasks.Jar
import org.gradle.util.ConfigureUtil
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.dsl.configureOrCreate
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultLanguageSettingsBuilder
@@ -42,17 +42,13 @@ class KotlinMultiplatformPlugin(
private val featurePreviews: FeaturePreviews // TODO get rid of this internal API usage once we don't need it
) : Plugin<Project> {
private class TargetFromPresetExtension(val targetsContainer: NamedDomainObjectCollection<KotlinTarget>) {
private class TargetFromPresetExtension(val targetsContainer: KotlinTargetsContainerWithPresets) {
fun <T : KotlinTarget> fromPreset(preset: KotlinTargetPreset<T>, name: String, configureClosure: Closure<*>): T =
fromPreset(preset, name, { ConfigureUtil.configure(configureClosure, this) })
fromPreset(preset, name) { ConfigureUtil.configure(configureClosure, this) }
@JvmOverloads
fun <T : KotlinTarget> fromPreset(preset: KotlinTargetPreset<T>, name: String, configureAction: T.() -> Unit = { }): T {
val target = preset.createTarget(name)
targetsContainer.add(target)
target.run(configureAction)
return target
}
fun <T : KotlinTarget> fromPreset(preset: KotlinTargetPreset<T>, name: String, configureAction: T.() -> Unit = { }): T =
targetsContainer.configureOrCreate(name, preset, configureAction)
}
override fun apply(project: Project) {
@@ -60,9 +56,10 @@ class KotlinMultiplatformPlugin(
SingleWarningPerBuild.show(project, "Kotlin Multiplatform Projects are an experimental feature.")
val targetsContainer = project.container(KotlinTarget::class.java)
val targetsFromPreset = TargetFromPresetExtension(targetsContainer)
val kotlinMultiplatformExtension = project.extensions.getByType(KotlinMultiplatformExtension::class.java)
val targetsFromPreset = TargetFromPresetExtension(kotlinMultiplatformExtension)
project.extensions.getByType(KotlinMultiplatformExtension::class.java).apply {
kotlinMultiplatformExtension.apply {
DslObject(targetsContainer).addConvention("fromPreset", targetsFromPreset)
targets = targetsContainer
@@ -302,8 +299,8 @@ class KotlinMultiplatformPlugin(
internal val KotlinTarget.defaultArtifactId get() = "${project.name}-${name.toLowerCase()}"
internal fun compilationsBySourceSet(project: Project): Map<KotlinSourceSet, Set<KotlinCompilation>> =
HashMap<KotlinSourceSet, MutableSet<KotlinCompilation>>().also { result ->
internal fun compilationsBySourceSet(project: Project): Map<KotlinSourceSet, Set<KotlinCompilation<*>>> =
HashMap<KotlinSourceSet, MutableSet<KotlinCompilation<*>>>().also { result ->
for (target in project.multiplatformExtension!!.targets) {
for (compilation in target.compilations) {
for (sourceSet in compilation.allKotlinSourceSets) {
@@ -32,7 +32,7 @@ class DefaultKotlinCompilationOutput(
}
class KotlinWithJavaCompilationOutput(
internal val compilation: KotlinWithJavaCompilation
internal val compilation: KotlinWithJavaCompilation<*>
) : KotlinCompilationOutput, Callable<FileCollection> {
private val javaSourceSetOutput
@@ -14,12 +14,13 @@ import org.gradle.api.file.FileCollection
import org.gradle.api.file.SourceDirectorySet
import org.gradle.api.tasks.SourceSet
import org.gradle.util.ConfigureUtil
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
import org.jetbrains.kotlin.gradle.dsl.*
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.sources.defaultSourceSetLanguageSettingsChecker
import org.jetbrains.kotlin.gradle.plugin.sources.getSourceSetHierarchy
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
import org.jetbrains.kotlin.gradle.tasks.KotlinCompileCommon
import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile
import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
@@ -27,14 +28,14 @@ import java.io.File
import java.util.*
import java.util.concurrent.Callable
internal fun KotlinCompilation.composeName(prefix: String? = null, suffix: String? = null): String {
internal fun KotlinCompilation<*>.composeName(prefix: String? = null, suffix: String? = null): String {
val compilationNamePart = compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }
val targetNamePart = target.disambiguationClassifier
return lowerCamelCaseName(prefix, targetNamePart, compilationNamePart, suffix)
}
internal val KotlinCompilation.defaultSourceSetName: String
internal val KotlinCompilation<*>.defaultSourceSetName: String
get() = lowerCamelCaseName(target.disambiguationClassifier, compilationName)
internal class DefaultKotlinDependencyHandler(
@@ -54,10 +55,20 @@ internal class DefaultKotlinDependencyHandler(
}
}
abstract class AbstractKotlinCompilation(
abstract class AbstractKotlinCompilation<T : KotlinCommonOptions>(
target: KotlinTarget,
override val compilationName: String
) : KotlinCompilation, HasKotlinDependencies {
) : KotlinCompilation<T>, HasKotlinDependencies {
override val kotlinOptions: T
get() = compileKotlinTask.kotlinOptions
override fun kotlinOptions(configure: T.() -> Unit) =
configure(kotlinOptions)
@Suppress("UNCHECKED_CAST")
override val compileKotlinTask: KotlinCompile<T>
get() = (target.project.tasks.getByName(compileKotlinTaskName) as KotlinCompile<T>)
// Don't declare this property in the constructor to avoid NPE
// when an overriding property of a subclass is accessed instead.
@@ -101,7 +112,7 @@ abstract class AbstractKotlinCompilation(
addExtendsFromRelation(implementationConfigurationName, sourceSet.implementationConfigurationName, forced = false)
addExtendsFromRelation(compileOnlyConfigurationName, sourceSet.compileOnlyConfigurationName, forced = false)
if (this is KotlinCompilationToRunnableFiles) {
if (this is KotlinCompilationToRunnableFiles<*>) {
addExtendsFromRelation(runtimeOnlyConfigurationName, sourceSet.runtimeOnlyConfigurationName, forced = false)
}
@@ -163,13 +174,13 @@ abstract class AbstractKotlinCompilation(
override fun toString(): String = "compilation '$compilationName' ($target)"
}
val KotlinCompilation.allKotlinSourceSets: Set<KotlinSourceSet>
val KotlinCompilation<*>.allKotlinSourceSets: Set<KotlinSourceSet>
get() = kotlinSourceSets.flatMapTo(mutableSetOf()) { it.getSourceSetHierarchy() }
abstract class AbstractKotlinCompilationToRunnableFiles(
abstract class AbstractKotlinCompilationToRunnableFiles<T : KotlinCommonOptions>(
target: KotlinTarget,
name: String
) : AbstractKotlinCompilation(target, name), KotlinCompilationToRunnableFiles {
) : AbstractKotlinCompilation<T>(target, name), KotlinCompilationToRunnableFiles<T> {
override val runtimeDependencyConfigurationName: String
get() = lowerCamelCaseName(
target.disambiguationClassifier,
@@ -180,7 +191,7 @@ abstract class AbstractKotlinCompilationToRunnableFiles(
override lateinit var runtimeDependencyFiles: FileCollection
}
internal fun KotlinCompilation.disambiguateName(simpleName: String): String {
internal fun KotlinCompilation<*>.disambiguateName(simpleName: String): String {
return lowerCamelCaseName(
target.disambiguationClassifier,
compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME },
@@ -191,15 +202,18 @@ internal fun KotlinCompilation.disambiguateName(simpleName: String): String {
open class KotlinJvmCompilation(
target: KotlinTarget,
name: String
) : AbstractKotlinCompilationToRunnableFiles(target, name), KotlinCompilationWithResources {
) : AbstractKotlinCompilationToRunnableFiles<KotlinJvmOptions>(target, name), KotlinCompilationWithResources<KotlinJvmOptions> {
override val processResourcesTaskName: String
get() = disambiguateName("processResources")
override val compileKotlinTask: org.jetbrains.kotlin.gradle.tasks.KotlinCompile
get() = super.compileKotlinTask as org.jetbrains.kotlin.gradle.tasks.KotlinCompile
}
class KotlinWithJavaCompilation(
target: KotlinWithJavaTarget,
class KotlinWithJavaCompilation<KotlinOptionsType : KotlinCommonOptions>(
target: KotlinWithJavaTarget<KotlinOptionsType>,
name: String
) : AbstractKotlinCompilationToRunnableFiles(target, name), KotlinCompilationWithResources {
) : AbstractKotlinCompilationToRunnableFiles<KotlinOptionsType>(target, name), KotlinCompilationWithResources<KotlinOptionsType> {
lateinit var javaSourceSet: SourceSet
override val output: KotlinCompilationOutput by lazy { KotlinWithJavaCompilationOutput(this) }
@@ -252,22 +266,37 @@ class KotlinWithJavaCompilation(
class KotlinJvmAndroidCompilation(
target: KotlinAndroidTarget,
name: String
) : AbstractKotlinCompilationToRunnableFiles(target, name)
) : AbstractKotlinCompilationToRunnableFiles<KotlinJvmOptions>(target, name) {
override val compileKotlinTask: org.jetbrains.kotlin.gradle.tasks.KotlinCompile
get() = super.compileKotlinTask as org.jetbrains.kotlin.gradle.tasks.KotlinCompile
}
class KotlinJsCompilation(
target: KotlinTarget,
name: String
) : AbstractKotlinCompilationToRunnableFiles(target, name)
) : AbstractKotlinCompilationToRunnableFiles<KotlinJsOptions>(target, name) {
override val compileKotlinTask: Kotlin2JsCompile
get() = super.compileKotlinTask as Kotlin2JsCompile
}
class KotlinCommonCompilation(
target: KotlinTarget,
name: String
) : AbstractKotlinCompilation(target, name)
) : AbstractKotlinCompilation<KotlinMultiplatformCommonOptions>(target, name) {
override val compileKotlinTask: KotlinCompileCommon
get() = super.compileKotlinTask as KotlinCompileCommon
}
class KotlinNativeCompilation(
override val target: KotlinNativeTarget,
name: String
) : AbstractKotlinCompilation(target, name), KotlinCompilationWithResources {
) : AbstractKotlinCompilation<KotlinCommonOptions>(target, name), KotlinCompilationWithResources<KotlinCommonOptions> {
override val kotlinOptions: KotlinCommonOptions
get() = compileKotlinTask.kotlinOptions
override val compileKotlinTask: KotlinNativeCompile
get() = super.compileKotlinTask as KotlinNativeCompile
private val project: Project
get() = target.project
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.compilerRunner.KotlinNativeProjectProperty
import org.jetbrains.kotlin.compilerRunner.hasProperty
import org.jetbrains.kotlin.compilerRunner.konanHome
import org.jetbrains.kotlin.gradle.dsl.KotlinCompile
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.sources.applyLanguageSettingsToKotlinTask
@@ -28,7 +29,7 @@ import org.jetbrains.kotlin.konan.target.KonanTarget
import java.io.File
import java.util.*
abstract class KotlinOnlyTargetPreset<T : KotlinCompilation>(
abstract class KotlinOnlyTargetPreset<T : KotlinCompilation<*>>(
protected val project: Project,
private val instantiator: Instantiator,
private val fileResolver: FileResolver,
@@ -197,14 +198,14 @@ class KotlinAndroidTargetPreset(
class KotlinJvmWithJavaTargetPreset(
private val project: Project,
private val kotlinPluginVersion: String
) : KotlinTargetPreset<KotlinWithJavaTarget> {
) : KotlinTargetPreset<KotlinWithJavaTarget<KotlinJvmOptions>> {
override fun getName(): String = PRESET_NAME
override fun createTarget(name: String): KotlinWithJavaTarget {
override fun createTarget(name: String): KotlinWithJavaTarget<KotlinJvmOptions> {
project.plugins.apply(JavaPlugin::class.java)
val target = KotlinWithJavaTarget(project, KotlinPlatformType.jvm, name).apply {
val target = KotlinWithJavaTarget<KotlinJvmOptions>(project, KotlinPlatformType.jvm, name).apply {
disambiguationClassifier = name
preset = this@KotlinJvmWithJavaTargetPreset
}
@@ -19,6 +19,7 @@ import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.util.ConfigureUtil
import org.gradle.util.WrapUtil
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
import org.jetbrains.kotlin.gradle.plugin.*
@@ -138,7 +139,7 @@ open class KotlinAndroidTarget(
}
}
open class KotlinWithJavaTarget(
open class KotlinWithJavaTarget<KotlinOptionsType : KotlinCommonOptions>(
project: Project,
override val platformType: KotlinPlatformType,
override val targetName: String
@@ -158,14 +159,15 @@ open class KotlinWithJavaTarget(
override val artifactsTaskName: String
get() = JavaPlugin.JAR_TASK_NAME
override val compilations: NamedDomainObjectContainer<KotlinWithJavaCompilation> =
override val compilations: NamedDomainObjectContainer<KotlinWithJavaCompilation<KotlinOptionsType>> =
@Suppress("UNCHECKED_CAST")
project.container(
KotlinWithJavaCompilation::class.java,
KotlinWithJavaCompilation::class.java as Class<KotlinWithJavaCompilation<KotlinOptionsType>>,
KotlinWithJavaCompilationFactory(project, this)
)
}
open class KotlinOnlyTarget<T : KotlinCompilation>(
open class KotlinOnlyTarget<T : KotlinCompilation<*>>(
project: Project,
override val platformType: KotlinPlatformType
) : AbstractKotlinTarget(project) {
@@ -123,7 +123,7 @@ class ScriptingKotlinGradleSubplugin : KotlinGradleSubplugin<AbstractCompile> {
javaCompile: AbstractCompile?,
variantData: Any?,
androidProjectHandler: Any?,
kotlinCompilation: KotlinCompilation?
kotlinCompilation: KotlinCompilation<*>?
): List<SubpluginOption> {
if (!ScriptingGradleSubplugin.isEnabled(project)) return emptyList()
@@ -29,7 +29,7 @@ import org.jetbrains.kotlin.incremental.ChangedFiles
import java.io.File
@CacheableTask
internal open class KotlinCompileCommon : AbstractKotlinCompile<K2MetadataCompilerArguments>(), KotlinCommonCompile {
open class KotlinCompileCommon : AbstractKotlinCompile<K2MetadataCompilerArguments>(), KotlinCommonCompile {
private val kotlinOptionsImpl = KotlinMultiplatformCommonOptionsImpl()
override val kotlinOptions: KotlinMultiplatformCommonOptions
@@ -230,7 +230,7 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractKo
/** Registers the directory provided by the [provider] as attached, meaning that the directory should
* be consumed as a friend classes directory by other tasks that have this task as a [friendTask]. */
fun attachClassesDir(provider: () -> File?) {
internal fun attachClassesDir(provider: () -> File?) {
attachedClassesDirs += lazy(provider)
}
@@ -305,7 +305,7 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractKo
setupPlugins(args)
}
fun setupPlugins(compilerArgs: T) {
internal fun setupPlugins(compilerArgs: T) {
compilerArgs.pluginClasspaths = pluginClasspath.toSortedPathsArray()
compilerArgs.pluginOptions = pluginOptions.arguments.toTypedArray()
}
@@ -26,7 +26,7 @@ internal open class KotlinTasksProvider(val targetName: String) {
open fun createKotlinJVMTask(
project: Project,
name: String,
compilation: KotlinCompilation
compilation: KotlinCompilation<*>
): KotlinCompile {
val properties = PropertiesProvider(project)
val taskClass = taskOrWorkersTask<KotlinCompile, KotlinCompileWithWorkers>(properties)
@@ -35,7 +35,7 @@ internal open class KotlinTasksProvider(val targetName: String) {
}
}
fun createKotlinJSTask(project: Project, name: String, compilation: KotlinCompilation): Kotlin2JsCompile {
fun createKotlinJSTask(project: Project, name: String, compilation: KotlinCompilation<*>): Kotlin2JsCompile {
val properties = PropertiesProvider(project)
val taskClass = taskOrWorkersTask<Kotlin2JsCompile, Kotlin2JsCompileWithWorkers>(properties)
return project.tasks.create(name, taskClass).apply {
@@ -43,8 +43,7 @@ internal open class KotlinTasksProvider(val targetName: String) {
}
}
fun createKotlinCommonTask(project: Project, name: String, compilation: KotlinCompilation): KotlinCompileCommon {
fun createKotlinCommonTask(project: Project, name: String, compilation: KotlinCompilation<*>): KotlinCompileCommon {
val properties = PropertiesProvider(project)
val taskClass = taskOrWorkersTask<KotlinCompileCommon, KotlinCompileCommonWithWorkers>(properties)
return project.tasks.create(name, taskClass).apply {
@@ -56,7 +55,7 @@ internal open class KotlinTasksProvider(val targetName: String) {
kotlinTask: AbstractKotlinCompile<*>,
project: Project,
propertiesProvider: PropertiesProvider,
compilation: KotlinCompilation
compilation: KotlinCompilation<*>
) {
kotlinTask.sourceSetName = compilation.name
kotlinTask.friendTaskName = taskToFriendTaskMapper[kotlinTask]
@@ -86,7 +85,7 @@ internal class AndroidTasksProvider(targetName: String) : KotlinTasksProvider(ta
kotlinTask: AbstractKotlinCompile<*>,
project: Project,
propertiesProvider: PropertiesProvider,
compilation: KotlinCompilation
compilation: KotlinCompilation<*>
) {
super.configure(kotlinTask, project, propertiesProvider, compilation)
kotlinTask.useModuleDetection = true
@@ -56,7 +56,7 @@ class NoArgKotlinGradleSubplugin : KotlinGradleSubplugin<AbstractCompile> {
javaCompile: AbstractCompile?,
variantData: Any?,
androidProjectHandler: Any?,
kotlinCompilation: KotlinCompilation?
kotlinCompilation: KotlinCompilation<*>?
): List<SubpluginOption> {
if (!NoArgGradleSubplugin.isEnabled(project)) return emptyList()
@@ -51,7 +51,7 @@ class SamWithReceiverKotlinGradleSubplugin : KotlinGradleSubplugin<AbstractCompi
javaCompile: AbstractCompile?,
variantData: Any?,
androidProjectHandler: Any?,
kotlinCompilation: KotlinCompilation?
kotlinCompilation: KotlinCompilation<*>?
): List<SubpluginOption> {
if (!SamWithReceiverGradleSubplugin.isEnabled(project)) return emptyList()
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin
import org.jetbrains.kotlin.gradle.plugin.SubpluginArtifact
import org.jetbrains.kotlin.gradle.plugin.SubpluginOption
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
class SerializationGradleSubplugin : Plugin<Project> {
companion object {
@@ -51,7 +50,7 @@ class SerializationKotlinGradleSubplugin : KotlinGradleSubplugin<AbstractCompile
javaCompile: AbstractCompile?,
variantData: Any?,
androidProjectHandler: Any?,
kotlinCompilation: KotlinCompilation?
kotlinCompilation: KotlinCompilation<*>?
): List<SubpluginOption> {
return emptyList()
}