Gradle plugin prototype that uses the project model 2.0
This commit is contained in:
@@ -226,6 +226,11 @@ pluginBundle {
|
|||||||
id = "org.jetbrains.kotlin.native.cocoapods",
|
id = "org.jetbrains.kotlin.native.cocoapods",
|
||||||
display = "Kotlin Native plugin for CocoaPods integration"
|
display = "Kotlin Native plugin for CocoaPods integration"
|
||||||
)
|
)
|
||||||
|
create(
|
||||||
|
name = "kotlinMultiplatformPluginPm20",
|
||||||
|
id = "org.jetbrains.kotlin.multiplatform.pm20",
|
||||||
|
display = "Kotlin Multiplatform plugin with PM2.0"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
publishPluginMarkers()
|
publishPluginMarkers()
|
||||||
|
|||||||
+5
-5
@@ -19,15 +19,15 @@ import org.jetbrains.kotlin.daemon.common.CompilerId
|
|||||||
import org.jetbrains.kotlin.gradle.dsl.kotlinExtensionOrNull
|
import org.jetbrains.kotlin.gradle.dsl.kotlinExtensionOrNull
|
||||||
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull
|
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull
|
||||||
import org.jetbrains.kotlin.gradle.logging.kotlinDebug
|
import org.jetbrains.kotlin.gradle.logging.kotlinDebug
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
|
||||||
import org.jetbrains.kotlin.gradle.plugin.internal.state.TaskLoggers
|
import org.jetbrains.kotlin.gradle.plugin.internal.state.TaskLoggers
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaTarget
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaTarget
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.isMain
|
import org.jetbrains.kotlin.gradle.plugin.mpp.isMain
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.ownModuleName
|
|
||||||
import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService
|
import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService
|
||||||
import org.jetbrains.kotlin.gradle.tasks.GradleCompileTaskProvider
|
import org.jetbrains.kotlin.gradle.tasks.GradleCompileTaskProvider
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompileTaskData
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompileTaskData
|
||||||
import org.jetbrains.kotlin.gradle.tasks.locateTask
|
|
||||||
import org.jetbrains.kotlin.gradle.utils.archivePathCompatible
|
import org.jetbrains.kotlin.gradle.utils.archivePathCompatible
|
||||||
import org.jetbrains.kotlin.gradle.utils.newTmpFile
|
import org.jetbrains.kotlin.gradle.utils.newTmpFile
|
||||||
import org.jetbrains.kotlin.gradle.utils.relativeOrCanonical
|
import org.jetbrains.kotlin.gradle.utils.relativeOrCanonical
|
||||||
@@ -216,7 +216,7 @@ internal open class GradleCompilerRunner(protected val taskProvider: GradleCompi
|
|||||||
|
|
||||||
KotlinCompileTaskData.getTaskDataContainer(project).forEach { taskData ->
|
KotlinCompileTaskData.getTaskDataContainer(project).forEach { taskData ->
|
||||||
val compilation = taskData.compilation
|
val compilation = taskData.compilation
|
||||||
val target = taskData.compilation.target
|
val target = taskData.compilation.owner
|
||||||
val module = IncrementalModuleEntry(
|
val module = IncrementalModuleEntry(
|
||||||
project.path,
|
project.path,
|
||||||
compilation.ownModuleName,
|
compilation.ownModuleName,
|
||||||
@@ -229,12 +229,12 @@ internal open class GradleCompilerRunner(protected val taskProvider: GradleCompi
|
|||||||
nameToModules.getOrPut(module.name) { HashSet() }.add(module)
|
nameToModules.getOrPut(module.name) { HashSet() }.add(module)
|
||||||
|
|
||||||
if (compilation.platformType == KotlinPlatformType.js) {
|
if (compilation.platformType == KotlinPlatformType.js) {
|
||||||
jarForSourceSet(project, compilation.name)?.let {
|
jarForSourceSet(project, compilation.compilationPurpose)?.let {
|
||||||
jarToModule[it] = module
|
jarToModule[it] = module
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compilation.isMain()) {
|
if (compilation is KotlinCompilation<*> && target is KotlinTarget && compilation.isMain()) { // FIXME support PM20
|
||||||
if (isMultiplatformProject) {
|
if (isMultiplatformProject) {
|
||||||
try {
|
try {
|
||||||
//It could cause task reconfiguration. TODO: fix it some day if need
|
//It could cause task reconfiguration. TODO: fix it some day if need
|
||||||
|
|||||||
+13
-3
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.gradle.plugin.*
|
|||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsSingleTargetPreset
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsSingleTargetPreset
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaTarget
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaTarget
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinPm20ProjectExtension
|
||||||
import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService
|
import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.calculateJsCompilerType
|
import org.jetbrains.kotlin.gradle.targets.js.calculateJsCompilerType
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsTargetDsl
|
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsTargetDsl
|
||||||
@@ -25,12 +26,15 @@ import kotlin.reflect.KClass
|
|||||||
|
|
||||||
private const val KOTLIN_PROJECT_EXTENSION_NAME = "kotlin"
|
private const val KOTLIN_PROJECT_EXTENSION_NAME = "kotlin"
|
||||||
|
|
||||||
internal fun Project.createKotlinExtension(extensionClass: KClass<out KotlinProjectExtension>): KotlinProjectExtension {
|
internal fun Project.createKotlinExtension(extensionClass: KClass<out KotlinTopLevelExtension>): KotlinTopLevelExtension {
|
||||||
val kotlinExt = extensions.create(KOTLIN_PROJECT_EXTENSION_NAME, extensionClass.java, this)
|
val kotlinExt = extensions.create(KOTLIN_PROJECT_EXTENSION_NAME, extensionClass.java, this)
|
||||||
DslObject(kotlinExt).extensions.create("experimental", ExperimentalExtension::class.java)
|
DslObject(kotlinExt).extensions.create("experimental", ExperimentalExtension::class.java)
|
||||||
return kotlinExtension
|
return topLevelExtension
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal val Project.topLevelExtension: KotlinTopLevelExtension
|
||||||
|
get() = extensions.getByName(KOTLIN_PROJECT_EXTENSION_NAME) as KotlinTopLevelExtension
|
||||||
|
|
||||||
internal val Project.kotlinExtensionOrNull: KotlinProjectExtension?
|
internal val Project.kotlinExtensionOrNull: KotlinProjectExtension?
|
||||||
get() = extensions.findByName(KOTLIN_PROJECT_EXTENSION_NAME) as? KotlinProjectExtension
|
get() = extensions.findByName(KOTLIN_PROJECT_EXTENSION_NAME) as? KotlinProjectExtension
|
||||||
|
|
||||||
@@ -43,7 +47,11 @@ internal val Project.multiplatformExtensionOrNull: KotlinMultiplatformExtension?
|
|||||||
internal val Project.multiplatformExtension: KotlinMultiplatformExtension
|
internal val Project.multiplatformExtension: KotlinMultiplatformExtension
|
||||||
get() = extensions.getByName(KOTLIN_PROJECT_EXTENSION_NAME) as KotlinMultiplatformExtension
|
get() = extensions.getByName(KOTLIN_PROJECT_EXTENSION_NAME) as KotlinMultiplatformExtension
|
||||||
|
|
||||||
open class KotlinProjectExtension(internal val project: Project) : KotlinSourceSetContainer {
|
internal val Project.pm20Extension: KotlinPm20ProjectExtension
|
||||||
|
get() = extensions.getByName(KOTLIN_PROJECT_EXTENSION_NAME) as KotlinPm20ProjectExtension
|
||||||
|
|
||||||
|
|
||||||
|
open class KotlinTopLevelExtension (internal val project: Project) {
|
||||||
val experimental: ExperimentalExtension
|
val experimental: ExperimentalExtension
|
||||||
get() = DslObject(this).extensions.getByType(ExperimentalExtension::class.java)
|
get() = DslObject(this).extensions.getByType(ExperimentalExtension::class.java)
|
||||||
|
|
||||||
@@ -58,7 +66,9 @@ open class KotlinProjectExtension(internal val project: Project) : KotlinSourceS
|
|||||||
fun explicitApiWarning() {
|
fun explicitApiWarning() {
|
||||||
explicitApi = ExplicitApiMode.Warning
|
explicitApi = ExplicitApiMode.Warning
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open class KotlinProjectExtension(project: Project) : KotlinTopLevelExtension(project), KotlinSourceSetContainer {
|
||||||
override var sourceSets: NamedDomainObjectContainer<KotlinSourceSet>
|
override var sourceSets: NamedDomainObjectContainer<KotlinSourceSet>
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
get() = DslObject(this).extensions.getByName("sourceSets") as NamedDomainObjectContainer<KotlinSourceSet>
|
get() = DslObject(this).extensions.getByName("sourceSets") as NamedDomainObjectContainer<KotlinSourceSet>
|
||||||
|
|||||||
+57
-16
@@ -20,14 +20,15 @@ import org.gradle.api.tasks.testing.Test
|
|||||||
import org.gradle.api.tasks.testing.junit.JUnitOptions
|
import org.gradle.api.tasks.testing.junit.JUnitOptions
|
||||||
import org.gradle.api.tasks.testing.junitplatform.JUnitPlatformOptions
|
import org.gradle.api.tasks.testing.junitplatform.JUnitPlatformOptions
|
||||||
import org.gradle.api.tasks.testing.testng.TestNGOptions
|
import org.gradle.api.tasks.testing.testng.TestNGOptions
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinAndroidProjectExtension
|
import org.jetbrains.kotlin.gradle.dsl.*
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
|
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
|
||||||
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
||||||
import org.jetbrains.kotlin.gradle.execution.KotlinAggregateExecutionSource
|
import org.jetbrains.kotlin.gradle.execution.KotlinAggregateExecutionSource
|
||||||
import org.jetbrains.kotlin.gradle.plugin.*
|
import org.jetbrains.kotlin.gradle.plugin.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
|
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinGradleFragment
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinGradleModule
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinPm20ProjectExtension
|
||||||
import org.jetbrains.kotlin.gradle.plugin.sources.KotlinDependencyScope
|
import org.jetbrains.kotlin.gradle.plugin.sources.KotlinDependencyScope
|
||||||
import org.jetbrains.kotlin.gradle.plugin.sources.withAllDependsOnSourceSets
|
import org.jetbrains.kotlin.gradle.plugin.sources.withAllDependsOnSourceSets
|
||||||
import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllDependsOnSourceSets
|
import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllDependsOnSourceSets
|
||||||
@@ -41,7 +42,9 @@ import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
|||||||
|
|
||||||
internal fun customizeKotlinDependencies(project: Project) {
|
internal fun customizeKotlinDependencies(project: Project) {
|
||||||
configureStdlibDefaultDependency(project)
|
configureStdlibDefaultDependency(project)
|
||||||
configureKotlinTestDependency(project)
|
if (project.topLevelExtension is KotlinProjectExtension) { // TODO: extend this logic to PM20
|
||||||
|
configureKotlinTestDependency(project)
|
||||||
|
}
|
||||||
configureDefaultVersionsResolutionStrategy(project)
|
configureDefaultVersionsResolutionStrategy(project)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,7 +52,7 @@ private fun configureDefaultVersionsResolutionStrategy(project: Project) {
|
|||||||
project.configurations.all { configuration ->
|
project.configurations.all { configuration ->
|
||||||
// Use the API introduced in Gradle 4.4 to modify the dependencies directly before they are resolved:
|
// Use the API introduced in Gradle 4.4 to modify the dependencies directly before they are resolved:
|
||||||
configuration.withDependencies { dependencySet ->
|
configuration.withDependencies { dependencySet ->
|
||||||
val coreLibrariesVersion = project.kotlinExtension.coreLibrariesVersion
|
val coreLibrariesVersion = project.topLevelExtension.coreLibrariesVersion
|
||||||
dependencySet.filterIsInstance<ExternalDependency>()
|
dependencySet.filterIsInstance<ExternalDependency>()
|
||||||
.filter { it.group == KOTLIN_MODULE_GROUP && it.version.isNullOrEmpty() }
|
.filter { it.group == KOTLIN_MODULE_GROUP && it.version.isNullOrEmpty() }
|
||||||
.forEach { it.version { constraint -> constraint.require(coreLibrariesVersion) } }
|
.forEach { it.version { constraint -> constraint.require(coreLibrariesVersion) } }
|
||||||
@@ -64,20 +67,58 @@ internal fun configureStdlibDefaultDependency(project: Project) = with(project)
|
|||||||
|
|
||||||
val scopesToHandleConfigurations = listOf(KotlinDependencyScope.API_SCOPE, KotlinDependencyScope.IMPLEMENTATION_SCOPE)
|
val scopesToHandleConfigurations = listOf(KotlinDependencyScope.API_SCOPE, KotlinDependencyScope.IMPLEMENTATION_SCOPE)
|
||||||
|
|
||||||
project.kotlinExtension.sourceSets.all { kotlinSourceSet ->
|
when (val topLevelExtension = project.topLevelExtension) {
|
||||||
scopesToHandleConfigurations.forEach { scope ->
|
is KotlinPm20ProjectExtension -> {
|
||||||
val scopeConfiguration = project.sourceSetDependencyConfigurationByScope(kotlinSourceSet, scope)
|
addStdlibToPm20Project(topLevelExtension)
|
||||||
|
}
|
||||||
|
is KotlinProjectExtension -> {
|
||||||
|
topLevelExtension.sourceSets.all { kotlinSourceSet ->
|
||||||
|
scopesToHandleConfigurations.forEach { scope ->
|
||||||
|
val scopeConfiguration = project.sourceSetDependencyConfigurationByScope(kotlinSourceSet, scope)
|
||||||
|
|
||||||
project.tryWithDependenciesIfUnresolved(scopeConfiguration) { dependencies ->
|
project.tryWithDependenciesIfUnresolved(scopeConfiguration) { dependencies ->
|
||||||
val scopeToAddStdlibDependency =
|
val scopeToAddStdlibDependency =
|
||||||
if (isRelatedToAndroidTestSourceSet(project, kotlinSourceSet)) // AGP deprecates API configurations in test source sets
|
if (isRelatedToAndroidTestSourceSet(
|
||||||
KotlinDependencyScope.IMPLEMENTATION_SCOPE
|
project,
|
||||||
else KotlinDependencyScope.API_SCOPE
|
kotlinSourceSet
|
||||||
|
)
|
||||||
|
) // AGP deprecates API configurations in test source sets
|
||||||
|
KotlinDependencyScope.IMPLEMENTATION_SCOPE
|
||||||
|
else KotlinDependencyScope.API_SCOPE
|
||||||
|
|
||||||
if (scope != scopeToAddStdlibDependency)
|
if (scope != scopeToAddStdlibDependency)
|
||||||
return@tryWithDependenciesIfUnresolved
|
return@tryWithDependenciesIfUnresolved
|
||||||
|
|
||||||
chooseAndAddStdlibDependency(project, kotlinSourceSet, dependencies)
|
chooseAndAddStdlibDependency(project, kotlinSourceSet, dependencies)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addStdlibToPm20Project(
|
||||||
|
topLevelExtension: KotlinPm20ProjectExtension
|
||||||
|
) {
|
||||||
|
val project = topLevelExtension.project
|
||||||
|
topLevelExtension.modules.matching { it.name == KotlinGradleModule.MAIN_MODULE_NAME }.configureEach { main ->
|
||||||
|
main.fragments.matching { it.name == KotlinGradleFragment.COMMON_FRAGMENT_NAME }.configureEach { common ->
|
||||||
|
common.dependencies {
|
||||||
|
api(project.kotlinDependency("kotlin-stdlib-common", project.topLevelExtension.coreLibrariesVersion))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
main.variants.configureEach { variant ->
|
||||||
|
val dependency = when (variant.platformType) {
|
||||||
|
KotlinPlatformType.common -> error("variants are not expected to be common")
|
||||||
|
KotlinPlatformType.jvm -> "kotlin-stdlib" // TODO get JDK from JVM variants
|
||||||
|
KotlinPlatformType.js -> "kotlin-stdlib-js"
|
||||||
|
KotlinPlatformType.androidJvm -> null // TODO: expect support on the AGP side?
|
||||||
|
KotlinPlatformType.native -> null
|
||||||
|
}
|
||||||
|
if (dependency != null) {
|
||||||
|
variant.dependencies {
|
||||||
|
api(project.kotlinDependency(dependency, project.topLevelExtension.coreLibrariesVersion))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.gradle.internal.kapt.incremental.StructureTransformA
|
|||||||
import org.jetbrains.kotlin.gradle.internal.kapt.incremental.StructureTransformLegacyAction
|
import org.jetbrains.kotlin.gradle.internal.kapt.incremental.StructureTransformLegacyAction
|
||||||
import org.jetbrains.kotlin.gradle.model.builder.KaptModelBuilder
|
import org.jetbrains.kotlin.gradle.model.builder.KaptModelBuilder
|
||||||
import org.jetbrains.kotlin.gradle.plugin.*
|
import org.jetbrains.kotlin.gradle.plugin.*
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinCompilation
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmAndroidCompilation
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmAndroidCompilation
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompileTaskData
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompileTaskData
|
||||||
@@ -237,7 +238,7 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
|
|||||||
val javaCompile: TaskProvider<out AbstractCompile>?,
|
val javaCompile: TaskProvider<out AbstractCompile>?,
|
||||||
val variantData: Any?,
|
val variantData: Any?,
|
||||||
val sourceSetName: String,
|
val sourceSetName: String,
|
||||||
val kotlinCompilation: KotlinCompilation<*>,
|
val kotlinCompilation: AbstractKotlinCompilation<*>,
|
||||||
val kaptExtension: KaptExtension,
|
val kaptExtension: KaptExtension,
|
||||||
val kaptClasspathConfigurations: List<Configuration>
|
val kaptClasspathConfigurations: List<Configuration>
|
||||||
) {
|
) {
|
||||||
@@ -288,7 +289,7 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
|
|||||||
|
|
||||||
val context = Kapt3SubpluginContext(
|
val context = Kapt3SubpluginContext(
|
||||||
project, javaCompileOrNull,
|
project, javaCompileOrNull,
|
||||||
androidVariantData, sourceSetName, kotlinCompilation, kaptExtension, nonEmptyKaptConfigurations
|
androidVariantData, sourceSetName, kotlinCompilation as AbstractKotlinCompilation<*>/*TODO?*/, kaptExtension, nonEmptyKaptConfigurations
|
||||||
)
|
)
|
||||||
|
|
||||||
val kaptGenerateStubsTaskProvider: TaskProvider<KaptGenerateStubsTask> = context.createKaptGenerateStubsTask()
|
val kaptGenerateStubsTaskProvider: TaskProvider<KaptGenerateStubsTask> = context.createKaptGenerateStubsTask()
|
||||||
|
|||||||
+2
-4
@@ -18,9 +18,7 @@ import org.jetbrains.kotlin.gradle.model.impl.CompilerArgumentsImpl
|
|||||||
import org.jetbrains.kotlin.gradle.model.impl.ExperimentalFeaturesImpl
|
import org.jetbrains.kotlin.gradle.model.impl.ExperimentalFeaturesImpl
|
||||||
import org.jetbrains.kotlin.gradle.model.impl.KotlinProjectImpl
|
import org.jetbrains.kotlin.gradle.model.impl.KotlinProjectImpl
|
||||||
import org.jetbrains.kotlin.gradle.model.impl.SourceSetImpl
|
import org.jetbrains.kotlin.gradle.model.impl.SourceSetImpl
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KOTLIN_DSL_NAME
|
import org.jetbrains.kotlin.gradle.plugin.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KOTLIN_JS_DSL_NAME
|
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
|
||||||
import org.jetbrains.kotlin.gradle.plugin.getConvention
|
import org.jetbrains.kotlin.gradle.plugin.getConvention
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.associateWithTransitiveClosure
|
import org.jetbrains.kotlin.gradle.plugin.mpp.associateWithTransitiveClosure
|
||||||
@@ -129,7 +127,7 @@ class KotlinModelBuilder(private val kotlinPluginVersion: String, private val an
|
|||||||
|
|
||||||
private fun AbstractKotlinCompile<*>.findFriendSourceSets(): Collection<String> {
|
private fun AbstractKotlinCompile<*>.findFriendSourceSets(): Collection<String> {
|
||||||
val friendSourceSets = ArrayList<String>()
|
val friendSourceSets = ArrayList<String>()
|
||||||
taskData.compilation.associateWithTransitiveClosure.forEach { associateCompilation ->
|
(taskData.compilation as? KotlinCompilation<*>)?.associateWithTransitiveClosure?.forEach { associateCompilation ->
|
||||||
friendSourceSets.add(associateCompilation.name)
|
friendSourceSets.add(associateCompilation.name)
|
||||||
}
|
}
|
||||||
return friendSourceSets
|
return friendSourceSets
|
||||||
|
|||||||
+42
-42
@@ -15,7 +15,6 @@ import org.gradle.api.artifacts.maven.MavenResolver
|
|||||||
import org.gradle.api.attributes.Usage
|
import org.gradle.api.attributes.Usage
|
||||||
import org.gradle.api.file.ConfigurableFileTree
|
import org.gradle.api.file.ConfigurableFileTree
|
||||||
import org.gradle.api.file.FileCollection
|
import org.gradle.api.file.FileCollection
|
||||||
import org.gradle.api.file.SourceDirectorySet
|
|
||||||
import org.gradle.api.logging.Logging
|
import org.gradle.api.logging.Logging
|
||||||
import org.gradle.api.plugins.InvalidPluginException
|
import org.gradle.api.plugins.InvalidPluginException
|
||||||
import org.gradle.api.plugins.JavaPlugin
|
import org.gradle.api.plugins.JavaPlugin
|
||||||
@@ -36,6 +35,7 @@ import org.jetbrains.kotlin.gradle.internal.customizeKotlinDependencies
|
|||||||
import org.jetbrains.kotlin.gradle.logging.kotlinDebug
|
import org.jetbrains.kotlin.gradle.logging.kotlinDebug
|
||||||
import org.jetbrains.kotlin.gradle.model.builder.KotlinModelBuilder
|
import org.jetbrains.kotlin.gradle.model.builder.KotlinModelBuilder
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData
|
||||||
import org.jetbrains.kotlin.gradle.scripting.internal.ScriptingGradleSubplugin
|
import org.jetbrains.kotlin.gradle.scripting.internal.ScriptingGradleSubplugin
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryMode
|
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryMode
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.ir.*
|
import org.jetbrains.kotlin.gradle.targets.js.ir.*
|
||||||
@@ -60,46 +60,48 @@ val KOTLIN_JS_DSL_NAME = "kotlin2js"
|
|||||||
val KOTLIN_OPTIONS_DSL_NAME = "kotlinOptions"
|
val KOTLIN_OPTIONS_DSL_NAME = "kotlinOptions"
|
||||||
|
|
||||||
abstract class KotlinCompilationProcessor<out T : SourceTask>(
|
abstract class KotlinCompilationProcessor<out T : SourceTask>(
|
||||||
open val kotlinCompilation: KotlinCompilation<*>
|
open val kotlinCompilation: KotlinCompilationData<*>
|
||||||
) {
|
) {
|
||||||
abstract val kotlinTask: TaskProvider<out T>
|
abstract val kotlinTask: TaskProvider<out T>
|
||||||
abstract fun run()
|
abstract fun run()
|
||||||
|
|
||||||
protected val project: Project
|
protected val project: Project
|
||||||
get() = kotlinCompilation.target.project
|
get() = kotlinCompilation.project
|
||||||
|
|
||||||
protected val defaultKotlinDestinationDir: File
|
protected val defaultKotlinDestinationDir: File
|
||||||
get() {
|
get() {
|
||||||
val kotlinExt = project.kotlinExtension
|
val kotlinExt = project.topLevelExtension
|
||||||
val targetSubDirectory =
|
val targetSubDirectory =
|
||||||
if (kotlinExt is KotlinSingleJavaTargetExtension)
|
if (kotlinExt is KotlinSingleJavaTargetExtension)
|
||||||
"" // In single-target projects, don't add the target name part to this path
|
"" // In single-target projects, don't add the target name part to this path
|
||||||
else
|
else
|
||||||
kotlinCompilation.target.disambiguationClassifier?.let { "$it/" }.orEmpty()
|
kotlinCompilation.compilationClassifier?.let { "$it/" }.orEmpty()
|
||||||
return File(project.buildDir, "classes/kotlin/$targetSubDirectory${kotlinCompilation.compilationName}")
|
return File(project.buildDir, "classes/kotlin/$targetSubDirectory${kotlinCompilation.compilationPurpose}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal abstract class KotlinSourceSetProcessor<T : AbstractKotlinCompile<*>>(
|
internal abstract class KotlinSourceSetProcessor<T : AbstractKotlinCompile<*>>(
|
||||||
val tasksProvider: KotlinTasksProvider,
|
val tasksProvider: KotlinTasksProvider,
|
||||||
val taskDescription: String,
|
val taskDescription: String,
|
||||||
kotlinCompilation: AbstractKotlinCompilation<*>
|
kotlinCompilation: KotlinCompilationData<*>
|
||||||
) : KotlinCompilationProcessor<T>(kotlinCompilation) {
|
) : KotlinCompilationProcessor<T>(kotlinCompilation) {
|
||||||
protected abstract fun doTargetSpecificProcessing()
|
protected abstract fun doTargetSpecificProcessing()
|
||||||
protected val logger = Logging.getLogger(this.javaClass)!!
|
protected val logger = Logging.getLogger(this.javaClass)!!
|
||||||
|
|
||||||
protected val sourceSetName: String = kotlinCompilation.compilationName
|
protected val sourceSetName: String = kotlinCompilation.compilationPurpose
|
||||||
|
|
||||||
override val kotlinTask: TaskProvider<out T> = prepareKotlinCompileTask()
|
override val kotlinTask: TaskProvider<out T> = prepareKotlinCompileTask()
|
||||||
|
|
||||||
protected val javaSourceSet: SourceSet?
|
protected val javaSourceSet: SourceSet?
|
||||||
get() =
|
get() {
|
||||||
(kotlinCompilation as? KotlinWithJavaCompilation<*>)?.javaSourceSet
|
val compilation = kotlinCompilation
|
||||||
?: kotlinCompilation.target.let {
|
return (compilation as? KotlinWithJavaCompilation<*>)?.javaSourceSet
|
||||||
if (it is KotlinJvmTarget && it.withJavaEnabled)
|
?: kotlinCompilation.owner.let {
|
||||||
project.convention.getPlugin(JavaPluginConvention::class.java).sourceSets.maybeCreate(kotlinCompilation.name)
|
if (it is KotlinJvmTarget && it.withJavaEnabled && compilation is KotlinJvmCompilation)
|
||||||
|
project.convention.getPlugin(JavaPluginConvention::class.java).sourceSets.maybeCreate(compilation.name)
|
||||||
else null
|
else null
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun prepareKotlinCompileTask(): TaskProvider<out T> =
|
private fun prepareKotlinCompileTask(): TaskProvider<out T> =
|
||||||
registerKotlinCompileTask(register = ::doRegisterTask).also { task ->
|
registerKotlinCompileTask(register = ::doRegisterTask).also { task ->
|
||||||
@@ -136,31 +138,23 @@ internal abstract class KotlinSourceSetProcessor<T : AbstractKotlinCompile<*>>(
|
|||||||
|
|
||||||
// Try to avoid duplicate Java sources in allSource; run lazily to allow changing the directory set:
|
// Try to avoid duplicate Java sources in allSource; run lazily to allow changing the directory set:
|
||||||
val kotlinSrcDirsToAdd = Callable {
|
val kotlinSrcDirsToAdd = Callable {
|
||||||
kotlinCompilation.kotlinSourceSets.map { filterOutJavaSrcDirsIfPossible(it.kotlin) }
|
kotlinCompilation.kotlinSourceDirectoriesByFragmentName.values.map { filterOutJavaSrcDirsIfPossible(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
java.allJava.srcDirs(kotlinSrcDirsToAdd)
|
java.allJava.srcDirs(kotlinSrcDirsToAdd)
|
||||||
java.allSource.srcDirs(kotlinSrcDirsToAdd)
|
java.allSource.srcDirs(kotlinSrcDirsToAdd)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun filterOutJavaSrcDirsIfPossible(sourceDirectorySet: SourceDirectorySet): FileCollection {
|
private fun filterOutJavaSrcDirsIfPossible(sourceDirectories: FileCollection): FileCollection {
|
||||||
val java = javaSourceSet ?: return sourceDirectorySet
|
val java = javaSourceSet ?: return sourceDirectories
|
||||||
|
|
||||||
// If the API used below is not available, fall back to not filtering the Java sources.
|
|
||||||
if (SourceDirectorySet::class.java.methods.none { it.name == "getSourceDirectories" }) {
|
|
||||||
return sourceDirectorySet
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getSourceDirectories(sourceDirectorySet: SourceDirectorySet): FileCollection {
|
|
||||||
val method = SourceDirectorySet::class.java.getMethod("getSourceDirectories")
|
|
||||||
return method(sourceDirectorySet) as FileCollection
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build a lazily-resolved file collection that filters out Java sources from sources of this sourceDirectorySet
|
// Build a lazily-resolved file collection that filters out Java sources from sources of this sourceDirectorySet
|
||||||
return getSourceDirectories(sourceDirectorySet).minus(getSourceDirectories(java.java))
|
return sourceDirectories.minus(java.java.sourceDirectories)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createAdditionalClassesTaskForIdeRunner() {
|
private fun createAdditionalClassesTaskForIdeRunner() {
|
||||||
|
val kotlinCompilation = kotlinCompilation as? KotlinCompilation<*> ?: return
|
||||||
|
|
||||||
open class IDEClassesTask : DefaultTask()
|
open class IDEClassesTask : DefaultTask()
|
||||||
// Workaround: as per KT-26641, when there's a Kotlin compilation with a Java source set, we create another task
|
// Workaround: as per KT-26641, when there's a Kotlin compilation with a Java source set, we create another task
|
||||||
// that has a name composed as '<IDE module name>Classes`, where the IDE module name is the default source set name:
|
// that has a name composed as '<IDE module name>Classes`, where the IDE module name is the default source set name:
|
||||||
@@ -185,7 +179,7 @@ internal abstract class KotlinSourceSetProcessor<T : AbstractKotlinCompile<*>>(
|
|||||||
|
|
||||||
internal class Kotlin2JvmSourceSetProcessor(
|
internal class Kotlin2JvmSourceSetProcessor(
|
||||||
tasksProvider: KotlinTasksProvider,
|
tasksProvider: KotlinTasksProvider,
|
||||||
kotlinCompilation: AbstractKotlinCompilation<*>,
|
kotlinCompilation: KotlinCompilationData<*>,
|
||||||
private val kotlinPluginVersion: String
|
private val kotlinPluginVersion: String
|
||||||
) : KotlinSourceSetProcessor<KotlinCompile>(
|
) : KotlinSourceSetProcessor<KotlinCompile>(
|
||||||
tasksProvider, "Compiles the $kotlinCompilation.", kotlinCompilation
|
tasksProvider, "Compiles the $kotlinCompilation.", kotlinCompilation
|
||||||
@@ -199,14 +193,16 @@ internal class Kotlin2JvmSourceSetProcessor(
|
|||||||
|
|
||||||
override fun doTargetSpecificProcessing() {
|
override fun doTargetSpecificProcessing() {
|
||||||
ifKaptEnabled(project) {
|
ifKaptEnabled(project) {
|
||||||
Kapt3GradleSubplugin.createAptConfigurationIfNeeded(project, kotlinCompilation.compilationName)
|
Kapt3GradleSubplugin.createAptConfigurationIfNeeded(project, kotlinCompilation.compilationPurpose)
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptingGradleSubplugin.configureForSourceSet(project, kotlinCompilation.compilationName)
|
ScriptingGradleSubplugin.configureForSourceSet(project, kotlinCompilation.compilationPurpose)
|
||||||
|
|
||||||
project.whenEvaluated {
|
project.whenEvaluated {
|
||||||
val subpluginEnvironment = SubpluginEnvironment.loadSubplugins(project, kotlinPluginVersion)
|
val subpluginEnvironment = SubpluginEnvironment.loadSubplugins(project, kotlinPluginVersion)
|
||||||
subpluginEnvironment.addSubpluginOptions(project, kotlinCompilation)
|
|
||||||
|
if (kotlinCompilation is KotlinCompilation<*>) // FIXME support compiler plugins with PM20
|
||||||
|
subpluginEnvironment.addSubpluginOptions(project, kotlinCompilation)
|
||||||
|
|
||||||
javaSourceSet?.let { java ->
|
javaSourceSet?.let { java ->
|
||||||
val javaTask = project.tasks.withType<AbstractCompile>().named(java.compileJavaTaskName)
|
val javaTask = project.tasks.withType<AbstractCompile>().named(java.compileJavaTaskName)
|
||||||
@@ -236,7 +232,7 @@ internal fun KotlinCompilationOutput.addClassesDir(classesDirProvider: () -> Fil
|
|||||||
|
|
||||||
internal class Kotlin2JsSourceSetProcessor(
|
internal class Kotlin2JsSourceSetProcessor(
|
||||||
tasksProvider: KotlinTasksProvider,
|
tasksProvider: KotlinTasksProvider,
|
||||||
kotlinCompilation: AbstractKotlinCompilation<*>,
|
kotlinCompilation: KotlinCompilationData<*>,
|
||||||
private val kotlinPluginVersion: String
|
private val kotlinPluginVersion: String
|
||||||
) : KotlinSourceSetProcessor<Kotlin2JsCompile>(
|
) : KotlinSourceSetProcessor<Kotlin2JsCompile>(
|
||||||
tasksProvider,
|
tasksProvider,
|
||||||
@@ -294,7 +290,9 @@ internal class Kotlin2JsSourceSetProcessor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val subpluginEnvironment: SubpluginEnvironment = SubpluginEnvironment.loadSubplugins(project, kotlinPluginVersion)
|
val subpluginEnvironment: SubpluginEnvironment = SubpluginEnvironment.loadSubplugins(project, kotlinPluginVersion)
|
||||||
subpluginEnvironment.addSubpluginOptions(project, kotlinCompilation)
|
if (kotlinCompilation is KotlinCompilation<*>) {
|
||||||
|
subpluginEnvironment.addSubpluginOptions(project, kotlinCompilation)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -358,7 +356,7 @@ internal class KotlinJsIrSourceSetProcessor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal class KotlinCommonSourceSetProcessor(
|
internal class KotlinCommonSourceSetProcessor(
|
||||||
compilation: AbstractKotlinCompilation<*>,
|
compilation: KotlinCompilationData<*>,
|
||||||
tasksProvider: KotlinTasksProvider,
|
tasksProvider: KotlinTasksProvider,
|
||||||
private val kotlinPluginVersion: String
|
private val kotlinPluginVersion: String
|
||||||
) : KotlinSourceSetProcessor<KotlinCompileCommon>(
|
) : KotlinSourceSetProcessor<KotlinCompileCommon>(
|
||||||
@@ -367,13 +365,15 @@ internal class KotlinCommonSourceSetProcessor(
|
|||||||
override fun doTargetSpecificProcessing() {
|
override fun doTargetSpecificProcessing() {
|
||||||
project.tasks.named(kotlinCompilation.compileAllTaskName).dependsOn(kotlinTask)
|
project.tasks.named(kotlinCompilation.compileAllTaskName).dependsOn(kotlinTask)
|
||||||
// can be missing (e.g. in case of tests)
|
// can be missing (e.g. in case of tests)
|
||||||
if (kotlinCompilation.isMain()) {
|
if ((kotlinCompilation as? AbstractKotlinCompilation<*>)?.isMain() == true) {
|
||||||
project.locateTask<Task>(kotlinCompilation.target.artifactsTaskName)?.dependsOn(kotlinTask)
|
project.locateTask<Task>(kotlinCompilation.target.artifactsTaskName)?.dependsOn(kotlinTask)
|
||||||
}
|
}
|
||||||
|
|
||||||
project.whenEvaluated {
|
if (kotlinCompilation is AbstractKotlinCompilation<*>) {
|
||||||
val subpluginEnvironment: SubpluginEnvironment = SubpluginEnvironment.loadSubplugins(project, kotlinPluginVersion)
|
project.whenEvaluated {
|
||||||
subpluginEnvironment.addSubpluginOptions(project, kotlinCompilation)
|
val subpluginEnvironment: SubpluginEnvironment = SubpluginEnvironment.loadSubplugins(project, kotlinPluginVersion)
|
||||||
|
subpluginEnvironment.addSubpluginOptions(project, kotlinCompilation)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -602,7 +602,7 @@ internal abstract class AbstractKotlinPlugin(
|
|||||||
internal open class KotlinPlugin(
|
internal open class KotlinPlugin(
|
||||||
kotlinPluginVersion: String,
|
kotlinPluginVersion: String,
|
||||||
registry: ToolingModelBuilderRegistry
|
registry: ToolingModelBuilderRegistry
|
||||||
) : AbstractKotlinPlugin(KotlinTasksProvider(targetName), kotlinPluginVersion, registry) {
|
) : AbstractKotlinPlugin(KotlinTasksProvider(), kotlinPluginVersion, registry) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val targetName = "" // use empty suffix for the task names
|
private const val targetName = "" // use empty suffix for the task names
|
||||||
@@ -633,7 +633,7 @@ internal open class KotlinPlugin(
|
|||||||
internal open class KotlinCommonPlugin(
|
internal open class KotlinCommonPlugin(
|
||||||
kotlinPluginVersion: String,
|
kotlinPluginVersion: String,
|
||||||
registry: ToolingModelBuilderRegistry
|
registry: ToolingModelBuilderRegistry
|
||||||
) : AbstractKotlinPlugin(KotlinTasksProvider(targetName), kotlinPluginVersion, registry) {
|
) : AbstractKotlinPlugin(KotlinTasksProvider(), kotlinPluginVersion, registry) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val targetName = "common"
|
private const val targetName = "common"
|
||||||
@@ -662,7 +662,7 @@ internal open class KotlinCommonPlugin(
|
|||||||
internal open class Kotlin2JsPlugin(
|
internal open class Kotlin2JsPlugin(
|
||||||
kotlinPluginVersion: String,
|
kotlinPluginVersion: String,
|
||||||
registry: ToolingModelBuilderRegistry
|
registry: ToolingModelBuilderRegistry
|
||||||
) : AbstractKotlinPlugin(KotlinTasksProvider(targetName), kotlinPluginVersion, registry) {
|
) : AbstractKotlinPlugin(KotlinTasksProvider(), kotlinPluginVersion, registry) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val targetName = "2Js"
|
private const val targetName = "2Js"
|
||||||
@@ -716,7 +716,7 @@ internal open class KotlinAndroidPlugin(
|
|||||||
kotlinPluginVersion: String,
|
kotlinPluginVersion: String,
|
||||||
androidTarget: KotlinAndroidTarget
|
androidTarget: KotlinAndroidTarget
|
||||||
): AbstractAndroidProjectHandler {
|
): AbstractAndroidProjectHandler {
|
||||||
val tasksProvider = AndroidTasksProvider(androidTarget.targetName)
|
val tasksProvider = AndroidTasksProvider()
|
||||||
|
|
||||||
if (androidPluginVersion != null) {
|
if (androidPluginVersion != null) {
|
||||||
val minimalVersion = "3.0.0"
|
val minimalVersion = "3.0.0"
|
||||||
|
|||||||
+19
-2
@@ -23,12 +23,15 @@ import org.gradle.api.Project
|
|||||||
import org.gradle.api.internal.FeaturePreviews
|
import org.gradle.api.internal.FeaturePreviews
|
||||||
import org.gradle.api.logging.Logger
|
import org.gradle.api.logging.Logger
|
||||||
import org.gradle.api.logging.Logging
|
import org.gradle.api.logging.Logging
|
||||||
|
import org.gradle.api.model.ObjectFactory
|
||||||
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
|
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
|
||||||
import org.jetbrains.kotlin.gradle.dsl.*
|
import org.jetbrains.kotlin.gradle.dsl.*
|
||||||
import org.jetbrains.kotlin.gradle.logging.kotlinDebug
|
import org.jetbrains.kotlin.gradle.logging.kotlinDebug
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMetadataTarget
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMetadataTarget
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMultiplatformPlugin
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMultiplatformPlugin
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinPm20GradlePlugin
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinPm20ProjectExtension
|
||||||
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSetFactory
|
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSetFactory
|
||||||
import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService
|
import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsCompilerAttribute
|
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsCompilerAttribute
|
||||||
@@ -52,7 +55,7 @@ abstract class KotlinBasePluginWrapper : Plugin<Project> {
|
|||||||
private val log = Logging.getLogger(this.javaClass)
|
private val log = Logging.getLogger(this.javaClass)
|
||||||
val kotlinPluginVersion = loadKotlinVersionFromResource(log)
|
val kotlinPluginVersion = loadKotlinVersionFromResource(log)
|
||||||
|
|
||||||
open val projectExtensionClass: KClass<out KotlinProjectExtension> get() = KotlinProjectExtension::class
|
open val projectExtensionClass: KClass<out KotlinTopLevelExtension> get() = KotlinProjectExtension::class
|
||||||
|
|
||||||
internal open fun kotlinSourceSetFactory(project: Project): NamedDomainObjectFactory<KotlinSourceSet> =
|
internal open fun kotlinSourceSetFactory(project: Project): NamedDomainObjectFactory<KotlinSourceSet> =
|
||||||
DefaultKotlinSourceSetFactory(project)
|
DefaultKotlinSourceSetFactory(project)
|
||||||
@@ -83,12 +86,18 @@ abstract class KotlinBasePluginWrapper : Plugin<Project> {
|
|||||||
kotlinGradleBuildServices.detectKotlinPluginLoadedInMultipleProjects(project, kotlinPluginVersion)
|
kotlinGradleBuildServices.detectKotlinPluginLoadedInMultipleProjects(project, kotlinPluginVersion)
|
||||||
|
|
||||||
project.createKotlinExtension(projectExtensionClass).apply {
|
project.createKotlinExtension(projectExtensionClass).apply {
|
||||||
|
if (this is KotlinPm20ProjectExtension)
|
||||||
|
this.project = project // refactor this code to remove the specific plugin class?
|
||||||
|
|
||||||
coreLibrariesVersion = kotlinPluginVersion
|
coreLibrariesVersion = kotlinPluginVersion
|
||||||
|
|
||||||
fun kotlinSourceSetContainer(factory: NamedDomainObjectFactory<KotlinSourceSet>) =
|
fun kotlinSourceSetContainer(factory: NamedDomainObjectFactory<KotlinSourceSet>) =
|
||||||
project.container(KotlinSourceSet::class.java, factory)
|
project.container(KotlinSourceSet::class.java, factory)
|
||||||
|
|
||||||
project.kotlinExtension.sourceSets = kotlinSourceSetContainer(kotlinSourceSetFactory(project))
|
val topLevelExtension = project.topLevelExtension
|
||||||
|
if (topLevelExtension is KotlinProjectExtension) {
|
||||||
|
project.kotlinExtension.sourceSets = kotlinSourceSetContainer(kotlinSourceSetFactory(project))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
project.extensions.add(KotlinTestsRegistry.PROJECT_EXTENSION_NAME, createTestRegistry(project))
|
project.extensions.add(KotlinTestsRegistry.PROJECT_EXTENSION_NAME, createTestRegistry(project))
|
||||||
@@ -237,6 +246,14 @@ open class KotlinMultiplatformPluginWrapper @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open class KotlinPm20PluginWrapper @Inject constructor(private val objectFactory: ObjectFactory) : KotlinBasePluginWrapper() {
|
||||||
|
override fun getPlugin(project: Project, kotlinGradleBuildServices: KotlinGradleBuildServices): Plugin<Project> =
|
||||||
|
objectFactory.newInstance(KotlinPm20GradlePlugin::class.java)
|
||||||
|
|
||||||
|
override val projectExtensionClass: KClass<out KotlinPm20ProjectExtension>
|
||||||
|
get() = KotlinPm20ProjectExtension::class
|
||||||
|
}
|
||||||
|
|
||||||
fun Project.getKotlinPluginVersion(): String? =
|
fun Project.getKotlinPluginVersion(): String? =
|
||||||
plugins.asSequence().mapNotNull { (it as? KotlinBasePluginWrapper)?.kotlinPluginVersion }.firstOrNull()
|
plugins.asSequence().mapNotNull { (it as? KotlinBasePluginWrapper)?.kotlinPluginVersion }.firstOrNull()
|
||||||
|
|
||||||
|
|||||||
+1
@@ -8,6 +8,7 @@ import org.gradle.api.tasks.compile.JavaCompile
|
|||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinCompile
|
import org.jetbrains.kotlin.gradle.dsl.KotlinCompile
|
||||||
import org.jetbrains.kotlin.gradle.logging.kotlinDebug
|
import org.jetbrains.kotlin.gradle.logging.kotlinDebug
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData
|
||||||
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
|
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
|
||||||
import org.jetbrains.kotlin.gradle.tasks.CompilerPluginOptions
|
import org.jetbrains.kotlin.gradle.tasks.CompilerPluginOptions
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile
|
import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile
|
||||||
|
|||||||
+14
-2
@@ -8,10 +8,13 @@ package org.jetbrains.kotlin.gradle.plugin.mpp
|
|||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.artifacts.Dependency
|
import org.gradle.api.artifacts.Dependency
|
||||||
import org.gradle.api.artifacts.ExternalModuleDependency
|
import org.gradle.api.artifacts.ExternalModuleDependency
|
||||||
|
import org.gradle.api.artifacts.ModuleDependency
|
||||||
import org.gradle.api.artifacts.ProjectDependency
|
import org.gradle.api.artifacts.ProjectDependency
|
||||||
import org.jetbrains.kotlin.gradle.plugin.HasKotlinDependencies
|
import org.jetbrains.kotlin.gradle.plugin.HasKotlinDependencies
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler
|
import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler
|
||||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
|
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinGradleModule
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.LazyCapability
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmDependency
|
import org.jetbrains.kotlin.gradle.targets.js.npm.NpmDependency
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.directoryNpmDependency
|
import org.jetbrains.kotlin.gradle.targets.js.npm.directoryNpmDependency
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.moduleName
|
import org.jetbrains.kotlin.gradle.targets.js.npm.moduleName
|
||||||
@@ -69,8 +72,17 @@ class DefaultKotlinDependencyHandler(
|
|||||||
private fun addDependencyByAnyNotation(
|
private fun addDependencyByAnyNotation(
|
||||||
configurationName: String,
|
configurationName: String,
|
||||||
dependencyNotation: Any
|
dependencyNotation: Any
|
||||||
): Dependency? =
|
): Dependency? {
|
||||||
project.dependencies.add(configurationName, dependencyNotation)
|
val dependency = when (dependencyNotation) {
|
||||||
|
is KotlinGradleModule -> project.dependencies.create(dependencyNotation.project).apply {
|
||||||
|
(this as ModuleDependency).capabilities {
|
||||||
|
it.requireCapability(LazyCapability.fromModule(dependencyNotation))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> dependencyNotation
|
||||||
|
}
|
||||||
|
return project.dependencies.add(configurationName, dependency)
|
||||||
|
}
|
||||||
|
|
||||||
private fun addDependencyByStringNotation(
|
private fun addDependencyByStringNotation(
|
||||||
configurationName: String,
|
configurationName: String,
|
||||||
|
|||||||
-1
@@ -158,7 +158,6 @@ class GradleProjectModuleBuilder(private val addInferredSourceSetVisibilityAsExp
|
|||||||
variant.variantAttributes[KotlinAttributeKey(key.name)] =
|
variant.variantAttributes[KotlinAttributeKey(key.name)] =
|
||||||
attributeString(compileDependenciesConfiguration.attributes, key)
|
attributeString(compileDependenciesConfiguration.attributes, key)
|
||||||
}
|
}
|
||||||
variant.isExported = compilation.isMain()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Once all fragments are created, add dependencies between them
|
// Once all fragments are created, add dependencies between them
|
||||||
|
|||||||
+6
-6
@@ -11,7 +11,7 @@ import org.gradle.api.Project
|
|||||||
import org.gradle.api.attributes.Attribute
|
import org.gradle.api.attributes.Attribute
|
||||||
import org.gradle.api.attributes.AttributeContainer
|
import org.gradle.api.attributes.AttributeContainer
|
||||||
import org.gradle.api.file.DuplicatesStrategy
|
import org.gradle.api.file.DuplicatesStrategy
|
||||||
import org.gradle.api.internal.FeaturePreviews
|
import org.gradle.api.file.FileCollection
|
||||||
import org.gradle.api.internal.plugins.DslObject
|
import org.gradle.api.internal.plugins.DslObject
|
||||||
import org.gradle.api.plugins.JavaBasePlugin
|
import org.gradle.api.plugins.JavaBasePlugin
|
||||||
import org.gradle.api.tasks.SourceTask
|
import org.gradle.api.tasks.SourceTask
|
||||||
@@ -295,11 +295,11 @@ internal fun applyUserDefinedAttributes(target: AbstractKotlinTarget) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun sourcesJarTask(compilation: KotlinCompilation<*>, componentName: String?, artifactNameAppendix: String): TaskProvider<Jar> =
|
internal fun sourcesJarTask(compilation: KotlinCompilation<*>, componentName: String?, artifactNameAppendix: String): TaskProvider<Jar> =
|
||||||
sourcesJarTask(compilation.target.project, lazy { compilation.allKotlinSourceSets }, componentName, artifactNameAppendix)
|
sourcesJarTask(compilation.target.project, lazy { compilation.allKotlinSourceSets.associate { it.name to it.kotlin } }, componentName, artifactNameAppendix)
|
||||||
|
|
||||||
internal fun sourcesJarTask(
|
internal fun sourcesJarTask(
|
||||||
project: Project,
|
project: Project,
|
||||||
sourceSets: Lazy<Set<KotlinSourceSet>>,
|
sourceSets: Lazy<Map<String, FileCollection>>,
|
||||||
componentName: String?,
|
componentName: String?,
|
||||||
artifactNameAppendix: String
|
artifactNameAppendix: String
|
||||||
): TaskProvider<Jar> {
|
): TaskProvider<Jar> {
|
||||||
@@ -316,9 +316,9 @@ internal fun sourcesJarTask(
|
|||||||
|
|
||||||
project.whenEvaluated {
|
project.whenEvaluated {
|
||||||
result.configure {
|
result.configure {
|
||||||
sourceSets.value.forEach { sourceSet ->
|
sourceSets.value.forEach { (sourceSetName, sourceSetFiles) ->
|
||||||
it.from(sourceSet.kotlin) { copySpec ->
|
it.from(sourceSetFiles) { copySpec ->
|
||||||
copySpec.into(sourceSet.name)
|
copySpec.into(sourceSetName)
|
||||||
// Duplicates are coming from `SourceSets` that `sourceSet` depends on.
|
// Duplicates are coming from `SourceSets` that `sourceSet` depends on.
|
||||||
// Such dependency was added by Kotlin compilation.
|
// Such dependency was added by Kotlin compilation.
|
||||||
// TODO: rethink approach for adding dependent `SourceSets` to Kotlin compilation `SourceSet`
|
// TODO: rethink approach for adding dependent `SourceSets` to Kotlin compilation `SourceSet`
|
||||||
|
|||||||
+17
-8
@@ -24,34 +24,43 @@ object KotlinUsages {
|
|||||||
|
|
||||||
private val jvmPlatformTypes: Set<KotlinPlatformType> = setOf(jvm, androidJvm)
|
private val jvmPlatformTypes: Set<KotlinPlatformType> = setOf(jvm, androidJvm)
|
||||||
|
|
||||||
internal fun consumerApiUsage(target: KotlinTarget) = target.project.usageByName(
|
internal fun consumerApiUsage(project: Project, platformType: KotlinPlatformType) = project.usageByName(
|
||||||
when (target.platformType) {
|
when (platformType) {
|
||||||
in jvmPlatformTypes -> JAVA_API
|
in jvmPlatformTypes -> JAVA_API
|
||||||
else -> KOTLIN_API
|
else -> KOTLIN_API
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
internal fun consumerRuntimeUsage(target: KotlinTarget) = target.project.usageByName(
|
internal fun consumerApiUsage(target: KotlinTarget): Usage =
|
||||||
when (target.platformType) {
|
consumerApiUsage(target.project, target.platformType)
|
||||||
|
|
||||||
|
internal fun consumerRuntimeUsage(project: Project, platformType: KotlinPlatformType) = project.usageByName(
|
||||||
|
when (platformType) {
|
||||||
in jvmPlatformTypes -> JAVA_RUNTIME
|
in jvmPlatformTypes -> JAVA_RUNTIME
|
||||||
else -> KOTLIN_RUNTIME
|
else -> KOTLIN_RUNTIME
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
internal fun producerApiUsage(target: KotlinTarget) = target.project.usageByName(
|
internal fun consumerRuntimeUsage(target: KotlinTarget) = consumerRuntimeUsage(target.project, target.platformType)
|
||||||
when (target.platformType) {
|
|
||||||
|
internal fun producerApiUsage(project: Project, platformType: KotlinPlatformType) = project.usageByName(
|
||||||
|
when (platformType) {
|
||||||
in jvmPlatformTypes -> "java-api-jars"
|
in jvmPlatformTypes -> "java-api-jars"
|
||||||
else -> KOTLIN_API
|
else -> KOTLIN_API
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
internal fun producerRuntimeUsage(target: KotlinTarget) = target.project.usageByName(
|
internal fun producerApiUsage(target: KotlinTarget) = producerApiUsage(target.project, target.platformType)
|
||||||
when (target.platformType) {
|
|
||||||
|
internal fun producerRuntimeUsage(project: Project, platformType: KotlinPlatformType) = project.usageByName(
|
||||||
|
when (platformType) {
|
||||||
in jvmPlatformTypes -> "java-runtime-jars"
|
in jvmPlatformTypes -> "java-runtime-jars"
|
||||||
else -> KOTLIN_RUNTIME
|
else -> KOTLIN_RUNTIME
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
internal fun producerRuntimeUsage(target: KotlinTarget) = producerRuntimeUsage(target.project, target.platformType)
|
||||||
|
|
||||||
private class KotlinJavaRuntimeJarsCompatibility : AttributeCompatibilityRule<Usage> {
|
private class KotlinJavaRuntimeJarsCompatibility : AttributeCompatibilityRule<Usage> {
|
||||||
// When Gradle resolves a plain old JAR dependency with no metadata attached, the Usage attribute of that dependency
|
// When Gradle resolves a plain old JAR dependency with no metadata attached, the Usage attribute of that dependency
|
||||||
// is 'java-runtime-jars'. This rule tells Gradle that Kotlin consumers can consume plain old JARs:
|
// is 'java-runtime-jars'. This rule tells Gradle that Kotlin consumers can consume plain old JARs:
|
||||||
|
|||||||
+77
-33
@@ -13,6 +13,7 @@ import org.gradle.api.UnknownTaskException
|
|||||||
import org.gradle.api.attributes.AttributeContainer
|
import org.gradle.api.attributes.AttributeContainer
|
||||||
import org.gradle.api.execution.TaskExecutionListener
|
import org.gradle.api.execution.TaskExecutionListener
|
||||||
import org.gradle.api.file.FileCollection
|
import org.gradle.api.file.FileCollection
|
||||||
|
import org.gradle.api.file.SourceDirectorySet
|
||||||
import org.gradle.api.plugins.BasePluginConvention
|
import org.gradle.api.plugins.BasePluginConvention
|
||||||
import org.gradle.api.plugins.ExtraPropertiesExtension
|
import org.gradle.api.plugins.ExtraPropertiesExtension
|
||||||
import org.gradle.api.provider.Property
|
import org.gradle.api.provider.Property
|
||||||
@@ -23,12 +24,14 @@ import org.gradle.util.ConfigureUtil
|
|||||||
import org.jetbrains.kotlin.gradle.dsl.*
|
import org.jetbrains.kotlin.gradle.dsl.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.*
|
import org.jetbrains.kotlin.gradle.plugin.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.internal.KotlinCompilationsModuleGroups
|
import org.jetbrains.kotlin.gradle.plugin.mpp.internal.KotlinCompilationsModuleGroups
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData
|
||||||
import org.jetbrains.kotlin.gradle.plugin.sources.defaultSourceSetLanguageSettingsChecker
|
import org.jetbrains.kotlin.gradle.plugin.sources.defaultSourceSetLanguageSettingsChecker
|
||||||
import org.jetbrains.kotlin.gradle.plugin.sources.withAllDependsOnSourceSets
|
import org.jetbrains.kotlin.gradle.plugin.sources.withAllDependsOnSourceSets
|
||||||
import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllDependsOnSourceSets
|
import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllDependsOnSourceSets
|
||||||
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
|
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
|
||||||
import org.jetbrains.kotlin.gradle.tasks.locateTask
|
import org.jetbrains.kotlin.gradle.tasks.locateTask
|
||||||
import org.jetbrains.kotlin.gradle.utils.*
|
import org.jetbrains.kotlin.gradle.utils.*
|
||||||
|
import java.io.File
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.Callable
|
import java.util.concurrent.Callable
|
||||||
|
|
||||||
@@ -52,8 +55,11 @@ internal val KotlinCompilation<*>.kotlinSourceSetsIncludingDefault: Set<KotlinSo
|
|||||||
|
|
||||||
abstract class AbstractKotlinCompilation<T : KotlinCommonOptions>(
|
abstract class AbstractKotlinCompilation<T : KotlinCommonOptions>(
|
||||||
target: KotlinTarget,
|
target: KotlinTarget,
|
||||||
|
override val compilationPurpose: String
|
||||||
|
) : KotlinCompilation<T>, HasKotlinDependencies, KotlinCompilationData<T> {
|
||||||
|
|
||||||
override val compilationName: String
|
override val compilationName: String
|
||||||
) : KotlinCompilation<T>, HasKotlinDependencies {
|
get() = compilationPurpose
|
||||||
|
|
||||||
override fun kotlinOptions(configure: T.() -> Unit) =
|
override fun kotlinOptions(configure: T.() -> Unit) =
|
||||||
configure(kotlinOptions)
|
configure(kotlinOptions)
|
||||||
@@ -86,7 +92,7 @@ abstract class AbstractKotlinCompilation<T : KotlinCommonOptions>(
|
|||||||
when {
|
when {
|
||||||
isMain() && target is KotlinMetadataTarget ->
|
isMain() && target is KotlinMetadataTarget ->
|
||||||
KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME // corner case: main compilation of the metadata target compiles commonMain
|
KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME // corner case: main compilation of the metadata target compiles commonMain
|
||||||
else -> compilationName
|
else -> compilationPurpose
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -101,23 +107,14 @@ abstract class AbstractKotlinCompilation<T : KotlinCommonOptions>(
|
|||||||
Callable { target.project.buildDir.resolve("processedResources/${target.targetName}/$name") })
|
Callable { target.project.buildDir.resolve("processedResources/${target.targetName}/$name") })
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun addSourcesToCompileTask(sourceSet: KotlinSourceSet, addAsCommonSources: Lazy<Boolean>) {
|
open fun addSourcesToCompileTask(sourceSet: KotlinSourceSet, addAsCommonSources: Lazy<Boolean>) =
|
||||||
fun AbstractKotlinCompile<*>.configureAction() {
|
addSourcesToKotlinCompileTask(
|
||||||
source(sourceSet.kotlin)
|
project,
|
||||||
sourceFilesExtensions(sourceSet.customSourceFilesExtensions)
|
compileKotlinTaskName,
|
||||||
commonSourceSet += project.files(Callable {
|
sourceSet.customSourceFilesExtensions,
|
||||||
if (addAsCommonSources.value) sourceSet.kotlin else emptyList<Any>()
|
{ sourceSet.kotlin },
|
||||||
})
|
addAsCommonSources
|
||||||
}
|
)
|
||||||
|
|
||||||
target.project.tasks
|
|
||||||
// To configure a task that may have not yet been created at this point, use 'withType-matching-configureEach`:
|
|
||||||
.withType(AbstractKotlinCompile::class.java)
|
|
||||||
.matching { it.name == compileKotlinTaskName }
|
|
||||||
.configureEach { compileKotlinTask ->
|
|
||||||
compileKotlinTask.configureAction()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun addExactSourceSetsEagerly(sourceSets: Set<KotlinSourceSet>) {
|
internal fun addExactSourceSetsEagerly(sourceSets: Set<KotlinSourceSet>) {
|
||||||
with(target.project) {
|
with(target.project) {
|
||||||
@@ -166,20 +163,20 @@ abstract class AbstractKotlinCompilation<T : KotlinCommonOptions>(
|
|||||||
override val compileDependencyConfigurationName: String
|
override val compileDependencyConfigurationName: String
|
||||||
get() = lowerCamelCaseName(
|
get() = lowerCamelCaseName(
|
||||||
target.disambiguationClassifier,
|
target.disambiguationClassifier,
|
||||||
compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }.orEmpty(),
|
compilationPurpose.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }.orEmpty(),
|
||||||
"compileClasspath"
|
"compileClasspath"
|
||||||
)
|
)
|
||||||
|
|
||||||
override val compileKotlinTaskName: String
|
override val compileKotlinTaskName: String
|
||||||
get() = lowerCamelCaseName(
|
get() = lowerCamelCaseName(
|
||||||
"compile",
|
"compile",
|
||||||
compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME },
|
compilationPurpose.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME },
|
||||||
"Kotlin",
|
"Kotlin",
|
||||||
target.targetName
|
target.targetName
|
||||||
)
|
)
|
||||||
|
|
||||||
override val compileAllTaskName: String
|
override val compileAllTaskName: String
|
||||||
get() = lowerCamelCaseName(target.disambiguationClassifier, compilationName, "classes")
|
get() = lowerCamelCaseName(target.disambiguationClassifier, compilationPurpose, "classes")
|
||||||
|
|
||||||
override lateinit var compileDependencyFiles: FileCollection
|
override lateinit var compileDependencyFiles: FileCollection
|
||||||
|
|
||||||
@@ -201,7 +198,7 @@ abstract class AbstractKotlinCompilation<T : KotlinCommonOptions>(
|
|||||||
override fun dependencies(configureClosure: Closure<Any?>) =
|
override fun dependencies(configureClosure: Closure<Any?>) =
|
||||||
dependencies f@{ ConfigureUtil.configure(configureClosure, this@f) }
|
dependencies f@{ ConfigureUtil.configure(configureClosure, this@f) }
|
||||||
|
|
||||||
override fun toString(): String = "compilation '$compilationName' ($target)"
|
override fun toString(): String = "compilation '$compilationPurpose' ($target)"
|
||||||
|
|
||||||
internal val friendArtifactsTask: TaskProvider<AbstractArchiveTask>? by lazy {
|
internal val friendArtifactsTask: TaskProvider<AbstractArchiveTask>? by lazy {
|
||||||
if (associateWithTransitiveClosure.any { it.isMain() }) {
|
if (associateWithTransitiveClosure.any { it.isMain() }) {
|
||||||
@@ -240,7 +237,7 @@ abstract class AbstractKotlinCompilation<T : KotlinCommonOptions>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override val moduleName: String
|
override val moduleName: String
|
||||||
get() = KotlinCompilationsModuleGroups.getModuleLeaderCompilation(this).takeIf { it != this }?.ownModuleName ?: ownModuleName
|
get() = KotlinCompilationsModuleGroups.getModuleLeaderCompilation(this).takeIf { it != this }?.ownModuleName() ?: ownModuleName
|
||||||
|
|
||||||
override fun associateWith(other: KotlinCompilation<*>) {
|
override fun associateWith(other: KotlinCompilation<*>) {
|
||||||
require(other.target == target) { "Only associations between compilations of a single target are supported" }
|
require(other.target == target) { "Only associations between compilations of a single target are supported" }
|
||||||
@@ -278,17 +275,64 @@ abstract class AbstractKotlinCompilation<T : KotlinCommonOptions>(
|
|||||||
|
|
||||||
override val associateWith: List<KotlinCompilation<*>>
|
override val associateWith: List<KotlinCompilation<*>>
|
||||||
get() = Collections.unmodifiableList(_associateWith.toList())
|
get() = Collections.unmodifiableList(_associateWith.toList())
|
||||||
|
|
||||||
|
override val kotlinOptions: T
|
||||||
|
get() = TODO("Not yet implemented")
|
||||||
|
|
||||||
|
override val project: Project
|
||||||
|
get() = target.project
|
||||||
|
|
||||||
|
override val owner: Any?
|
||||||
|
get() = target
|
||||||
|
|
||||||
|
override val compilationClassifier: String?
|
||||||
|
get() = target.disambiguationClassifier
|
||||||
|
|
||||||
|
override val kotlinSourceDirectoriesByFragmentName: Map<String, SourceDirectorySet>
|
||||||
|
get() = defaultSourceSet.withAllDependsOnSourceSets().associate { it.name to it.kotlin }
|
||||||
|
|
||||||
|
override val languageSettings: LanguageSettingsBuilder
|
||||||
|
get() = defaultSourceSet.languageSettings
|
||||||
|
|
||||||
|
override val platformType: KotlinPlatformType
|
||||||
|
get() = target.platformType
|
||||||
|
|
||||||
|
override val ownModuleName: String
|
||||||
|
get() = ownModuleName()
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val KotlinCompilation<*>.ownModuleName: String
|
internal fun addSourcesToKotlinCompileTask(
|
||||||
get() {
|
project: Project,
|
||||||
val project = target.project
|
taskName: String,
|
||||||
val baseName = project.convention.findPlugin(BasePluginConvention::class.java)?.archivesBaseName
|
sourceFileExtensions: Iterable<String>,
|
||||||
?: project.name
|
sources: () -> Iterable<File>,
|
||||||
val suffix = if (isMain()) "" else "_$compilationName"
|
addAsCommonSources: Lazy<Boolean>
|
||||||
return filterModuleName("$baseName$suffix")
|
) {
|
||||||
|
fun AbstractKotlinCompile<*>.configureAction() {
|
||||||
|
source(project.files(Callable { sources() }))
|
||||||
|
sourceFilesExtensions(sourceFileExtensions)
|
||||||
|
commonSourceSet += project.files(Callable {
|
||||||
|
if (addAsCommonSources.value) sources() else emptyList<Any>()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
project.tasks
|
||||||
|
// To configure a task that may have not yet been created at this point, use 'withType-matching-configureEach`:
|
||||||
|
.withType(AbstractKotlinCompile::class.java)
|
||||||
|
.matching { it.name == taskName }
|
||||||
|
.configureEach { compileKotlinTask ->
|
||||||
|
compileKotlinTask.configureAction()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun KotlinCompilation<*>.ownModuleName(): String {
|
||||||
|
val project = target.project
|
||||||
|
val baseName = project.convention.findPlugin(BasePluginConvention::class.java)?.archivesBaseName
|
||||||
|
?: project.name
|
||||||
|
val suffix = if (isMain()) "" else "_$compilationName"
|
||||||
|
return filterModuleName("$baseName$suffix")
|
||||||
|
}
|
||||||
|
|
||||||
internal val KotlinCompilation<*>.associateWithTransitiveClosure: Iterable<KotlinCompilation<*>>
|
internal val KotlinCompilation<*>.associateWithTransitiveClosure: Iterable<KotlinCompilation<*>>
|
||||||
get() = mutableSetOf<KotlinCompilation<*>>().apply {
|
get() = mutableSetOf<KotlinCompilation<*>>().apply {
|
||||||
fun visit(other: KotlinCompilation<*>) {
|
fun visit(other: KotlinCompilation<*>) {
|
||||||
@@ -306,7 +350,7 @@ abstract class AbstractKotlinCompilationToRunnableFiles<T : KotlinCommonOptions>
|
|||||||
override val runtimeDependencyConfigurationName: String
|
override val runtimeDependencyConfigurationName: String
|
||||||
get() = lowerCamelCaseName(
|
get() = lowerCamelCaseName(
|
||||||
target.disambiguationClassifier,
|
target.disambiguationClassifier,
|
||||||
compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME },
|
compilationPurpose.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME },
|
||||||
"runtimeClasspath"
|
"runtimeClasspath"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -397,5 +441,5 @@ internal object CompilationSourceSetUtil {
|
|||||||
|
|
||||||
private val invalidModuleNameCharactersRegex = """[\\/\r\n\t]""".toRegex()
|
private val invalidModuleNameCharactersRegex = """[\\/\r\n\t]""".toRegex()
|
||||||
|
|
||||||
private fun filterModuleName(moduleName: String): String =
|
internal fun filterModuleName(moduleName: String): String =
|
||||||
moduleName.replace(invalidModuleNameCharactersRegex, "_")
|
moduleName.replace(invalidModuleNameCharactersRegex, "_")
|
||||||
|
|||||||
+133
@@ -0,0 +1,133 @@
|
|||||||
|
/*
|
||||||
|
* 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.plugin.mpp.pm20
|
||||||
|
|
||||||
|
import org.gradle.api.NamedDomainObjectContainer
|
||||||
|
import org.gradle.api.NamedDomainObjectProvider
|
||||||
|
import org.gradle.api.Plugin
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.plugins.JavaBasePlugin
|
||||||
|
import org.gradle.util.GradleVersion
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.KotlinTopLevelExtension
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.pm20Extension
|
||||||
|
import org.jetbrains.kotlin.gradle.internal.customizeKotlinDependencies
|
||||||
|
import org.jetbrains.kotlin.gradle.utils.checkGradleCompatibility
|
||||||
|
|
||||||
|
abstract class KotlinPm20GradlePlugin : Plugin<Project> {
|
||||||
|
override fun apply(project: Project) {
|
||||||
|
checkGradleCompatibility("the Kotlin Multiplatform plugin", GradleVersion.version("6.1"))
|
||||||
|
|
||||||
|
// Gradle sets up the attribute schema for consuming JVM dependencies in the JavaBasePlugin
|
||||||
|
project.plugins.apply(JavaBasePlugin::class.java)
|
||||||
|
|
||||||
|
createDefaultModules(project)
|
||||||
|
customizeKotlinDependencies(project)
|
||||||
|
registerDefaultVariantFactories(project)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun registerDefaultVariantFactories(project: Project) {
|
||||||
|
project.pm20Extension.modules.configureEach {
|
||||||
|
it.fragments.registerFactory(
|
||||||
|
KotlinJvmVariant::class.java,
|
||||||
|
KotlinJvmVariantFactory(it)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createDefaultModules(project: Project) {
|
||||||
|
project.pm20Extension.apply {
|
||||||
|
modules.create(KotlinGradleModule.MAIN_MODULE_NAME)
|
||||||
|
modules.create(KotlinGradleModule.TEST_MODULE_NAME)
|
||||||
|
main { makePublic() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupMetadataCompilation() {
|
||||||
|
// TODO dependency transformations in tasks
|
||||||
|
// TODO classpath configurations
|
||||||
|
// TODO compilation data -> tasks
|
||||||
|
// TODO project structure metadata -> metadata artifact
|
||||||
|
// TODO task outputs -> metadata artifact
|
||||||
|
// TODO export the metadata artifact in consumable configurations
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open class KotlinPm20ProjectExtension : KotlinTopLevelExtension() {
|
||||||
|
internal lateinit var project: Project
|
||||||
|
|
||||||
|
val modules: NamedDomainObjectContainer<KotlinGradleModule> by lazy {
|
||||||
|
project.objects.domainObjectContainer(
|
||||||
|
KotlinGradleModule::class.java,
|
||||||
|
KotlinGradleModuleFactory(project)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("unused") // DSL function
|
||||||
|
fun mainAndTest(configure: KotlinGradleModule.() -> Unit) {
|
||||||
|
main(configure)
|
||||||
|
test(configure)
|
||||||
|
}
|
||||||
|
|
||||||
|
val main: KotlinGradleModule
|
||||||
|
get() = modules.getByName(KotlinGradleModule.MAIN_MODULE_NAME)
|
||||||
|
|
||||||
|
val test: KotlinGradleModule
|
||||||
|
get() = modules.getByName(KotlinGradleModule.TEST_MODULE_NAME)
|
||||||
|
|
||||||
|
fun main(configure: KotlinGradleModule.() -> Unit = { }) = main.apply(configure)
|
||||||
|
fun test(configure: KotlinGradleModule.() -> Unit = { }) = test.apply(configure)
|
||||||
|
}
|
||||||
|
|
||||||
|
val KotlinGradleModule.jvm: KotlinJvmVariant
|
||||||
|
get() = fragments.maybeCreate("jvm", KotlinJvmVariant::class.java)
|
||||||
|
|
||||||
|
fun KotlinGradleModule.jvm(configure: KotlinJvmVariant.() -> Unit): KotlinJvmVariant = jvm.apply(configure)
|
||||||
|
|
||||||
|
fun KotlinPm20ProjectExtension.jvm(configure: KotlinFragmentSlice<KotlinJvmVariant>.() -> Unit) {
|
||||||
|
val getOrCreateVariant: KotlinGradleModule.() -> KotlinJvmVariant = { jvm }
|
||||||
|
mainAndTest { getOrCreateVariant(this) }
|
||||||
|
val slice = KotlinFragmentSlice(this, getOrCreateVariant)
|
||||||
|
configure(slice)
|
||||||
|
}
|
||||||
|
|
||||||
|
open class KotlinFragmentSlice<T : KotlinGradleFragment>(
|
||||||
|
val pm20ProjectExtension: KotlinPm20ProjectExtension,
|
||||||
|
val getOrCreateFragment: (KotlinGradleModule) -> T
|
||||||
|
) {
|
||||||
|
fun inMain(configure: T.() -> Unit) {
|
||||||
|
pm20ProjectExtension.modules.getByName(KotlinGradleModule.MAIN_MODULE_NAME).apply {
|
||||||
|
getOrCreateFragment(this).configure()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun inTest(configure: T.() -> Unit) {
|
||||||
|
pm20ProjectExtension.modules.getByName(KotlinGradleModule.TEST_MODULE_NAME).apply {
|
||||||
|
getOrCreateFragment(this).configure()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun inMainAndTest(configure: T.() -> Unit) {
|
||||||
|
pm20ProjectExtension.mainAndTest { getOrCreateFragment(this).configure() }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun inAllModules(configure: T.() -> Unit) {
|
||||||
|
pm20ProjectExtension.modules.all {
|
||||||
|
getOrCreateFragment(it).configure()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun inModule(moduleName: String, configure: T.() -> Unit) {
|
||||||
|
pm20ProjectExtension.modules.getByName(moduleName).apply { getOrCreateFragment(this).configure() }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun inModule(module: NamedDomainObjectProvider<KotlinGradleModule>, configure: T.() -> Unit) {
|
||||||
|
module.get().apply { inModule(this, configure) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun inModule(module: KotlinGradleModule, configure: T.() -> Unit) {
|
||||||
|
getOrCreateFragment(module).configure()
|
||||||
|
}
|
||||||
|
}
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* 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.plugin.mpp.pm20
|
||||||
|
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.file.FileCollection
|
||||||
|
import org.gradle.api.file.SourceDirectorySet
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationOutput
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.LanguageSettingsBuilder
|
||||||
|
|
||||||
|
interface KotlinCompilationData<T : KotlinCommonOptions> {
|
||||||
|
val project: Project
|
||||||
|
val owner: Any?
|
||||||
|
|
||||||
|
val compilationPurpose: String
|
||||||
|
val compilationClassifier: String?
|
||||||
|
|
||||||
|
val kotlinSourceDirectoriesByFragmentName: Map<String, SourceDirectorySet>
|
||||||
|
val compileKotlinTaskName: String
|
||||||
|
val compileAllTaskName: String
|
||||||
|
|
||||||
|
val compileDependencyFiles: FileCollection
|
||||||
|
val output: KotlinCompilationOutput
|
||||||
|
|
||||||
|
val languageSettings: LanguageSettingsBuilder
|
||||||
|
val platformType: KotlinPlatformType
|
||||||
|
|
||||||
|
val moduleName: String
|
||||||
|
val ownModuleName: String
|
||||||
|
|
||||||
|
val kotlinOptions: T
|
||||||
|
}
|
||||||
+110
@@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* 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.plugin.mpp.pm20
|
||||||
|
|
||||||
|
import groovy.lang.Closure
|
||||||
|
import org.gradle.api.Named
|
||||||
|
import org.gradle.api.NamedDomainObjectProvider
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.file.SourceDirectorySet
|
||||||
|
import org.gradle.api.provider.Provider
|
||||||
|
import org.gradle.util.ConfigureUtil
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.HasKotlinDependencies
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.LanguageSettingsBuilder
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.DefaultKotlinDependencyHandler
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultLanguageSettingsBuilder
|
||||||
|
import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation
|
||||||
|
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||||
|
import org.jetbrains.kotlin.project.model.KotlinModuleDependency
|
||||||
|
import org.jetbrains.kotlin.project.model.KotlinModuleFragment
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
open class KotlinGradleFragment @Inject constructor(
|
||||||
|
override val containingModule: KotlinGradleModule,
|
||||||
|
override val fragmentName: String
|
||||||
|
) : KotlinModuleFragment, HasKotlinDependencies, Named {
|
||||||
|
|
||||||
|
override fun getName(): String = fragmentName
|
||||||
|
|
||||||
|
// TODO pull up to KotlinModuleFragment
|
||||||
|
val languageSettings: LanguageSettingsBuilder = DefaultLanguageSettingsBuilder()
|
||||||
|
|
||||||
|
protected val project: Project
|
||||||
|
get() = containingModule.project
|
||||||
|
|
||||||
|
open fun refines(other: KotlinGradleFragment) {
|
||||||
|
checkCanRefine(other)
|
||||||
|
refines(containingModule.fragments.named(other.name))
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun refines(other: NamedDomainObjectProvider<KotlinGradleFragment>) {
|
||||||
|
_directRefinesDependencies.add(other)
|
||||||
|
other.configure { checkCanRefine(it) }
|
||||||
|
listOf(
|
||||||
|
KotlinGradleFragment::transitiveApiConfigurationName,
|
||||||
|
KotlinGradleFragment::transitiveImplementationConfigurationName
|
||||||
|
).forEach { getConfiguration ->
|
||||||
|
project.addExtendsFromRelation(getConfiguration(this), getConfiguration(other.get())) // todo eager instantiation; fix?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkCanRefine(other: KotlinGradleFragment) {
|
||||||
|
check(containingModule == other.containingModule) { "Fragments can only refine each other within one module." }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun dependencies(configure: KotlinDependencyHandler.() -> Unit): Unit =
|
||||||
|
DefaultKotlinDependencyHandler(this, project).run(configure)
|
||||||
|
|
||||||
|
override fun dependencies(configureClosure: Closure<Any?>) =
|
||||||
|
dependencies f@{ ConfigureUtil.configure(configureClosure, this@f) }
|
||||||
|
|
||||||
|
override val apiConfigurationName: String
|
||||||
|
get() = disambiguateName("api")
|
||||||
|
|
||||||
|
override val implementationConfigurationName: String
|
||||||
|
get() = disambiguateName("implementation")
|
||||||
|
|
||||||
|
override val compileOnlyConfigurationName: String
|
||||||
|
get() = disambiguateName("compileOnly")
|
||||||
|
|
||||||
|
override val runtimeOnlyConfigurationName: String
|
||||||
|
get() = disambiguateName("runtimeOnly")
|
||||||
|
|
||||||
|
private val _directRefinesDependencies = mutableSetOf<Provider<KotlinGradleFragment>>()
|
||||||
|
|
||||||
|
override val directRefinesDependencies: Iterable<KotlinGradleFragment>
|
||||||
|
get() = _directRefinesDependencies.map { it.get() }
|
||||||
|
|
||||||
|
override val declaredModuleDependencies: Iterable<KotlinModuleDependency>
|
||||||
|
get() = TODO("Not yet implemented")
|
||||||
|
|
||||||
|
override val kotlinSourceRoots: SourceDirectorySet by lazy {
|
||||||
|
project.objects.sourceDirectorySet(
|
||||||
|
"$fragmentName.kotlin", "Kotlin sources for fragment $fragmentName"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** This configuration includes the dependencies from the refines-parents */
|
||||||
|
internal val transitiveApiConfigurationName: String
|
||||||
|
get() = disambiguateName("transitiveApi")
|
||||||
|
|
||||||
|
/** This configuration includes the dependencies from the refines-parents */
|
||||||
|
internal val transitiveImplementationConfigurationName: String
|
||||||
|
get() = disambiguateName("transitiveImplementation")
|
||||||
|
|
||||||
|
override val relatedConfigurationNames: List<String>
|
||||||
|
get() = super.relatedConfigurationNames +
|
||||||
|
// TODO: resolvable metadata configurations?
|
||||||
|
listOf(transitiveApiConfigurationName, transitiveImplementationConfigurationName)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val COMMON_FRAGMENT_NAME = "common"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun KotlinModuleFragment.disambiguateName(simpleName: String) =
|
||||||
|
lowerCamelCaseName(fragmentName, containingModule.moduleIdentifier.moduleClassifier ?: KotlinGradleModule.MAIN_MODULE_NAME, simpleName)
|
||||||
+93
@@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* 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.plugin.mpp.pm20
|
||||||
|
|
||||||
|
import groovy.lang.Closure
|
||||||
|
import org.gradle.api.ExtensiblePolymorphicDomainObjectContainer
|
||||||
|
import org.gradle.api.Named
|
||||||
|
import org.gradle.api.NamedDomainObjectSet
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.HasKotlinDependencies
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler
|
||||||
|
import org.jetbrains.kotlin.project.model.KotlinModule
|
||||||
|
import org.jetbrains.kotlin.project.model.KotlinModuleIdentifier
|
||||||
|
import org.jetbrains.kotlin.project.model.LocalModuleIdentifier
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
open class KotlinGradleModule(
|
||||||
|
internal val project: Project,
|
||||||
|
val moduleClassifier: String?
|
||||||
|
) : KotlinModule, Named, HasKotlinDependencies {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
constructor(project: Project, moduleClassifier: CharSequence)
|
||||||
|
: this(project, moduleClassifier.toString().takeIf { it != MAIN_MODULE_NAME })
|
||||||
|
|
||||||
|
override val moduleIdentifier: KotlinModuleIdentifier =
|
||||||
|
LocalModuleIdentifier(project.currentBuildId().name, project.path, moduleClassifier)
|
||||||
|
|
||||||
|
override val fragments: ExtensiblePolymorphicDomainObjectContainer<KotlinGradleFragment> =
|
||||||
|
project.objects.polymorphicDomainObjectContainer(KotlinGradleFragment::class.java)
|
||||||
|
|
||||||
|
// TODO DSL & build script model: find a way to create a flexible typed view on fragments?
|
||||||
|
override val variants: NamedDomainObjectSet<KotlinGradleVariant> by lazy {
|
||||||
|
fragments.withType(KotlinGradleVariant::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
var isPublic: Boolean = false
|
||||||
|
private set
|
||||||
|
|
||||||
|
private var setPublicHandlers: MutableList<() -> Unit> = mutableListOf()
|
||||||
|
|
||||||
|
fun ifMadePublic(action: () -> Unit) {
|
||||||
|
if (isPublic) action() else setPublicHandlers.add(action)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun makePublic() {
|
||||||
|
if (isPublic) return
|
||||||
|
setPublicHandlers.forEach { it() }
|
||||||
|
isPublic = true
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val MAIN_MODULE_NAME = "main"
|
||||||
|
const val TEST_MODULE_NAME = "test"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getName(): String = when (moduleClassifier) {
|
||||||
|
null -> MAIN_MODULE_NAME
|
||||||
|
else -> moduleClassifier
|
||||||
|
}
|
||||||
|
|
||||||
|
// DSL
|
||||||
|
|
||||||
|
val common: KotlinGradleFragment
|
||||||
|
get() = fragments.getByName(KotlinGradleFragment.COMMON_FRAGMENT_NAME)
|
||||||
|
|
||||||
|
fun common(configure: KotlinGradleFragment.() -> Unit) =
|
||||||
|
common.configure()
|
||||||
|
|
||||||
|
override fun dependencies(configure: KotlinDependencyHandler.() -> Unit) =
|
||||||
|
common.dependencies(configure)
|
||||||
|
|
||||||
|
override fun dependencies(configureClosure: Closure<Any?>) =
|
||||||
|
common.dependencies(configureClosure)
|
||||||
|
|
||||||
|
override val apiConfigurationName: String
|
||||||
|
get() = common.apiConfigurationName
|
||||||
|
|
||||||
|
override val implementationConfigurationName: String
|
||||||
|
get() = common.implementationConfigurationName
|
||||||
|
|
||||||
|
override val compileOnlyConfigurationName: String
|
||||||
|
get() = common.compileOnlyConfigurationName
|
||||||
|
|
||||||
|
override val runtimeOnlyConfigurationName: String
|
||||||
|
get() = common.runtimeOnlyConfigurationName
|
||||||
|
}
|
||||||
|
|
||||||
|
internal val KotlinGradleModule.isMain
|
||||||
|
get() = moduleIdentifier.moduleClassifier == null
|
||||||
+47
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* 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.plugin.mpp.pm20
|
||||||
|
|
||||||
|
import org.gradle.api.NamedDomainObjectFactory
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.pm20Extension
|
||||||
|
|
||||||
|
open class KotlinGradleModuleFactory(private val project: Project) : NamedDomainObjectFactory<KotlinGradleModule> {
|
||||||
|
override fun create(name: String): KotlinGradleModule {
|
||||||
|
val result = project.objects.newInstance(KotlinGradleModule::class.java, project, name)
|
||||||
|
registerFragmentFactory(result)
|
||||||
|
registerDefaultCommonFragment(result)
|
||||||
|
addDefaultDependencyOnMainModule(result)
|
||||||
|
addDefaultRefinementDependencyOnCommon(result)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun registerDefaultCommonFragment(module: KotlinGradleModule) {
|
||||||
|
module.fragments.create(KotlinGradleFragment.COMMON_FRAGMENT_NAME, KotlinGradleFragment::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun addDefaultRefinementDependencyOnCommon(module: KotlinGradleModule) {
|
||||||
|
module.fragments.matching { it.name != KotlinGradleFragment.COMMON_FRAGMENT_NAME }.all {
|
||||||
|
it.refines(module.fragments.named(KotlinGradleFragment.COMMON_FRAGMENT_NAME))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun addDefaultDependencyOnMainModule(module: KotlinGradleModule) {
|
||||||
|
if (module.name != KotlinGradleModule.MAIN_MODULE_NAME) {
|
||||||
|
module.fragments
|
||||||
|
.matching { it.fragmentName == KotlinGradleFragment.COMMON_FRAGMENT_NAME }
|
||||||
|
.configureEach { commonFragment ->
|
||||||
|
commonFragment.dependencies {
|
||||||
|
api(module.project.pm20Extension.modules.getByName(KotlinGradleModule.MAIN_MODULE_NAME))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun registerFragmentFactory(module: KotlinGradleModule) {
|
||||||
|
module.fragments.registerFactory(KotlinGradleFragment::class.java, CommonGradleFragmentFactory(module))
|
||||||
|
}
|
||||||
|
}
|
||||||
+80
@@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* 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.plugin.mpp.pm20
|
||||||
|
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.file.FileCollection
|
||||||
|
import org.gradle.api.file.SourceDirectorySet
|
||||||
|
import org.gradle.api.plugins.BasePluginConvention
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.pm20Extension
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationOutput
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.LanguageSettingsBuilder
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.filterModuleName
|
||||||
|
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||||
|
import org.jetbrains.kotlin.project.model.refinesClosure
|
||||||
|
|
||||||
|
open class KotlinJvmVariant(containingModule: KotlinGradleModule, fragmentName: String) :
|
||||||
|
KotlinGradleVariantWithRuntimeDependencies(containingModule, fragmentName) {
|
||||||
|
|
||||||
|
override val platformType: KotlinPlatformType
|
||||||
|
get() = KotlinPlatformType.jvm
|
||||||
|
}
|
||||||
|
|
||||||
|
class KotlinJvmVariantCompilationData(val variant: KotlinJvmVariant) : KotlinCompilationData<KotlinJvmOptions> {
|
||||||
|
override val project: Project get() = variant.containingModule.project
|
||||||
|
|
||||||
|
override val owner: KotlinJvmVariant get() = variant
|
||||||
|
|
||||||
|
override val compilationPurpose: String
|
||||||
|
get() = variant.containingModule.name
|
||||||
|
|
||||||
|
override val compilationClassifier: String
|
||||||
|
get() = variant.name
|
||||||
|
|
||||||
|
override val kotlinSourceDirectoriesByFragmentName: Map<String, SourceDirectorySet>
|
||||||
|
get() = variant.refinesClosure.filterIsInstance<KotlinGradleVariant>().associate { it.disambiguateName("") to it.kotlinSourceRoots }
|
||||||
|
|
||||||
|
override val output: KotlinCompilationOutput
|
||||||
|
get() = variant.compilationOutputs
|
||||||
|
|
||||||
|
override val compileKotlinTaskName: String
|
||||||
|
get() = lowerCamelCaseName("compile", compilationPurpose.takeIf { it != "main" }, "Kotlin", compilationClassifier)
|
||||||
|
|
||||||
|
override val compileAllTaskName: String
|
||||||
|
get() = variant.disambiguateName("classes")
|
||||||
|
|
||||||
|
override val compileDependencyFiles: FileCollection
|
||||||
|
get() = variant.compileDependencyFiles
|
||||||
|
|
||||||
|
override val languageSettings: LanguageSettingsBuilder
|
||||||
|
get() = variant.languageSettings
|
||||||
|
|
||||||
|
override val platformType: KotlinPlatformType
|
||||||
|
get() = variant.platformType
|
||||||
|
|
||||||
|
override val moduleName: String
|
||||||
|
get() = // TODO accurate module names that don't rely on all variants having a main counterpart
|
||||||
|
variant.containingModule.project.pm20Extension.modules
|
||||||
|
.getByName(KotlinGradleModule.MAIN_MODULE_NAME).variants.findByName(variant.name)?.ownModuleName() ?: ownModuleName
|
||||||
|
|
||||||
|
override val ownModuleName: String
|
||||||
|
get() = variant.ownModuleName()
|
||||||
|
|
||||||
|
// TODO pull out to the variant
|
||||||
|
override val kotlinOptions: KotlinJvmOptions
|
||||||
|
get() = KotlinJvmOptionsImpl()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun KotlinGradleVariant.ownModuleName(): String {
|
||||||
|
val project = containingModule.project
|
||||||
|
val baseName = project.convention.findPlugin(BasePluginConvention::class.java)?.archivesBaseName
|
||||||
|
?: project.name
|
||||||
|
val suffix = if (containingModule.moduleClassifier == null) "" else "_${containingModule.moduleClassifier}"
|
||||||
|
return filterModuleName("$baseName$suffix")
|
||||||
|
}
|
||||||
+122
@@ -0,0 +1,122 @@
|
|||||||
|
/*
|
||||||
|
* 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.plugin.mpp.pm20
|
||||||
|
|
||||||
|
import org.gradle.api.artifacts.Configuration
|
||||||
|
import org.gradle.api.attributes.Usage
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.sourcesJarTask
|
||||||
|
import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation
|
||||||
|
import org.jetbrains.kotlin.project.model.refinesClosure
|
||||||
|
|
||||||
|
abstract class AbstractKotlinGradleVariantFactory<T : KotlinGradleVariant>(
|
||||||
|
module: KotlinGradleModule
|
||||||
|
) : AbstractKotlinGradleFragmentFactory<T>(module) {
|
||||||
|
|
||||||
|
override fun create(name: String): T = super.create(name).also { fragment ->
|
||||||
|
createSourcesArchiveTask(fragment)
|
||||||
|
configureKotlinCompilation(fragment)
|
||||||
|
createElementsConfigurations(fragment)
|
||||||
|
// TODO configure resources processing
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun setPlatformAttributesInConfiguration(fragment: T, configuration: Configuration) {
|
||||||
|
configuration.attributes.attribute(KotlinPlatformType.attribute, fragment.platformType)
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun configureCompileResolvableConfiguration(fragment: T, configuration: Configuration) {
|
||||||
|
setPlatformAttributesInConfiguration(fragment, configuration)
|
||||||
|
configuration.attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerApiUsage(project, fragment.platformType))
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun configureApiElementsConfiguration(fragment: T, configuration: Configuration) {
|
||||||
|
setPlatformAttributesInConfiguration(fragment, configuration)
|
||||||
|
configuration.attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(project, fragment.platformType))
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract fun configureKotlinCompilation(fragment: T)
|
||||||
|
|
||||||
|
open fun createSourcesArchiveTask(fragment: T) {
|
||||||
|
sourcesJarTask(
|
||||||
|
project,
|
||||||
|
lazy { fragment.refinesClosure.associate { it.disambiguateName("") to project.files(it.kotlinSourceRoots) } },
|
||||||
|
fragment.name,
|
||||||
|
fragment.name.toLowerCase()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createDependencyConfigurations(fragment: T) {
|
||||||
|
super.createDependencyConfigurations(fragment)
|
||||||
|
|
||||||
|
fragment.compileDependencyFiles = project.configurations.create(fragment.compileDependencyConfigurationName).apply {
|
||||||
|
isCanBeConsumed = false
|
||||||
|
isCanBeResolved = true
|
||||||
|
configureCompileResolvableConfiguration(fragment, this@apply)
|
||||||
|
project.addExtendsFromRelation(name, fragment.transitiveApiConfigurationName)
|
||||||
|
project.addExtendsFromRelation(name, fragment.transitiveImplementationConfigurationName)
|
||||||
|
}
|
||||||
|
// FIXME runtime classpath if supported
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun createElementsConfigurations(fragment: T) {
|
||||||
|
project.configurations.maybeCreate(fragment.apiElementsConfigurationName).apply {
|
||||||
|
isCanBeResolved = false
|
||||||
|
isCanBeConsumed = false
|
||||||
|
module.ifMadePublic {
|
||||||
|
isCanBeConsumed = true
|
||||||
|
// FIXME set capability
|
||||||
|
}
|
||||||
|
attributes.attribute<Usage>(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(project, fragment.platformType))
|
||||||
|
extendsFrom(project.configurations.getByName(fragment.transitiveApiConfigurationName))
|
||||||
|
// FIXME + compileOnly
|
||||||
|
configureApiElementsConfiguration(fragment, this@apply)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class AbstractKotlinGradleVariantWithRuntimeDependenciesFactory<T : KotlinGradleVariantWithRuntimeDependencies>(module: KotlinGradleModule) :
|
||||||
|
AbstractKotlinGradleVariantFactory<T>(module) {
|
||||||
|
|
||||||
|
open fun configureRuntimeResolvableConfiguration(fragment: T, configuration: Configuration) {
|
||||||
|
setPlatformAttributesInConfiguration(fragment, configuration)
|
||||||
|
configuration.attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerRuntimeUsage(project, fragment.platformType))
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun configureRuntimeElementsConfiguration(fragment: T, configuration: Configuration) {
|
||||||
|
setPlatformAttributesInConfiguration(fragment, configuration)
|
||||||
|
configuration.attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerRuntimeUsage(project, fragment.platformType))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createDependencyConfigurations(fragment: T) {
|
||||||
|
super.createDependencyConfigurations(fragment)
|
||||||
|
|
||||||
|
fragment.runtimeDependencyFiles = project.configurations.create(fragment.runtimeDependencyConfigurationName).apply {
|
||||||
|
isCanBeConsumed = false
|
||||||
|
isCanBeResolved = true
|
||||||
|
configureCompileResolvableConfiguration(fragment, this@apply)
|
||||||
|
project.addExtendsFromRelation(name, fragment.transitiveApiConfigurationName)
|
||||||
|
project.addExtendsFromRelation(name, fragment.transitiveImplementationConfigurationName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createElementsConfigurations(fragment: T) {
|
||||||
|
super.createElementsConfigurations(fragment)
|
||||||
|
|
||||||
|
project.configurations.maybeCreate(fragment.runtimeElementsConfigurationName).apply {
|
||||||
|
isCanBeResolved = false
|
||||||
|
isCanBeConsumed = false
|
||||||
|
module.ifMadePublic {
|
||||||
|
isCanBeConsumed = true
|
||||||
|
// FIXME set capability
|
||||||
|
}
|
||||||
|
configureRuntimeElementsConfiguration(fragment, this@apply)
|
||||||
|
extendsFrom(project.configurations.getByName(fragment.transitiveApiConfigurationName))
|
||||||
|
extendsFrom(project.configurations.getByName(fragment.transitiveImplementationConfigurationName))
|
||||||
|
// FIXME + runtimeOnly
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+74
@@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* 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.plugin.mpp.pm20
|
||||||
|
|
||||||
|
import org.gradle.api.file.ConfigurableFileCollection
|
||||||
|
import org.gradle.api.file.FileCollection
|
||||||
|
import org.gradle.api.tasks.TaskProvider
|
||||||
|
import org.gradle.api.tasks.bundling.AbstractArchiveTask
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationOutput
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.DefaultKotlinCompilationOutput
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.fromPlatform
|
||||||
|
import org.jetbrains.kotlin.gradle.tasks.withType
|
||||||
|
import org.jetbrains.kotlin.project.model.KotlinAttributeKey
|
||||||
|
import org.jetbrains.kotlin.project.model.KotlinModuleVariant
|
||||||
|
import org.jetbrains.kotlin.project.model.KotlinPlatformTypeAttribute
|
||||||
|
|
||||||
|
abstract class KotlinGradleVariant(
|
||||||
|
containingModule: KotlinGradleModule,
|
||||||
|
override val fragmentName: String
|
||||||
|
) : KotlinGradleFragment(containingModule, fragmentName), KotlinModuleVariant {
|
||||||
|
|
||||||
|
abstract val platformType: KotlinPlatformType
|
||||||
|
|
||||||
|
override val variantAttributes: Map<KotlinAttributeKey, String>
|
||||||
|
get() = mapOf(KotlinPlatformTypeAttribute to KotlinPlatformTypeAttribute.fromPlatform(platformType)) // TODO user attributes
|
||||||
|
|
||||||
|
// TODO generalize with KotlinCompilation?
|
||||||
|
val compileDependencyConfigurationName: String
|
||||||
|
get() = disambiguateName("CompileDependencies")
|
||||||
|
|
||||||
|
open lateinit var compileDependencyFiles: FileCollection
|
||||||
|
|
||||||
|
// TODO rewrite using our own artifacts API?
|
||||||
|
val compilationOutputs: KotlinCompilationOutput =
|
||||||
|
DefaultKotlinCompilationOutput(
|
||||||
|
project,
|
||||||
|
project.provider { project.buildDir.resolve("processedResources/${containingModule.name}/${fragmentName}") }
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO rewrite using our own artifacts API
|
||||||
|
open val sourceArchiveTask: TaskProvider<AbstractArchiveTask>
|
||||||
|
get() = project.tasks.withType<AbstractArchiveTask>().named(defaultSourceArtifactTaskName)
|
||||||
|
|
||||||
|
// TODO generalize exposing outputs: what if a variant has more than one such configurations or none?
|
||||||
|
val apiElementsConfigurationName: String
|
||||||
|
get() = disambiguateName("apiElements")
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: rewrite with the artifacts API
|
||||||
|
internal val KotlinGradleVariant.defaultSourceArtifactTaskName: String
|
||||||
|
get() = disambiguateName("sourcesJar")
|
||||||
|
|
||||||
|
abstract class KotlinGradleVariantWithRuntimeDependencies(
|
||||||
|
containingModule: KotlinGradleModule,
|
||||||
|
fragmentName: String
|
||||||
|
) : KotlinGradleVariant(containingModule, fragmentName) {
|
||||||
|
// TODO deduplicate with KotlinCompilation?
|
||||||
|
val runtimeDependencyConfigurationName: String
|
||||||
|
get() = disambiguateName("RuntimeDependencies")
|
||||||
|
|
||||||
|
open lateinit var runtimeDependencyFiles: FileCollection
|
||||||
|
|
||||||
|
open val runtimeFiles: ConfigurableFileCollection by lazy {
|
||||||
|
project.files(compilationOutputs.allOutputs, runtimeDependencyFiles)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO generalize exposing outputs: what if a variant has more than one such configurations or none?
|
||||||
|
val runtimeElementsConfigurationName: String
|
||||||
|
get() = disambiguateName("runtimeElements")
|
||||||
|
}
|
||||||
+66
@@ -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.plugin.mpp.pm20
|
||||||
|
|
||||||
|
import org.gradle.api.NamedDomainObjectFactory
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.sources.METADATA_CONFIGURATION_NAME_SUFFIX
|
||||||
|
import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation
|
||||||
|
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||||
|
import org.jetbrains.kotlin.project.model.KotlinModuleFragment
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
abstract class AbstractKotlinGradleFragmentFactory<T : KotlinGradleFragment>(
|
||||||
|
protected val module: KotlinGradleModule
|
||||||
|
) : NamedDomainObjectFactory<T> {
|
||||||
|
|
||||||
|
protected val project: Project
|
||||||
|
get() = module.project
|
||||||
|
|
||||||
|
abstract fun instantiateFragment(name: String): T
|
||||||
|
|
||||||
|
override fun create(name: String): T =
|
||||||
|
instantiateFragment(name).apply {
|
||||||
|
createDependencyConfigurations(this)
|
||||||
|
addDefaultSourceDirectories(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun createDependencyConfigurations(fragment: T) {
|
||||||
|
with(project.configurations) {
|
||||||
|
fragment.relatedConfigurationNames.forEach { configurationName ->
|
||||||
|
maybeCreate(configurationName).apply {
|
||||||
|
// FIXME add metadata configurations?
|
||||||
|
if (!configurationName.endsWith(METADATA_CONFIGURATION_NAME_SUFFIX)) {
|
||||||
|
isCanBeResolved = false
|
||||||
|
}
|
||||||
|
isCanBeConsumed = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
listOf(
|
||||||
|
fragment.apiConfigurationName to fragment.transitiveApiConfigurationName,
|
||||||
|
fragment.implementationConfigurationName to fragment.transitiveImplementationConfigurationName
|
||||||
|
).forEach { (configuration, transitiveConfiguration) ->
|
||||||
|
project.addExtendsFromRelation(transitiveConfiguration, configuration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun addDefaultSourceDirectories(fragment: KotlinGradleFragment) {
|
||||||
|
fragment.kotlinSourceRoots.srcDir(defaultSourceFolder(project, module.name, fragment.fragmentName, "kotlin"))
|
||||||
|
// TODO handle resources
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun defaultSourceFolder(project: Project, moduleName: String, fragmentName: String, type: String): File {
|
||||||
|
return project.file("src/${lowerCamelCaseName(fragmentName, moduleName)}/$type")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CommonGradleFragmentFactory(module: KotlinGradleModule) : AbstractKotlinGradleFragmentFactory<KotlinGradleFragment>(module) {
|
||||||
|
override fun instantiateFragment(name: String): KotlinGradleFragment =
|
||||||
|
project.objects.newInstance(KotlinGradleFragment::class.java, module, name)
|
||||||
|
}
|
||||||
+86
@@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* 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.plugin.mpp.pm20
|
||||||
|
|
||||||
|
import org.gradle.api.*
|
||||||
|
import org.gradle.api.file.FileCollection
|
||||||
|
import org.gradle.api.file.SourceDirectorySet
|
||||||
|
import org.gradle.api.plugins.BasePluginConvention
|
||||||
|
import org.gradle.api.tasks.TaskProvider
|
||||||
|
import org.gradle.jvm.tasks.Jar
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.pm20Extension
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.*
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
||||||
|
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
|
||||||
|
import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask
|
||||||
|
import org.jetbrains.kotlin.gradle.utils.dashSeparatedName
|
||||||
|
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||||
|
import org.jetbrains.kotlin.project.model.*
|
||||||
|
import org.jetbrains.kotlin.project.model.utils.variantsContainingFragment
|
||||||
|
import java.util.concurrent.Callable
|
||||||
|
|
||||||
|
//region Fragment
|
||||||
|
|
||||||
|
//endregion Fragment
|
||||||
|
|
||||||
|
//region Variant
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
open class KotlinJvmVariantFactory(module: KotlinGradleModule) :
|
||||||
|
AbstractKotlinGradleVariantWithRuntimeDependenciesFactory<KotlinJvmVariant>(module) {
|
||||||
|
override fun instantiateFragment(name: String) = KotlinJvmVariant(module, name)
|
||||||
|
|
||||||
|
// FIXME expose the JAR with the artifacts API
|
||||||
|
private fun getOrCreateJarTask(fragment: KotlinJvmVariant): TaskProvider<Jar> {
|
||||||
|
val jarTaskName = fragment.disambiguateName("jar")
|
||||||
|
return project.locateOrRegisterTask(jarTaskName) {
|
||||||
|
it.from(fragment.compilationOutputs.allOutputs)
|
||||||
|
it.archiveClassifier.set(dashSeparatedName(fragment.name, module.moduleClassifier))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createElementsConfigurations(fragment: KotlinJvmVariant) {
|
||||||
|
super.createElementsConfigurations(fragment)
|
||||||
|
listOf(fragment.apiElementsConfigurationName, fragment.runtimeElementsConfigurationName).forEach {
|
||||||
|
project.artifacts.add(it, getOrCreateJarTask(fragment))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun configureKotlinCompilation(fragment: KotlinJvmVariant) {
|
||||||
|
val compilationData = KotlinJvmVariantCompilationData(fragment)
|
||||||
|
|
||||||
|
val classesTaskName = compilationData.compileAllTaskName
|
||||||
|
project.tasks.register(classesTaskName) { classesTask ->
|
||||||
|
classesTask.dependsOn(fragment.compilationOutputs.allOutputs)
|
||||||
|
}
|
||||||
|
|
||||||
|
Kotlin2JvmSourceSetProcessor(KotlinTasksProvider(), compilationData, project.getKotlinPluginVersion() ?: "unknown"/*TODO*/).run()
|
||||||
|
|
||||||
|
val allSources = { project.files(Callable { fragment.refinesClosure.map { it.kotlinSourceRoots } }) }
|
||||||
|
val commonSources = {
|
||||||
|
project.files(Callable {
|
||||||
|
fragment.refinesClosure.filter { module.variantsContainingFragment(it).count() > 1 }.map { it.kotlinSourceRoots }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
addSourcesToKotlinCompileTask(
|
||||||
|
project, compilationData.compileKotlinTaskName, /*FIXME*/ emptyList(), allSources,
|
||||||
|
addAsCommonSources = lazyOf(false)
|
||||||
|
)
|
||||||
|
addSourcesToKotlinCompileTask(
|
||||||
|
project, compilationData.compileKotlinTaskName, /*FIXME*/ emptyList(), commonSources,
|
||||||
|
addAsCommonSources = lazyOf(true)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//endregion Variant
|
||||||
+35
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* 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.plugin.mpp.pm20.util
|
||||||
|
|
||||||
|
import org.gradle.api.capabilities.Capability
|
||||||
|
import org.gradle.api.provider.Provider
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinGradleModule
|
||||||
|
|
||||||
|
internal class LazyCapability(
|
||||||
|
val groupProvider: Provider<String>,
|
||||||
|
val nameValue: String,
|
||||||
|
val versionProvider: Provider<String>,
|
||||||
|
val suffix: String?
|
||||||
|
) : Capability {
|
||||||
|
override fun getGroup(): String = groupProvider.get()
|
||||||
|
|
||||||
|
override fun getName(): String = nameValue + suffix?.let { "..$it" }.orEmpty()
|
||||||
|
|
||||||
|
override fun getVersion(): String? = versionProvider.get()
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun fromModule(module: KotlinGradleModule): LazyCapability {
|
||||||
|
val project = module.project
|
||||||
|
return LazyCapability(
|
||||||
|
project.provider { project.group.toString() },
|
||||||
|
project.name,
|
||||||
|
project.provider { project.version.toString() },
|
||||||
|
module.moduleClassifier
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-1
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.gradle.plugin.sources
|
|||||||
|
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.artifacts.Configuration
|
import org.gradle.api.artifacts.Configuration
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.HasKotlinDependencies
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||||
import org.jetbrains.kotlin.gradle.plugin.sources.KotlinDependencyScope.*
|
import org.jetbrains.kotlin.gradle.plugin.sources.KotlinDependencyScope.*
|
||||||
@@ -26,7 +27,7 @@ internal enum class KotlinDependencyScope(val scopeName: String) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun Project.sourceSetDependencyConfigurationByScope(sourceSet: KotlinSourceSet, scope: KotlinDependencyScope): Configuration =
|
internal fun Project.sourceSetDependencyConfigurationByScope(sourceSet: HasKotlinDependencies, scope: KotlinDependencyScope): Configuration =
|
||||||
project.configurations.getByName(
|
project.configurations.getByName(
|
||||||
when (scope) {
|
when (scope) {
|
||||||
API_SCOPE -> sourceSet.apiConfigurationName
|
API_SCOPE -> sourceSet.apiConfigurationName
|
||||||
|
|||||||
+2
-2
@@ -99,7 +99,7 @@ open class KotlinJsCompilation(
|
|||||||
private fun disambiguateNameInPlatform(simpleName: String): String {
|
private fun disambiguateNameInPlatform(simpleName: String): String {
|
||||||
return lowerCamelCaseName(
|
return lowerCamelCaseName(
|
||||||
disambiguationClassifierInPlatform,
|
disambiguationClassifierInPlatform,
|
||||||
compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME },
|
compilationPurpose.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME },
|
||||||
simpleName
|
simpleName
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -111,7 +111,7 @@ open class KotlinJsCompilation(
|
|||||||
target.irTarget?.let {
|
target.irTarget?.let {
|
||||||
target.disambiguationClassifierInPlatform
|
target.disambiguationClassifierInPlatform
|
||||||
} ?: target.disambiguationClassifier,
|
} ?: target.disambiguationClassifier,
|
||||||
compilationName
|
compilationPurpose
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -50,7 +50,7 @@ open class KotlinJsTargetConfigurator(kotlinPluginVersion: String) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun buildCompilationProcessor(compilation: KotlinJsCompilation): KotlinSourceSetProcessor<*> {
|
override fun buildCompilationProcessor(compilation: KotlinJsCompilation): KotlinSourceSetProcessor<*> {
|
||||||
val tasksProvider = KotlinTasksProvider(compilation.target.targetName)
|
val tasksProvider = KotlinTasksProvider()
|
||||||
return Kotlin2JsSourceSetProcessor(tasksProvider, compilation, kotlinPluginVersion)
|
return Kotlin2JsSourceSetProcessor(tasksProvider, compilation, kotlinPluginVersion)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -36,7 +36,7 @@ class KotlinJsIrCompilation(
|
|||||||
target.disambiguationClassifierInPlatform
|
target.disambiguationClassifierInPlatform
|
||||||
else
|
else
|
||||||
target.disambiguationClassifier,
|
target.disambiguationClassifier,
|
||||||
compilationName
|
compilationPurpose
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -54,7 +54,7 @@ open class KotlinJsIrTargetConfigurator(kotlinPluginVersion: String) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun buildCompilationProcessor(compilation: KotlinJsIrCompilation): KotlinSourceSetProcessor<*> {
|
override fun buildCompilationProcessor(compilation: KotlinJsIrCompilation): KotlinSourceSetProcessor<*> {
|
||||||
val tasksProvider = KotlinTasksProvider(compilation.target.targetName)
|
val tasksProvider = KotlinTasksProvider()
|
||||||
return KotlinJsIrSourceSetProcessor(tasksProvider, compilation, kotlinPluginVersion)
|
return KotlinJsIrSourceSetProcessor(tasksProvider, compilation, kotlinPluginVersion)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -93,7 +93,7 @@ constructor(
|
|||||||
val compilationId: String by lazy {
|
val compilationId: String by lazy {
|
||||||
compilation.let {
|
compilation.let {
|
||||||
val target = it.target
|
val target = it.target
|
||||||
target.project.path + "@" + target.name + ":" + it.compilationName
|
target.project.path + "@" + target.name + ":" + it.compilationPurpose
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -62,7 +62,7 @@ constructor(
|
|||||||
val compilationId: String by lazy {
|
val compilationId: String by lazy {
|
||||||
compilation.let {
|
compilation.let {
|
||||||
val target = it.target
|
val target = it.target
|
||||||
target.project.path + "@" + target.name + ":" + it.compilationName
|
target.project.path + "@" + target.name + ":" + it.compilationPurpose
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -35,7 +35,7 @@ open class KotlinJvmCompilation(
|
|||||||
get() = if (target.withJavaEnabled) {
|
get() = if (target.withJavaEnabled) {
|
||||||
val project = target.project
|
val project = target.project
|
||||||
val javaSourceSets = project.convention.getPlugin(JavaPluginConvention::class.java).sourceSets
|
val javaSourceSets = project.convention.getPlugin(JavaPluginConvention::class.java).sourceSets
|
||||||
val javaSourceSet = javaSourceSets.getByName(compilationName)
|
val javaSourceSet = javaSourceSets.getByName(compilationPurpose)
|
||||||
project.tasks.withType(JavaCompile::class.java).named(javaSourceSet.compileJavaTaskName)
|
project.tasks.withType(JavaCompile::class.java).named(javaSourceSet.compileJavaTaskName)
|
||||||
} else null
|
} else null
|
||||||
}
|
}
|
||||||
+1
-1
@@ -73,7 +73,7 @@ class KotlinJvmTargetConfigurator(kotlinPluginVersion: String) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun buildCompilationProcessor(compilation: KotlinJvmCompilation): KotlinSourceSetProcessor<*> {
|
override fun buildCompilationProcessor(compilation: KotlinJvmCompilation): KotlinSourceSetProcessor<*> {
|
||||||
val tasksProvider = KotlinTasksProvider(compilation.target.targetName)
|
val tasksProvider = KotlinTasksProvider()
|
||||||
return Kotlin2JvmSourceSetProcessor(tasksProvider, compilation, kotlinPluginVersion)
|
return Kotlin2JvmSourceSetProcessor(tasksProvider, compilation, kotlinPluginVersion)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -36,7 +36,7 @@ class KotlinJvmWithJavaTargetPreset(
|
|||||||
}
|
}
|
||||||
|
|
||||||
AbstractKotlinPlugin.configureTarget(target) { compilation ->
|
AbstractKotlinPlugin.configureTarget(target) { compilation ->
|
||||||
Kotlin2JvmSourceSetProcessor(KotlinTasksProvider(name), compilation, kotlinPluginVersion)
|
Kotlin2JvmSourceSetProcessor(KotlinTasksProvider(), compilation, kotlinPluginVersion)
|
||||||
}
|
}
|
||||||
|
|
||||||
target.compilations.getByName("test").run {
|
target.compilations.getByName("test").run {
|
||||||
|
|||||||
+1
-1
@@ -110,7 +110,7 @@ class KotlinMetadataTargetConfigurator(kotlinPluginVersion: String) :
|
|||||||
|
|
||||||
override fun buildCompilationProcessor(compilation: AbstractKotlinCompilation<*>): KotlinCompilationProcessor<*> = when (compilation) {
|
override fun buildCompilationProcessor(compilation: AbstractKotlinCompilation<*>): KotlinCompilationProcessor<*> = when (compilation) {
|
||||||
is KotlinCommonCompilation -> {
|
is KotlinCommonCompilation -> {
|
||||||
val tasksProvider = KotlinTasksProvider(compilation.target.targetName)
|
val tasksProvider = KotlinTasksProvider()
|
||||||
KotlinCommonSourceSetProcessor(compilation, tasksProvider, kotlinPluginVersion)
|
KotlinCommonSourceSetProcessor(compilation, tasksProvider, kotlinPluginVersion)
|
||||||
}
|
}
|
||||||
is KotlinSharedNativeCompilation -> NativeSharedCompilationProcessor(compilation)
|
is KotlinSharedNativeCompilation -> NativeSharedCompilationProcessor(compilation)
|
||||||
|
|||||||
+1
-1
@@ -57,7 +57,7 @@ open class DefaultCInteropSettings @Inject constructor(
|
|||||||
val interopProcessingTaskName: String
|
val interopProcessingTaskName: String
|
||||||
get() = lowerCamelCaseName(
|
get() = lowerCamelCaseName(
|
||||||
"cinterop",
|
"cinterop",
|
||||||
compilation.compilationName.takeIf { it != "main" }.orEmpty(),
|
compilation.compilationPurpose.takeIf { it != "main" }.orEmpty(),
|
||||||
name,
|
name,
|
||||||
target.disambiguationClassifier
|
target.disambiguationClassifier
|
||||||
)
|
)
|
||||||
|
|||||||
+3
-7
@@ -9,7 +9,6 @@ package org.jetbrains.kotlin.gradle.plugin.mpp
|
|||||||
import groovy.lang.Closure
|
import groovy.lang.Closure
|
||||||
import org.gradle.api.Action
|
import org.gradle.api.Action
|
||||||
import org.gradle.api.NamedDomainObjectContainer
|
import org.gradle.api.NamedDomainObjectContainer
|
||||||
import org.gradle.api.Project
|
|
||||||
import org.gradle.api.file.FileCollection
|
import org.gradle.api.file.FileCollection
|
||||||
import org.gradle.api.tasks.TaskProvider
|
import org.gradle.api.tasks.TaskProvider
|
||||||
import org.gradle.util.ConfigureUtil
|
import org.gradle.util.ConfigureUtil
|
||||||
@@ -77,9 +76,6 @@ class KotlinNativeCompilation(
|
|||||||
) : AbstractKotlinNativeCompilation(target, konanTarget, name),
|
) : AbstractKotlinNativeCompilation(target, konanTarget, name),
|
||||||
KotlinCompilationWithResources<KotlinCommonOptions> {
|
KotlinCompilationWithResources<KotlinCommonOptions> {
|
||||||
|
|
||||||
private val project: Project
|
|
||||||
get() = target.project
|
|
||||||
|
|
||||||
// Interop DSL.
|
// Interop DSL.
|
||||||
val cinterops = project.container(DefaultCInteropSettings::class.java) { cinteropName ->
|
val cinterops = project.container(DefaultCInteropSettings::class.java) { cinteropName ->
|
||||||
DefaultCInteropSettings(project, cinteropName, this)
|
DefaultCInteropSettings(project, cinteropName, this)
|
||||||
@@ -95,15 +91,15 @@ class KotlinNativeCompilation(
|
|||||||
override val compileDependencyConfigurationName: String
|
override val compileDependencyConfigurationName: String
|
||||||
get() = lowerCamelCaseName(
|
get() = lowerCamelCaseName(
|
||||||
target.disambiguationClassifier,
|
target.disambiguationClassifier,
|
||||||
compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }.orEmpty(),
|
compilationPurpose.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }.orEmpty(),
|
||||||
"compileKlibraries"
|
"compileKlibraries"
|
||||||
)
|
)
|
||||||
|
|
||||||
override val compileAllTaskName: String
|
override val compileAllTaskName: String
|
||||||
get() = lowerCamelCaseName(target.disambiguationClassifier, compilationName, "klibrary")
|
get() = lowerCamelCaseName(target.disambiguationClassifier, compilationPurpose, "klibrary")
|
||||||
|
|
||||||
val binariesTaskName: String
|
val binariesTaskName: String
|
||||||
get() = lowerCamelCaseName(target.disambiguationClassifier, compilationName, "binaries")
|
get() = lowerCamelCaseName(target.disambiguationClassifier, compilationPurpose, "binaries")
|
||||||
|
|
||||||
override fun addAssociateCompilationDependencies(other: KotlinCompilation<*>) {
|
override fun addAssociateCompilationDependencies(other: KotlinCompilation<*>) {
|
||||||
with(target.project) {
|
with(target.project) {
|
||||||
|
|||||||
+16
-8
@@ -30,7 +30,9 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformCommonOptionsImpl
|
|||||||
import org.jetbrains.kotlin.gradle.dsl.fillDefaultValues
|
import org.jetbrains.kotlin.gradle.dsl.fillDefaultValues
|
||||||
import org.jetbrains.kotlin.gradle.internal.tasks.allOutputFiles
|
import org.jetbrains.kotlin.gradle.internal.tasks.allOutputFiles
|
||||||
import org.jetbrains.kotlin.gradle.logging.GradlePrintingMessageCollector
|
import org.jetbrains.kotlin.gradle.logging.GradlePrintingMessageCollector
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinCommonCompilation
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinCommonCompilation
|
||||||
import org.jetbrains.kotlin.gradle.utils.getValue
|
import org.jetbrains.kotlin.gradle.utils.getValue
|
||||||
import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllDependsOnSourceSets
|
import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllDependsOnSourceSets
|
||||||
@@ -78,19 +80,25 @@ open class KotlinCompileCommon : AbstractKotlinCompile<K2MetadataCompilerArgumen
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun outputPathsFromMetadataCompilationsOf(sourceSets: Iterable<KotlinSourceSet>): List<File> {
|
private fun outputPathsFromMetadataCompilationsOf(sourceSets: Iterable<KotlinSourceSet>): List<File> {
|
||||||
val target = taskData.compilation.target
|
val target = taskData.compilation.owner
|
||||||
return sourceSets
|
return when (target) {
|
||||||
.mapNotNull { sourceSet -> target.compilations.findByName(sourceSet.name)?.output?.classesDirs }
|
is KotlinTarget -> sourceSets
|
||||||
.flatten()
|
.mapNotNull { sourceSet -> target.compilations.findByName(sourceSet.name)?.output?.classesDirs }
|
||||||
|
.flatten()
|
||||||
|
else -> error("unexpected compilation owner") // FIXME support PM20 variant
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val defaultKotlinSourceSet: KotlinSourceSet
|
|
||||||
get() = taskData.compilation.defaultSourceSet
|
|
||||||
|
|
||||||
@get:PathSensitive(PathSensitivity.RELATIVE)
|
@get:PathSensitive(PathSensitivity.RELATIVE)
|
||||||
@get:InputFiles
|
@get:InputFiles
|
||||||
internal val refinesMetadataPaths by project.provider {
|
internal val refinesMetadataPaths by project.provider {
|
||||||
outputPathsFromMetadataCompilationsOf(defaultKotlinSourceSet.resolveAllDependsOnSourceSets())
|
when (val compilation = taskData.compilation) {
|
||||||
|
is KotlinCompilation<*> -> {
|
||||||
|
val defaultKotlinSourceSet: KotlinSourceSet = compilation.defaultSourceSet
|
||||||
|
outputPathsFromMetadataCompilationsOf(defaultKotlinSourceSet.resolveAllDependsOnSourceSets())
|
||||||
|
}
|
||||||
|
else -> error("unexpected compilation type") // FIXME support PM20 variant
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun callCompilerAsync(args: K2MetadataCompilerArguments, sourceRoots: SourceRoots, changedFiles: ChangedFiles) {
|
override fun callCompilerAsync(args: K2MetadataCompilerArguments, sourceRoots: SourceRoots, changedFiles: ChangedFiles) {
|
||||||
|
|||||||
+9
-6
@@ -42,7 +42,6 @@ import org.jetbrains.kotlin.gradle.plugin.*
|
|||||||
import org.jetbrains.kotlin.gradle.plugin.COMPILER_CLASSPATH_CONFIGURATION_NAME
|
import org.jetbrains.kotlin.gradle.plugin.COMPILER_CLASSPATH_CONFIGURATION_NAME
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinCompilation
|
import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinCompilation
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.associateWithTransitiveClosure
|
import org.jetbrains.kotlin.gradle.plugin.mpp.associateWithTransitiveClosure
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.ownModuleName
|
|
||||||
import org.jetbrains.kotlin.gradle.report.ReportingSettings
|
import org.jetbrains.kotlin.gradle.report.ReportingSettings
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.ir.isProduceUnzippedKlib
|
import org.jetbrains.kotlin.gradle.targets.js.ir.isProduceUnzippedKlib
|
||||||
import org.jetbrains.kotlin.gradle.utils.*
|
import org.jetbrains.kotlin.gradle.utils.*
|
||||||
@@ -216,7 +215,9 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractKo
|
|||||||
@get:InputFiles
|
@get:InputFiles
|
||||||
@get:Classpath
|
@get:Classpath
|
||||||
open val pluginClasspath: FileCollection by project.provider {
|
open val pluginClasspath: FileCollection by project.provider {
|
||||||
project.configurations.getByName(taskData.compilation.pluginConfigurationName)
|
// FIXME support compiler plugins with PM20
|
||||||
|
(taskData.compilation as? KotlinCompilation<*>?)?.pluginConfigurationName?.let(project.configurations::getByName)
|
||||||
|
?: project.files()
|
||||||
}
|
}
|
||||||
|
|
||||||
@get:Internal
|
@get:Internal
|
||||||
@@ -253,7 +254,7 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractKo
|
|||||||
|
|
||||||
@get:Internal
|
@get:Internal
|
||||||
@field:Transient
|
@field:Transient
|
||||||
internal val kotlinExtProvider: KotlinProjectExtension = project.extensions.findByType(KotlinProjectExtension::class.java)!!
|
internal val kotlinExtProvider: KotlinTopLevelExtension = project.extensions.findByType(KotlinTopLevelExtension::class.java)!!
|
||||||
|
|
||||||
override fun getDestinationDir(): File =
|
override fun getDestinationDir(): File =
|
||||||
taskData.destinationDir.get()
|
taskData.destinationDir.get()
|
||||||
@@ -293,7 +294,7 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractKo
|
|||||||
|
|
||||||
@get:Internal
|
@get:Internal
|
||||||
internal val sourceSetName: String
|
internal val sourceSetName: String
|
||||||
get() = taskData.compilation.name
|
get() = taskData.compilation.compilationPurpose
|
||||||
|
|
||||||
@get:InputFiles
|
@get:InputFiles
|
||||||
@get:PathSensitive(PathSensitivity.RELATIVE)
|
@get:PathSensitive(PathSensitivity.RELATIVE)
|
||||||
@@ -308,7 +309,7 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractKo
|
|||||||
val friendPaths: FileCollection = project.files(
|
val friendPaths: FileCollection = project.files(
|
||||||
project.provider {
|
project.provider {
|
||||||
taskData.compilation.run {
|
taskData.compilation.run {
|
||||||
if (this !is AbstractKotlinCompilation<*>) return@run project.files()
|
if (this !is AbstractKotlinCompilation<*>) return@run project.files() // FIXME support PM20
|
||||||
mutableListOf<FileCollection>().also { allCollections ->
|
mutableListOf<FileCollection>().also { allCollections ->
|
||||||
associateWithTransitiveClosure.forEach { allCollections.add(it.output.classesDirs) }
|
associateWithTransitiveClosure.forEach { allCollections.add(it.output.classesDirs) }
|
||||||
allCollections.add(friendArtifacts)
|
allCollections.add(friendArtifacts)
|
||||||
@@ -398,7 +399,9 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractKo
|
|||||||
internal abstract fun callCompilerAsync(args: T, sourceRoots: SourceRoots, changedFiles: ChangedFiles)
|
internal abstract fun callCompilerAsync(args: T, sourceRoots: SourceRoots, changedFiles: ChangedFiles)
|
||||||
|
|
||||||
@get:Input
|
@get:Input
|
||||||
internal val isMultiplatform: Boolean by lazy { project.plugins.any { it is KotlinPlatformPluginBase || it is KotlinMultiplatformPluginWrapper } }
|
internal val isMultiplatform: Boolean by lazy {
|
||||||
|
project.plugins.any { it is KotlinPlatformPluginBase || it is KotlinMultiplatformPluginWrapper || it is KotlinPm20PluginWrapper }
|
||||||
|
}
|
||||||
|
|
||||||
@get:Internal
|
@get:Internal
|
||||||
internal val abstractKotlinCompileArgumentsContributor by lazy {
|
internal val abstractKotlinCompileArgumentsContributor by lazy {
|
||||||
|
|||||||
+10
-9
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
|||||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
|
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mapKotlinTaskProperties
|
import org.jetbrains.kotlin.gradle.plugin.mapKotlinTaskProperties
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinCompilation
|
import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinCompilation
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData
|
||||||
import org.jetbrains.kotlin.gradle.plugin.runOnceAfterEvaluated
|
import org.jetbrains.kotlin.gradle.plugin.runOnceAfterEvaluated
|
||||||
import org.jetbrains.kotlin.gradle.plugin.sources.applyLanguageSettingsToKotlinOptions
|
import org.jetbrains.kotlin.gradle.plugin.sources.applyLanguageSettingsToKotlinOptions
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrLink
|
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrLink
|
||||||
@@ -80,11 +81,11 @@ internal inline fun <reified T : Task> Project.locateOrRegisterTask(name: String
|
|||||||
return project.locateTask(name) ?: project.registerTask(name, T::class.java, body = body)
|
return project.locateTask(name) ?: project.registerTask(name, T::class.java, body = body)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal open class KotlinTasksProvider(val targetName: String) {
|
internal open class KotlinTasksProvider {
|
||||||
open fun registerKotlinJVMTask(
|
open fun registerKotlinJVMTask(
|
||||||
project: Project,
|
project: Project,
|
||||||
name: String,
|
name: String,
|
||||||
compilation: KotlinCompilation<*>,
|
compilation: KotlinCompilationData<*>,
|
||||||
configureAction: (KotlinCompile) -> (Unit)
|
configureAction: (KotlinCompile) -> (Unit)
|
||||||
): TaskProvider<out KotlinCompile> {
|
): TaskProvider<out KotlinCompile> {
|
||||||
val properties = PropertiesProvider(project)
|
val properties = PropertiesProvider(project)
|
||||||
@@ -99,7 +100,7 @@ internal open class KotlinTasksProvider(val targetName: String) {
|
|||||||
fun registerKotlinJSTask(
|
fun registerKotlinJSTask(
|
||||||
project: Project,
|
project: Project,
|
||||||
name: String,
|
name: String,
|
||||||
compilation: KotlinCompilation<*>,
|
compilation: KotlinCompilationData<*>,
|
||||||
configureAction: (Kotlin2JsCompile) -> Unit
|
configureAction: (Kotlin2JsCompile) -> Unit
|
||||||
): TaskProvider<out Kotlin2JsCompile> {
|
): TaskProvider<out Kotlin2JsCompile> {
|
||||||
val properties = PropertiesProvider(project)
|
val properties = PropertiesProvider(project)
|
||||||
@@ -114,7 +115,7 @@ internal open class KotlinTasksProvider(val targetName: String) {
|
|||||||
fun registerKotlinJsIrTask(
|
fun registerKotlinJsIrTask(
|
||||||
project: Project,
|
project: Project,
|
||||||
name: String,
|
name: String,
|
||||||
compilation: KotlinCompilation<*>,
|
compilation: KotlinCompilationData<*>,
|
||||||
configureAction: (KotlinJsIrLink) -> Unit
|
configureAction: (KotlinJsIrLink) -> Unit
|
||||||
): TaskProvider<out KotlinJsIrLink> {
|
): TaskProvider<out KotlinJsIrLink> {
|
||||||
val properties = PropertiesProvider(project)
|
val properties = PropertiesProvider(project)
|
||||||
@@ -129,7 +130,7 @@ internal open class KotlinTasksProvider(val targetName: String) {
|
|||||||
fun registerKotlinCommonTask(
|
fun registerKotlinCommonTask(
|
||||||
project: Project,
|
project: Project,
|
||||||
name: String,
|
name: String,
|
||||||
compilation: KotlinCompilation<*>,
|
compilation: KotlinCompilationData<*>,
|
||||||
configureAction: (KotlinCompileCommon) -> (Unit)
|
configureAction: (KotlinCompileCommon) -> (Unit)
|
||||||
): TaskProvider<out KotlinCompileCommon> {
|
): TaskProvider<out KotlinCompileCommon> {
|
||||||
val properties = PropertiesProvider(project)
|
val properties = PropertiesProvider(project)
|
||||||
@@ -145,13 +146,13 @@ internal open class KotlinTasksProvider(val targetName: String) {
|
|||||||
kotlinTaskHolder: TaskProvider<out AbstractKotlinCompile<*>>,
|
kotlinTaskHolder: TaskProvider<out AbstractKotlinCompile<*>>,
|
||||||
project: Project,
|
project: Project,
|
||||||
propertiesProvider: PropertiesProvider,
|
propertiesProvider: PropertiesProvider,
|
||||||
compilation: KotlinCompilation<*>
|
compilation: KotlinCompilationData<*>
|
||||||
) {
|
) {
|
||||||
project.runOnceAfterEvaluated("apply properties and language settings to ${kotlinTaskHolder.name}", kotlinTaskHolder) {
|
project.runOnceAfterEvaluated("apply properties and language settings to ${kotlinTaskHolder.name}", kotlinTaskHolder) {
|
||||||
propertiesProvider.mapKotlinTaskProperties(kotlinTaskHolder.get())
|
propertiesProvider.mapKotlinTaskProperties(kotlinTaskHolder.get())
|
||||||
|
|
||||||
applyLanguageSettingsToKotlinOptions(
|
applyLanguageSettingsToKotlinOptions(
|
||||||
compilation.defaultSourceSet.languageSettings,
|
compilation.languageSettings,
|
||||||
(kotlinTaskHolder.get() as org.jetbrains.kotlin.gradle.dsl.KotlinCompile<*>).kotlinOptions
|
(kotlinTaskHolder.get() as org.jetbrains.kotlin.gradle.dsl.KotlinCompile<*>).kotlinOptions
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -161,12 +162,12 @@ internal open class KotlinTasksProvider(val targetName: String) {
|
|||||||
if (properties.parallelTasksInProject != true) Task::class.java else WorkersTask::class.java
|
if (properties.parallelTasksInProject != true) Task::class.java else WorkersTask::class.java
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class AndroidTasksProvider(targetName: String) : KotlinTasksProvider(targetName) {
|
internal class AndroidTasksProvider : KotlinTasksProvider() {
|
||||||
override fun configure(
|
override fun configure(
|
||||||
kotlinTaskHolder: TaskProvider<out AbstractKotlinCompile<*>>,
|
kotlinTaskHolder: TaskProvider<out AbstractKotlinCompile<*>>,
|
||||||
project: Project,
|
project: Project,
|
||||||
propertiesProvider: PropertiesProvider,
|
propertiesProvider: PropertiesProvider,
|
||||||
compilation: KotlinCompilation<*>
|
compilation: KotlinCompilationData<*>
|
||||||
) {
|
) {
|
||||||
super.configure(kotlinTaskHolder, project, propertiesProvider, compilation)
|
super.configure(kotlinTaskHolder, project, propertiesProvider, compilation)
|
||||||
kotlinTaskHolder.configure {
|
kotlinTaskHolder.configure {
|
||||||
|
|||||||
+6
-5
@@ -10,21 +10,22 @@ import org.gradle.api.plugins.ExtraPropertiesExtension
|
|||||||
import org.gradle.api.provider.Property
|
import org.gradle.api.provider.Property
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinCompilation
|
import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinCompilation
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData
|
||||||
import org.jetbrains.kotlin.gradle.utils.getValue
|
import org.jetbrains.kotlin.gradle.utils.getValue
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
internal open class KotlinCompileTaskData(
|
internal open class KotlinCompileTaskData(
|
||||||
val taskName: String,
|
val taskName: String,
|
||||||
@field:Transient // cannot be serialized for Gradle Instant Execution, but actually is not needed when a task is deserialized
|
@field:Transient // cannot be serialized for Gradle Instant Execution, but actually is not needed when a task is deserialized
|
||||||
val compilation: KotlinCompilation<*>,
|
val compilation: KotlinCompilationData<*>,
|
||||||
val destinationDir: Property<File>,
|
val destinationDir: Property<File>,
|
||||||
val useModuleDetection: Property<Boolean>
|
val useModuleDetection: Property<Boolean>
|
||||||
) {
|
) {
|
||||||
private val project: Project
|
private val project: Project
|
||||||
get() = compilation.target.project
|
get() = compilation.project
|
||||||
|
|
||||||
private val taskBuildDirectory: File by project.provider {
|
private val taskBuildDirectory: File by project.provider {
|
||||||
File(File(compilation.target.project.buildDir, KOTLIN_BUILD_DIR_NAME), taskName)
|
File(File(compilation.project.buildDir, KOTLIN_BUILD_DIR_NAME), taskName)
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO
|
//TODO
|
||||||
@@ -42,9 +43,9 @@ internal open class KotlinCompileTaskData(
|
|||||||
|
|
||||||
fun register(
|
fun register(
|
||||||
taskName: String,
|
taskName: String,
|
||||||
compilation: KotlinCompilation<*>
|
compilation: KotlinCompilationData<*>
|
||||||
): KotlinCompileTaskData {
|
): KotlinCompileTaskData {
|
||||||
val project = compilation.target.project
|
val project = compilation.project
|
||||||
val container = project.getTaskDataMap()
|
val container = project.getTaskDataMap()
|
||||||
|
|
||||||
@Suppress("UnstableApiUsage")
|
@Suppress("UnstableApiUsage")
|
||||||
|
|||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
implementation-class=org.jetbrains.kotlin.gradle.plugin.KotlinPm20PluginWrapper
|
||||||
@@ -17,13 +17,12 @@ interface KotlinModuleFragment {
|
|||||||
// TODO: scopes
|
// TODO: scopes
|
||||||
val declaredModuleDependencies: Iterable<KotlinModuleDependency>
|
val declaredModuleDependencies: Iterable<KotlinModuleDependency>
|
||||||
|
|
||||||
|
// TODO: should this be source roots or source files?
|
||||||
val kotlinSourceRoots: Iterable<File>
|
val kotlinSourceRoots: Iterable<File>
|
||||||
}
|
}
|
||||||
|
|
||||||
interface KotlinModuleVariant : KotlinModuleFragment {
|
interface KotlinModuleVariant : KotlinModuleFragment {
|
||||||
val variantAttributes: Map<KotlinAttributeKey, String>
|
val variantAttributes: Map<KotlinAttributeKey, String>
|
||||||
|
|
||||||
var isExported: Boolean
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val KotlinModuleFragment.fragmentAttributeSets: Map<KotlinAttributeKey, Set<String>>
|
val KotlinModuleFragment.fragmentAttributeSets: Map<KotlinAttributeKey, Set<String>>
|
||||||
@@ -65,7 +64,6 @@ class BasicKotlinModuleVariant(
|
|||||||
containingModule,
|
containingModule,
|
||||||
fragmentName
|
fragmentName
|
||||||
), KotlinModuleVariant {
|
), KotlinModuleVariant {
|
||||||
override var isExported: Boolean = true
|
|
||||||
override val variantAttributes: MutableMap<KotlinAttributeKey, String> = mutableMapOf()
|
override val variantAttributes: MutableMap<KotlinAttributeKey, String> = mutableMapOf()
|
||||||
override fun toString(): String = "variant $fragmentName"
|
override fun toString(): String = "variant $fragmentName"
|
||||||
}
|
}
|
||||||
+1
-1
@@ -9,7 +9,7 @@ class MatchVariantsByExactAttributes : ModuleVariantResolver {
|
|||||||
override fun getChosenVariant(requestingVariant: KotlinModuleVariant, dependencyModule: KotlinModule): VariantResolution {
|
override fun getChosenVariant(requestingVariant: KotlinModuleVariant, dependencyModule: KotlinModule): VariantResolution {
|
||||||
val candidates = dependencyModule.variants
|
val candidates = dependencyModule.variants
|
||||||
return candidates.filter { candidate ->
|
return candidates.filter { candidate ->
|
||||||
candidate.isExported && candidate.variantAttributes.all { (attributeKey, candidateValue) ->
|
candidate.variantAttributes.all { (attributeKey, candidateValue) ->
|
||||||
attributeKey !in requestingVariant.variantAttributes.keys ||
|
attributeKey !in requestingVariant.variantAttributes.keys ||
|
||||||
candidateValue == requestingVariant.variantAttributes.getValue(attributeKey)
|
candidateValue == requestingVariant.variantAttributes.getValue(attributeKey)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user