diff --git a/libraries/tools/kotlin-gradle-plugin/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin/build.gradle.kts index 8cb53d5825a..578789358cc 100644 --- a/libraries/tools/kotlin-gradle-plugin/build.gradle.kts +++ b/libraries/tools/kotlin-gradle-plugin/build.gradle.kts @@ -226,6 +226,11 @@ pluginBundle { id = "org.jetbrains.kotlin.native.cocoapods", display = "Kotlin Native plugin for CocoaPods integration" ) + create( + name = "kotlinMultiplatformPluginPm20", + id = "org.jetbrains.kotlin.multiplatform.pm20", + display = "Kotlin Multiplatform plugin with PM2.0" + ) } publishPluginMarkers() diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt index fb4fc14b5a2..2f5ead2d8fa 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt @@ -19,15 +19,15 @@ import org.jetbrains.kotlin.daemon.common.CompilerId import org.jetbrains.kotlin.gradle.dsl.kotlinExtensionOrNull import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull 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.KotlinTarget import org.jetbrains.kotlin.gradle.plugin.internal.state.TaskLoggers import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaTarget 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.tasks.GradleCompileTaskProvider 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.newTmpFile import org.jetbrains.kotlin.gradle.utils.relativeOrCanonical @@ -216,7 +216,7 @@ internal open class GradleCompilerRunner(protected val taskProvider: GradleCompi KotlinCompileTaskData.getTaskDataContainer(project).forEach { taskData -> val compilation = taskData.compilation - val target = taskData.compilation.target + val target = taskData.compilation.owner val module = IncrementalModuleEntry( project.path, compilation.ownModuleName, @@ -229,12 +229,12 @@ internal open class GradleCompilerRunner(protected val taskProvider: GradleCompi nameToModules.getOrPut(module.name) { HashSet() }.add(module) if (compilation.platformType == KotlinPlatformType.js) { - jarForSourceSet(project, compilation.name)?.let { + jarForSourceSet(project, compilation.compilationPurpose)?.let { jarToModule[it] = module } } - if (compilation.isMain()) { + if (compilation is KotlinCompilation<*> && target is KotlinTarget && compilation.isMain()) { // FIXME support PM20 if (isMultiplatformProject) { try { //It could cause task reconfiguration. TODO: fix it some day if need diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinProjectExtension.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinProjectExtension.kt index d09ee4071e1..45ddca8927e 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinProjectExtension.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinProjectExtension.kt @@ -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.KotlinJsSingleTargetPreset 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.targets.js.calculateJsCompilerType 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" -internal fun Project.createKotlinExtension(extensionClass: KClass): KotlinProjectExtension { +internal fun Project.createKotlinExtension(extensionClass: KClass): KotlinTopLevelExtension { val kotlinExt = extensions.create(KOTLIN_PROJECT_EXTENSION_NAME, extensionClass.java, this) DslObject(kotlinExt).extensions.create("experimental", ExperimentalExtension::class.java) - return kotlinExtension + return topLevelExtension } +internal val Project.topLevelExtension: KotlinTopLevelExtension + get() = extensions.getByName(KOTLIN_PROJECT_EXTENSION_NAME) as KotlinTopLevelExtension + internal val Project.kotlinExtensionOrNull: KotlinProjectExtension? get() = extensions.findByName(KOTLIN_PROJECT_EXTENSION_NAME) as? KotlinProjectExtension @@ -43,7 +47,11 @@ internal val Project.multiplatformExtensionOrNull: KotlinMultiplatformExtension? internal val Project.multiplatformExtension: 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 get() = DslObject(this).extensions.getByType(ExperimentalExtension::class.java) @@ -58,7 +66,9 @@ open class KotlinProjectExtension(internal val project: Project) : KotlinSourceS fun explicitApiWarning() { explicitApi = ExplicitApiMode.Warning } +} +open class KotlinProjectExtension(project: Project) : KotlinTopLevelExtension(project), KotlinSourceSetContainer { override var sourceSets: NamedDomainObjectContainer @Suppress("UNCHECKED_CAST") get() = DslObject(this).extensions.getByName("sourceSets") as NamedDomainObjectContainer diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/KotlinDependenciesManagement.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/KotlinDependenciesManagement.kt index b069ce50b46..52f17659c70 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/KotlinDependenciesManagement.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/KotlinDependenciesManagement.kt @@ -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.junitplatform.JUnitPlatformOptions import org.gradle.api.tasks.testing.testng.TestNGOptions -import org.jetbrains.kotlin.gradle.dsl.KotlinAndroidProjectExtension -import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions -import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension +import org.jetbrains.kotlin.gradle.dsl.* import org.jetbrains.kotlin.gradle.dsl.kotlinExtension import org.jetbrains.kotlin.gradle.execution.KotlinAggregateExecutionSource import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider 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.withAllDependsOnSourceSets import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllDependsOnSourceSets @@ -41,7 +42,9 @@ import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName internal fun customizeKotlinDependencies(project: Project) { configureStdlibDefaultDependency(project) - configureKotlinTestDependency(project) + if (project.topLevelExtension is KotlinProjectExtension) { // TODO: extend this logic to PM20 + configureKotlinTestDependency(project) + } configureDefaultVersionsResolutionStrategy(project) } @@ -49,7 +52,7 @@ private fun configureDefaultVersionsResolutionStrategy(project: Project) { project.configurations.all { configuration -> // Use the API introduced in Gradle 4.4 to modify the dependencies directly before they are resolved: configuration.withDependencies { dependencySet -> - val coreLibrariesVersion = project.kotlinExtension.coreLibrariesVersion + val coreLibrariesVersion = project.topLevelExtension.coreLibrariesVersion dependencySet.filterIsInstance() .filter { it.group == KOTLIN_MODULE_GROUP && it.version.isNullOrEmpty() } .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) - project.kotlinExtension.sourceSets.all { kotlinSourceSet -> - scopesToHandleConfigurations.forEach { scope -> - val scopeConfiguration = project.sourceSetDependencyConfigurationByScope(kotlinSourceSet, scope) + when (val topLevelExtension = project.topLevelExtension) { + is KotlinPm20ProjectExtension -> { + addStdlibToPm20Project(topLevelExtension) + } + is KotlinProjectExtension -> { + topLevelExtension.sourceSets.all { kotlinSourceSet -> + scopesToHandleConfigurations.forEach { scope -> + val scopeConfiguration = project.sourceSetDependencyConfigurationByScope(kotlinSourceSet, scope) - project.tryWithDependenciesIfUnresolved(scopeConfiguration) { dependencies -> - val scopeToAddStdlibDependency = - if (isRelatedToAndroidTestSourceSet(project, kotlinSourceSet)) // AGP deprecates API configurations in test source sets - KotlinDependencyScope.IMPLEMENTATION_SCOPE - else KotlinDependencyScope.API_SCOPE + project.tryWithDependenciesIfUnresolved(scopeConfiguration) { dependencies -> + val scopeToAddStdlibDependency = + if (isRelatedToAndroidTestSourceSet( + project, + kotlinSourceSet + ) + ) // AGP deprecates API configurations in test source sets + KotlinDependencyScope.IMPLEMENTATION_SCOPE + else KotlinDependencyScope.API_SCOPE - if (scope != scopeToAddStdlibDependency) - return@tryWithDependenciesIfUnresolved + if (scope != scopeToAddStdlibDependency) + 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)) + } } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/Kapt3KotlinGradleSubplugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/Kapt3KotlinGradleSubplugin.kt index 1e039491999..cc96d3acaad 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/Kapt3KotlinGradleSubplugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/Kapt3KotlinGradleSubplugin.kt @@ -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.model.builder.KaptModelBuilder 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.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompileTaskData @@ -237,7 +238,7 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To val javaCompile: TaskProvider?, val variantData: Any?, val sourceSetName: String, - val kotlinCompilation: KotlinCompilation<*>, + val kotlinCompilation: AbstractKotlinCompilation<*>, val kaptExtension: KaptExtension, val kaptClasspathConfigurations: List ) { @@ -288,7 +289,7 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To val context = Kapt3SubpluginContext( project, javaCompileOrNull, - androidVariantData, sourceSetName, kotlinCompilation, kaptExtension, nonEmptyKaptConfigurations + androidVariantData, sourceSetName, kotlinCompilation as AbstractKotlinCompilation<*>/*TODO?*/, kaptExtension, nonEmptyKaptConfigurations ) val kaptGenerateStubsTaskProvider: TaskProvider = context.createKaptGenerateStubsTask() diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/model/builder/KotlinModelBuilder.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/model/builder/KotlinModelBuilder.kt index 66dd5de4413..4b640092c72 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/model/builder/KotlinModelBuilder.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/model/builder/KotlinModelBuilder.kt @@ -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.KotlinProjectImpl import org.jetbrains.kotlin.gradle.model.impl.SourceSetImpl -import org.jetbrains.kotlin.gradle.plugin.KOTLIN_DSL_NAME -import org.jetbrains.kotlin.gradle.plugin.KOTLIN_JS_DSL_NAME -import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet +import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.getConvention import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget 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 { val friendSourceSets = ArrayList() - taskData.compilation.associateWithTransitiveClosure.forEach { associateCompilation -> + (taskData.compilation as? KotlinCompilation<*>)?.associateWithTransitiveClosure?.forEach { associateCompilation -> friendSourceSets.add(associateCompilation.name) } return friendSourceSets diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt index d7d6e7c8680..a62bb4d0320 100755 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt @@ -15,7 +15,6 @@ import org.gradle.api.artifacts.maven.MavenResolver import org.gradle.api.attributes.Usage import org.gradle.api.file.ConfigurableFileTree import org.gradle.api.file.FileCollection -import org.gradle.api.file.SourceDirectorySet import org.gradle.api.logging.Logging import org.gradle.api.plugins.InvalidPluginException 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.model.builder.KotlinModelBuilder 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.targets.js.dsl.KotlinJsBinaryMode import org.jetbrains.kotlin.gradle.targets.js.ir.* @@ -60,46 +60,48 @@ val KOTLIN_JS_DSL_NAME = "kotlin2js" val KOTLIN_OPTIONS_DSL_NAME = "kotlinOptions" abstract class KotlinCompilationProcessor( - open val kotlinCompilation: KotlinCompilation<*> + open val kotlinCompilation: KotlinCompilationData<*> ) { abstract val kotlinTask: TaskProvider abstract fun run() protected val project: Project - get() = kotlinCompilation.target.project + get() = kotlinCompilation.project protected val defaultKotlinDestinationDir: File get() { - val kotlinExt = project.kotlinExtension + val kotlinExt = project.topLevelExtension val targetSubDirectory = if (kotlinExt is KotlinSingleJavaTargetExtension) "" // In single-target projects, don't add the target name part to this path else - kotlinCompilation.target.disambiguationClassifier?.let { "$it/" }.orEmpty() - return File(project.buildDir, "classes/kotlin/$targetSubDirectory${kotlinCompilation.compilationName}") + kotlinCompilation.compilationClassifier?.let { "$it/" }.orEmpty() + return File(project.buildDir, "classes/kotlin/$targetSubDirectory${kotlinCompilation.compilationPurpose}") } } internal abstract class KotlinSourceSetProcessor>( val tasksProvider: KotlinTasksProvider, val taskDescription: String, - kotlinCompilation: AbstractKotlinCompilation<*> + kotlinCompilation: KotlinCompilationData<*> ) : KotlinCompilationProcessor(kotlinCompilation) { protected abstract fun doTargetSpecificProcessing() protected val logger = Logging.getLogger(this.javaClass)!! - protected val sourceSetName: String = kotlinCompilation.compilationName + protected val sourceSetName: String = kotlinCompilation.compilationPurpose override val kotlinTask: TaskProvider = prepareKotlinCompileTask() protected val javaSourceSet: SourceSet? - get() = - (kotlinCompilation as? KotlinWithJavaCompilation<*>)?.javaSourceSet - ?: kotlinCompilation.target.let { - if (it is KotlinJvmTarget && it.withJavaEnabled) - project.convention.getPlugin(JavaPluginConvention::class.java).sourceSets.maybeCreate(kotlinCompilation.name) + get() { + val compilation = kotlinCompilation + return (compilation as? KotlinWithJavaCompilation<*>)?.javaSourceSet + ?: kotlinCompilation.owner.let { + if (it is KotlinJvmTarget && it.withJavaEnabled && compilation is KotlinJvmCompilation) + project.convention.getPlugin(JavaPluginConvention::class.java).sourceSets.maybeCreate(compilation.name) else null } + } private fun prepareKotlinCompileTask(): TaskProvider = registerKotlinCompileTask(register = ::doRegisterTask).also { task -> @@ -136,31 +138,23 @@ internal abstract class KotlinSourceSetProcessor>( // Try to avoid duplicate Java sources in allSource; run lazily to allow changing the directory set: val kotlinSrcDirsToAdd = Callable { - kotlinCompilation.kotlinSourceSets.map { filterOutJavaSrcDirsIfPossible(it.kotlin) } + kotlinCompilation.kotlinSourceDirectoriesByFragmentName.values.map { filterOutJavaSrcDirsIfPossible(it) } } java.allJava.srcDirs(kotlinSrcDirsToAdd) java.allSource.srcDirs(kotlinSrcDirsToAdd) } - private fun filterOutJavaSrcDirsIfPossible(sourceDirectorySet: SourceDirectorySet): FileCollection { - val java = javaSourceSet ?: return sourceDirectorySet - - // 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 - } + private fun filterOutJavaSrcDirsIfPossible(sourceDirectories: FileCollection): FileCollection { + val java = javaSourceSet ?: return sourceDirectories // 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() { + val kotlinCompilation = kotlinCompilation as? KotlinCompilation<*> ?: return + open class IDEClassesTask : DefaultTask() // 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 'Classes`, where the IDE module name is the default source set name: @@ -185,7 +179,7 @@ internal abstract class KotlinSourceSetProcessor>( internal class Kotlin2JvmSourceSetProcessor( tasksProvider: KotlinTasksProvider, - kotlinCompilation: AbstractKotlinCompilation<*>, + kotlinCompilation: KotlinCompilationData<*>, private val kotlinPluginVersion: String ) : KotlinSourceSetProcessor( tasksProvider, "Compiles the $kotlinCompilation.", kotlinCompilation @@ -199,14 +193,16 @@ internal class Kotlin2JvmSourceSetProcessor( override fun doTargetSpecificProcessing() { ifKaptEnabled(project) { - Kapt3GradleSubplugin.createAptConfigurationIfNeeded(project, kotlinCompilation.compilationName) + Kapt3GradleSubplugin.createAptConfigurationIfNeeded(project, kotlinCompilation.compilationPurpose) } - ScriptingGradleSubplugin.configureForSourceSet(project, kotlinCompilation.compilationName) + ScriptingGradleSubplugin.configureForSourceSet(project, kotlinCompilation.compilationPurpose) project.whenEvaluated { 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 -> val javaTask = project.tasks.withType().named(java.compileJavaTaskName) @@ -236,7 +232,7 @@ internal fun KotlinCompilationOutput.addClassesDir(classesDirProvider: () -> Fil internal class Kotlin2JsSourceSetProcessor( tasksProvider: KotlinTasksProvider, - kotlinCompilation: AbstractKotlinCompilation<*>, + kotlinCompilation: KotlinCompilationData<*>, private val kotlinPluginVersion: String ) : KotlinSourceSetProcessor( tasksProvider, @@ -294,7 +290,9 @@ internal class Kotlin2JsSourceSetProcessor( } 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( - compilation: AbstractKotlinCompilation<*>, + compilation: KotlinCompilationData<*>, tasksProvider: KotlinTasksProvider, private val kotlinPluginVersion: String ) : KotlinSourceSetProcessor( @@ -367,13 +365,15 @@ internal class KotlinCommonSourceSetProcessor( override fun doTargetSpecificProcessing() { project.tasks.named(kotlinCompilation.compileAllTaskName).dependsOn(kotlinTask) // can be missing (e.g. in case of tests) - if (kotlinCompilation.isMain()) { + if ((kotlinCompilation as? AbstractKotlinCompilation<*>)?.isMain() == true) { project.locateTask(kotlinCompilation.target.artifactsTaskName)?.dependsOn(kotlinTask) } - project.whenEvaluated { - val subpluginEnvironment: SubpluginEnvironment = SubpluginEnvironment.loadSubplugins(project, kotlinPluginVersion) - subpluginEnvironment.addSubpluginOptions(project, kotlinCompilation) + if (kotlinCompilation is AbstractKotlinCompilation<*>) { + project.whenEvaluated { + val subpluginEnvironment: SubpluginEnvironment = SubpluginEnvironment.loadSubplugins(project, kotlinPluginVersion) + subpluginEnvironment.addSubpluginOptions(project, kotlinCompilation) + } } } @@ -602,7 +602,7 @@ internal abstract class AbstractKotlinPlugin( internal open class KotlinPlugin( kotlinPluginVersion: String, registry: ToolingModelBuilderRegistry -) : AbstractKotlinPlugin(KotlinTasksProvider(targetName), kotlinPluginVersion, registry) { +) : AbstractKotlinPlugin(KotlinTasksProvider(), kotlinPluginVersion, registry) { companion object { private const val targetName = "" // use empty suffix for the task names @@ -633,7 +633,7 @@ internal open class KotlinPlugin( internal open class KotlinCommonPlugin( kotlinPluginVersion: String, registry: ToolingModelBuilderRegistry -) : AbstractKotlinPlugin(KotlinTasksProvider(targetName), kotlinPluginVersion, registry) { +) : AbstractKotlinPlugin(KotlinTasksProvider(), kotlinPluginVersion, registry) { companion object { private const val targetName = "common" @@ -662,7 +662,7 @@ internal open class KotlinCommonPlugin( internal open class Kotlin2JsPlugin( kotlinPluginVersion: String, registry: ToolingModelBuilderRegistry -) : AbstractKotlinPlugin(KotlinTasksProvider(targetName), kotlinPluginVersion, registry) { +) : AbstractKotlinPlugin(KotlinTasksProvider(), kotlinPluginVersion, registry) { companion object { private const val targetName = "2Js" @@ -716,7 +716,7 @@ internal open class KotlinAndroidPlugin( kotlinPluginVersion: String, androidTarget: KotlinAndroidTarget ): AbstractAndroidProjectHandler { - val tasksProvider = AndroidTasksProvider(androidTarget.targetName) + val tasksProvider = AndroidTasksProvider() if (androidPluginVersion != null) { val minimalVersion = "3.0.0" diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt index 1b79c543c3a..05b9b990a72 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt @@ -23,12 +23,15 @@ import org.gradle.api.Project import org.gradle.api.internal.FeaturePreviews import org.gradle.api.logging.Logger import org.gradle.api.logging.Logging +import org.gradle.api.model.ObjectFactory import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry import org.jetbrains.kotlin.gradle.dsl.* import org.jetbrains.kotlin.gradle.logging.kotlinDebug import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMetadataTarget import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMultiplatformPlugin 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.statistics.KotlinBuildStatsService import org.jetbrains.kotlin.gradle.targets.js.KotlinJsCompilerAttribute @@ -52,7 +55,7 @@ abstract class KotlinBasePluginWrapper : Plugin { private val log = Logging.getLogger(this.javaClass) val kotlinPluginVersion = loadKotlinVersionFromResource(log) - open val projectExtensionClass: KClass get() = KotlinProjectExtension::class + open val projectExtensionClass: KClass get() = KotlinProjectExtension::class internal open fun kotlinSourceSetFactory(project: Project): NamedDomainObjectFactory = DefaultKotlinSourceSetFactory(project) @@ -83,12 +86,18 @@ abstract class KotlinBasePluginWrapper : Plugin { kotlinGradleBuildServices.detectKotlinPluginLoadedInMultipleProjects(project, kotlinPluginVersion) project.createKotlinExtension(projectExtensionClass).apply { + if (this is KotlinPm20ProjectExtension) + this.project = project // refactor this code to remove the specific plugin class? + coreLibrariesVersion = kotlinPluginVersion fun kotlinSourceSetContainer(factory: NamedDomainObjectFactory) = 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)) @@ -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 = + objectFactory.newInstance(KotlinPm20GradlePlugin::class.java) + + override val projectExtensionClass: KClass + get() = KotlinPm20ProjectExtension::class +} + fun Project.getKotlinPluginVersion(): String? = plugins.asSequence().mapNotNull { (it as? KotlinBasePluginWrapper)?.kotlinPluginVersion }.firstOrNull() diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/SubpluginEnvironment.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/SubpluginEnvironment.kt index 2fd9f092135..b28872f8216 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/SubpluginEnvironment.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/SubpluginEnvironment.kt @@ -8,6 +8,7 @@ import org.gradle.api.tasks.compile.JavaCompile import org.jetbrains.kotlin.gradle.dsl.KotlinCompile import org.jetbrains.kotlin.gradle.logging.kotlinDebug 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.CompilerPluginOptions import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/DefaultKotlinDependencyHandler.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/DefaultKotlinDependencyHandler.kt index 69dc63d0ecc..1c6fbe37ab4 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/DefaultKotlinDependencyHandler.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/DefaultKotlinDependencyHandler.kt @@ -8,10 +8,13 @@ package org.jetbrains.kotlin.gradle.plugin.mpp import org.gradle.api.Project import org.gradle.api.artifacts.Dependency import org.gradle.api.artifacts.ExternalModuleDependency +import org.gradle.api.artifacts.ModuleDependency import org.gradle.api.artifacts.ProjectDependency import org.jetbrains.kotlin.gradle.plugin.HasKotlinDependencies import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler 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.directoryNpmDependency import org.jetbrains.kotlin.gradle.targets.js.npm.moduleName @@ -69,8 +72,17 @@ class DefaultKotlinDependencyHandler( private fun addDependencyByAnyNotation( configurationName: String, dependencyNotation: Any - ): Dependency? = - project.dependencies.add(configurationName, dependencyNotation) + ): Dependency? { + 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( configurationName: String, diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/GradleProjectModuleBuilder.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/GradleProjectModuleBuilder.kt index 514a95d8836..2bc0a862b75 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/GradleProjectModuleBuilder.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/GradleProjectModuleBuilder.kt @@ -158,7 +158,6 @@ class GradleProjectModuleBuilder(private val addInferredSourceSetVisibilityAsExp variant.variantAttributes[KotlinAttributeKey(key.name)] = attributeString(compileDependenciesConfiguration.attributes, key) } - variant.isExported = compilation.isMain() } } // Once all fragments are created, add dependencies between them diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMultiplatformPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMultiplatformPlugin.kt index f6165b8dac2..6c855d6ce35 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMultiplatformPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMultiplatformPlugin.kt @@ -11,7 +11,7 @@ import org.gradle.api.Project import org.gradle.api.attributes.Attribute import org.gradle.api.attributes.AttributeContainer 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.plugins.JavaBasePlugin 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 = - 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( project: Project, - sourceSets: Lazy>, + sourceSets: Lazy>, componentName: String?, artifactNameAppendix: String ): TaskProvider { @@ -316,9 +316,9 @@ internal fun sourcesJarTask( project.whenEvaluated { result.configure { - sourceSets.value.forEach { sourceSet -> - it.from(sourceSet.kotlin) { copySpec -> - copySpec.into(sourceSet.name) + sourceSets.value.forEach { (sourceSetName, sourceSetFiles) -> + it.from(sourceSetFiles) { copySpec -> + copySpec.into(sourceSetName) // Duplicates are coming from `SourceSets` that `sourceSet` depends on. // Such dependency was added by Kotlin compilation. // TODO: rethink approach for adding dependent `SourceSets` to Kotlin compilation `SourceSet` diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinUsages.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinUsages.kt index 00dd4c8dd9a..fe8f1762aef 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinUsages.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinUsages.kt @@ -24,34 +24,43 @@ object KotlinUsages { private val jvmPlatformTypes: Set = setOf(jvm, androidJvm) - internal fun consumerApiUsage(target: KotlinTarget) = target.project.usageByName( - when (target.platformType) { + internal fun consumerApiUsage(project: Project, platformType: KotlinPlatformType) = project.usageByName( + when (platformType) { in jvmPlatformTypes -> JAVA_API else -> KOTLIN_API } ) - internal fun consumerRuntimeUsage(target: KotlinTarget) = target.project.usageByName( - when (target.platformType) { + internal fun consumerApiUsage(target: KotlinTarget): Usage = + consumerApiUsage(target.project, target.platformType) + + internal fun consumerRuntimeUsage(project: Project, platformType: KotlinPlatformType) = project.usageByName( + when (platformType) { in jvmPlatformTypes -> JAVA_RUNTIME else -> KOTLIN_RUNTIME } ) - internal fun producerApiUsage(target: KotlinTarget) = target.project.usageByName( - when (target.platformType) { + internal fun consumerRuntimeUsage(target: KotlinTarget) = consumerRuntimeUsage(target.project, target.platformType) + + internal fun producerApiUsage(project: Project, platformType: KotlinPlatformType) = project.usageByName( + when (platformType) { in jvmPlatformTypes -> "java-api-jars" else -> KOTLIN_API } ) - internal fun producerRuntimeUsage(target: KotlinTarget) = target.project.usageByName( - when (target.platformType) { + internal fun producerApiUsage(target: KotlinTarget) = producerApiUsage(target.project, target.platformType) + + internal fun producerRuntimeUsage(project: Project, platformType: KotlinPlatformType) = project.usageByName( + when (platformType) { in jvmPlatformTypes -> "java-runtime-jars" else -> KOTLIN_RUNTIME } ) + internal fun producerRuntimeUsage(target: KotlinTarget) = producerRuntimeUsage(target.project, target.platformType) + private class KotlinJavaRuntimeJarsCompatibility : AttributeCompatibilityRule { // 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: diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilations.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilations.kt index a09735864b9..138e6a50317 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilations.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilations.kt @@ -13,6 +13,7 @@ import org.gradle.api.UnknownTaskException import org.gradle.api.attributes.AttributeContainer import org.gradle.api.execution.TaskExecutionListener import org.gradle.api.file.FileCollection +import org.gradle.api.file.SourceDirectorySet import org.gradle.api.plugins.BasePluginConvention import org.gradle.api.plugins.ExtraPropertiesExtension 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.plugin.* 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.withAllDependsOnSourceSets import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllDependsOnSourceSets import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile import org.jetbrains.kotlin.gradle.tasks.locateTask import org.jetbrains.kotlin.gradle.utils.* +import java.io.File import java.util.* import java.util.concurrent.Callable @@ -52,8 +55,11 @@ internal val KotlinCompilation<*>.kotlinSourceSetsIncludingDefault: Set( target: KotlinTarget, + override val compilationPurpose: String +) : KotlinCompilation, HasKotlinDependencies, KotlinCompilationData { + override val compilationName: String -) : KotlinCompilation, HasKotlinDependencies { + get() = compilationPurpose override fun kotlinOptions(configure: T.() -> Unit) = configure(kotlinOptions) @@ -86,7 +92,7 @@ abstract class AbstractKotlinCompilation( when { isMain() && target is KotlinMetadataTarget -> 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( Callable { target.project.buildDir.resolve("processedResources/${target.targetName}/$name") }) } - open fun addSourcesToCompileTask(sourceSet: KotlinSourceSet, addAsCommonSources: Lazy) { - fun AbstractKotlinCompile<*>.configureAction() { - source(sourceSet.kotlin) - sourceFilesExtensions(sourceSet.customSourceFilesExtensions) - commonSourceSet += project.files(Callable { - if (addAsCommonSources.value) sourceSet.kotlin else emptyList() - }) - } - - 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() - } - } + open fun addSourcesToCompileTask(sourceSet: KotlinSourceSet, addAsCommonSources: Lazy) = + addSourcesToKotlinCompileTask( + project, + compileKotlinTaskName, + sourceSet.customSourceFilesExtensions, + { sourceSet.kotlin }, + addAsCommonSources + ) internal fun addExactSourceSetsEagerly(sourceSets: Set) { with(target.project) { @@ -166,20 +163,20 @@ abstract class AbstractKotlinCompilation( override val compileDependencyConfigurationName: String get() = lowerCamelCaseName( target.disambiguationClassifier, - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }.orEmpty(), + compilationPurpose.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }.orEmpty(), "compileClasspath" ) override val compileKotlinTaskName: String get() = lowerCamelCaseName( "compile", - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, + compilationPurpose.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, "Kotlin", target.targetName ) override val compileAllTaskName: String - get() = lowerCamelCaseName(target.disambiguationClassifier, compilationName, "classes") + get() = lowerCamelCaseName(target.disambiguationClassifier, compilationPurpose, "classes") override lateinit var compileDependencyFiles: FileCollection @@ -201,7 +198,7 @@ abstract class AbstractKotlinCompilation( override fun dependencies(configureClosure: Closure) = 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? by lazy { if (associateWithTransitiveClosure.any { it.isMain() }) { @@ -240,7 +237,7 @@ abstract class AbstractKotlinCompilation( } 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<*>) { require(other.target == target) { "Only associations between compilations of a single target are supported" } @@ -278,17 +275,64 @@ abstract class AbstractKotlinCompilation( override val associateWith: List> 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 + 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 - get() { - 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 fun addSourcesToKotlinCompileTask( + project: Project, + taskName: String, + sourceFileExtensions: Iterable, + sources: () -> Iterable, + addAsCommonSources: Lazy +) { + fun AbstractKotlinCompile<*>.configureAction() { + source(project.files(Callable { sources() })) + sourceFilesExtensions(sourceFileExtensions) + commonSourceSet += project.files(Callable { + if (addAsCommonSources.value) sources() else emptyList() + }) } + 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> get() = mutableSetOf>().apply { fun visit(other: KotlinCompilation<*>) { @@ -306,7 +350,7 @@ abstract class AbstractKotlinCompilationToRunnableFiles override val runtimeDependencyConfigurationName: String get() = lowerCamelCaseName( target.disambiguationClassifier, - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, + compilationPurpose.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, "runtimeClasspath" ) @@ -397,5 +441,5 @@ internal object CompilationSourceSetUtil { private val invalidModuleNameCharactersRegex = """[\\/\r\n\t]""".toRegex() -private fun filterModuleName(moduleName: String): String = +internal fun filterModuleName(moduleName: String): String = moduleName.replace(invalidModuleNameCharactersRegex, "_") diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradlePlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradlePlugin.kt new file mode 100644 index 00000000000..435022f633a --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradlePlugin.kt @@ -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 { + 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 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.() -> Unit) { + val getOrCreateVariant: KotlinGradleModule.() -> KotlinJvmVariant = { jvm } + mainAndTest { getOrCreateVariant(this) } + val slice = KotlinFragmentSlice(this, getOrCreateVariant) + configure(slice) +} + +open class KotlinFragmentSlice( + 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, configure: T.() -> Unit) { + module.get().apply { inModule(this, configure) } + } + + fun inModule(module: KotlinGradleModule, configure: T.() -> Unit) { + getOrCreateFragment(module).configure() + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinCompilationData.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinCompilationData.kt new file mode 100644 index 00000000000..2d24716f308 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinCompilationData.kt @@ -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 { + val project: Project + val owner: Any? + + val compilationPurpose: String + val compilationClassifier: String? + + val kotlinSourceDirectoriesByFragmentName: Map + 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 +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinGradleFragment.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinGradleFragment.kt new file mode 100644 index 00000000000..01b93d0288b --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinGradleFragment.kt @@ -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) { + _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) = + 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>() + + override val directRefinesDependencies: Iterable + get() = _directRefinesDependencies.map { it.get() } + + override val declaredModuleDependencies: Iterable + 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 + 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) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinGradleModule.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinGradleModule.kt new file mode 100644 index 00000000000..b3add60ea83 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinGradleModule.kt @@ -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 = + 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 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) = + 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 diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinGradleModuleFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinGradleModuleFactory.kt new file mode 100644 index 00000000000..537607dae41 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinGradleModuleFactory.kt @@ -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 { + 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)) + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinJvmVariant.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinJvmVariant.kt new file mode 100644 index 00000000000..dd925031df9 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinJvmVariant.kt @@ -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 { + 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 + get() = variant.refinesClosure.filterIsInstance().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") +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/abstractVariantFactories.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/abstractVariantFactories.kt new file mode 100644 index 00000000000..1644234d29d --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/abstractVariantFactories.kt @@ -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( + module: KotlinGradleModule +) : AbstractKotlinGradleFragmentFactory(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_ATTRIBUTE, KotlinUsages.producerApiUsage(project, fragment.platformType)) + extendsFrom(project.configurations.getByName(fragment.transitiveApiConfigurationName)) + // FIXME + compileOnly + configureApiElementsConfiguration(fragment, this@apply) + } + } +} + +abstract class AbstractKotlinGradleVariantWithRuntimeDependenciesFactory(module: KotlinGradleModule) : + AbstractKotlinGradleVariantFactory(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 + } + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/abstractVariants.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/abstractVariants.kt new file mode 100644 index 00000000000..b62da769547 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/abstractVariants.kt @@ -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 + 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 + get() = project.tasks.withType().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") +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/fragmentFactories.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/fragmentFactories.kt new file mode 100644 index 00000000000..dca3958639a --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/fragmentFactories.kt @@ -0,0 +1,66 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.gradle.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( + protected val module: KotlinGradleModule +) : NamedDomainObjectFactory { + + 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(module) { + override fun instantiateFragment(name: String): KotlinGradleFragment = + project.objects.newInstance(KotlinGradleFragment::class.java, module, name) +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/modelClasses.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/modelClasses.kt new file mode 100644 index 00000000000..31cb0adceda --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/modelClasses.kt @@ -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(module) { + override fun instantiateFragment(name: String) = KotlinJvmVariant(module, name) + + // FIXME expose the JAR with the artifacts API + private fun getOrCreateJarTask(fragment: KotlinJvmVariant): TaskProvider { + 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 \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/util/capabilities.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/util/capabilities.kt new file mode 100644 index 00000000000..8d7a0814b28 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/util/capabilities.kt @@ -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, + val nameValue: String, + val versionProvider: Provider, + 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 + ) + } + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/KotlinDependencyScope.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/KotlinDependencyScope.kt index 3d8cb0e3089..c5ce224f41c 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/KotlinDependencyScope.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/KotlinDependencyScope.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.gradle.plugin.sources import org.gradle.api.Project 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.KotlinSourceSet 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( when (scope) { API_SCOPE -> sourceSet.apiConfigurationName diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/KotlinJsCompilation.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/KotlinJsCompilation.kt index bd90d2d800b..5f188d4c96c 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/KotlinJsCompilation.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/KotlinJsCompilation.kt @@ -99,7 +99,7 @@ open class KotlinJsCompilation( private fun disambiguateNameInPlatform(simpleName: String): String { return lowerCamelCaseName( disambiguationClassifierInPlatform, - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, + compilationPurpose.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, simpleName ) } @@ -111,7 +111,7 @@ open class KotlinJsCompilation( target.irTarget?.let { target.disambiguationClassifierInPlatform } ?: target.disambiguationClassifier, - compilationName + compilationPurpose ) } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/KotlinJsTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/KotlinJsTargetConfigurator.kt index 3703275e4e4..345cfa2f684 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/KotlinJsTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/KotlinJsTargetConfigurator.kt @@ -50,7 +50,7 @@ open class KotlinJsTargetConfigurator(kotlinPluginVersion: String) : } override fun buildCompilationProcessor(compilation: KotlinJsCompilation): KotlinSourceSetProcessor<*> { - val tasksProvider = KotlinTasksProvider(compilation.target.targetName) + val tasksProvider = KotlinTasksProvider() return Kotlin2JsSourceSetProcessor(tasksProvider, compilation, kotlinPluginVersion) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrCompilation.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrCompilation.kt index 8d24db0083e..20eb5243a1a 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrCompilation.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrCompilation.kt @@ -36,7 +36,7 @@ class KotlinJsIrCompilation( target.disambiguationClassifierInPlatform else target.disambiguationClassifier, - compilationName + compilationPurpose ) } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTargetConfigurator.kt index 7381a68787a..0f66f5cc9dd 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTargetConfigurator.kt @@ -54,7 +54,7 @@ open class KotlinJsIrTargetConfigurator(kotlinPluginVersion: String) : } override fun buildCompilationProcessor(compilation: KotlinJsIrCompilation): KotlinSourceSetProcessor<*> { - val tasksProvider = KotlinTasksProvider(compilation.target.targetName) + val tasksProvider = KotlinTasksProvider() return KotlinJsIrSourceSetProcessor(tasksProvider, compilation, kotlinPluginVersion) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/KotlinJsTest.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/KotlinJsTest.kt index 75a9f83e4d1..080918743f2 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/KotlinJsTest.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/KotlinJsTest.kt @@ -93,7 +93,7 @@ constructor( val compilationId: String by lazy { compilation.let { val target = it.target - target.project.path + "@" + target.name + ":" + it.compilationName + target.project.path + "@" + target.name + ":" + it.compilationPurpose } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/webpack/KotlinWebpack.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/webpack/KotlinWebpack.kt index 73b130f95e2..2c774e1c269 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/webpack/KotlinWebpack.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/webpack/KotlinWebpack.kt @@ -62,7 +62,7 @@ constructor( val compilationId: String by lazy { compilation.let { val target = it.target - target.project.path + "@" + target.name + ":" + it.compilationName + target.project.path + "@" + target.name + ":" + it.compilationPurpose } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmCompilation.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmCompilation.kt index 45d484f02d4..81f1b75c535 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmCompilation.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmCompilation.kt @@ -35,7 +35,7 @@ open class KotlinJvmCompilation( get() = if (target.withJavaEnabled) { val project = target.project 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) } else null } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTargetConfigurator.kt index 899c3465013..32726173ac3 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTargetConfigurator.kt @@ -73,7 +73,7 @@ class KotlinJvmTargetConfigurator(kotlinPluginVersion: String) : } override fun buildCompilationProcessor(compilation: KotlinJvmCompilation): KotlinSourceSetProcessor<*> { - val tasksProvider = KotlinTasksProvider(compilation.target.targetName) + val tasksProvider = KotlinTasksProvider() return Kotlin2JvmSourceSetProcessor(tasksProvider, compilation, kotlinPluginVersion) } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmWithJavaTargetPreset.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmWithJavaTargetPreset.kt index 2fb64a96b69..3c5ac09bc67 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmWithJavaTargetPreset.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmWithJavaTargetPreset.kt @@ -36,7 +36,7 @@ class KotlinJvmWithJavaTargetPreset( } AbstractKotlinPlugin.configureTarget(target) { compilation -> - Kotlin2JvmSourceSetProcessor(KotlinTasksProvider(name), compilation, kotlinPluginVersion) + Kotlin2JvmSourceSetProcessor(KotlinTasksProvider(), compilation, kotlinPluginVersion) } target.compilations.getByName("test").run { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt index 444f3b4e294..afa8f9d1a93 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt @@ -110,7 +110,7 @@ class KotlinMetadataTargetConfigurator(kotlinPluginVersion: String) : override fun buildCompilationProcessor(compilation: AbstractKotlinCompilation<*>): KotlinCompilationProcessor<*> = when (compilation) { is KotlinCommonCompilation -> { - val tasksProvider = KotlinTasksProvider(compilation.target.targetName) + val tasksProvider = KotlinTasksProvider() KotlinCommonSourceSetProcessor(compilation, tasksProvider, kotlinPluginVersion) } is KotlinSharedNativeCompilation -> NativeSharedCompilationProcessor(compilation) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/DefaultCInteropSettings.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/DefaultCInteropSettings.kt index 7979e9dfdee..dddbb32e56b 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/DefaultCInteropSettings.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/DefaultCInteropSettings.kt @@ -57,7 +57,7 @@ open class DefaultCInteropSettings @Inject constructor( val interopProcessingTaskName: String get() = lowerCamelCaseName( "cinterop", - compilation.compilationName.takeIf { it != "main" }.orEmpty(), + compilation.compilationPurpose.takeIf { it != "main" }.orEmpty(), name, target.disambiguationClassifier ) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeCompilation.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeCompilation.kt index a00902cf003..689bc843757 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeCompilation.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeCompilation.kt @@ -9,7 +9,6 @@ package org.jetbrains.kotlin.gradle.plugin.mpp import groovy.lang.Closure import org.gradle.api.Action import org.gradle.api.NamedDomainObjectContainer -import org.gradle.api.Project import org.gradle.api.file.FileCollection import org.gradle.api.tasks.TaskProvider import org.gradle.util.ConfigureUtil @@ -77,9 +76,6 @@ class KotlinNativeCompilation( ) : AbstractKotlinNativeCompilation(target, konanTarget, name), KotlinCompilationWithResources { - private val project: Project - get() = target.project - // Interop DSL. val cinterops = project.container(DefaultCInteropSettings::class.java) { cinteropName -> DefaultCInteropSettings(project, cinteropName, this) @@ -95,15 +91,15 @@ class KotlinNativeCompilation( override val compileDependencyConfigurationName: String get() = lowerCamelCaseName( target.disambiguationClassifier, - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }.orEmpty(), + compilationPurpose.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }.orEmpty(), "compileKlibraries" ) override val compileAllTaskName: String - get() = lowerCamelCaseName(target.disambiguationClassifier, compilationName, "klibrary") + get() = lowerCamelCaseName(target.disambiguationClassifier, compilationPurpose, "klibrary") val binariesTaskName: String - get() = lowerCamelCaseName(target.disambiguationClassifier, compilationName, "binaries") + get() = lowerCamelCaseName(target.disambiguationClassifier, compilationPurpose, "binaries") override fun addAssociateCompilationDependencies(other: KotlinCompilation<*>) { with(target.project) { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompileCommon.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompileCommon.kt index 28da1d84902..d29b181f786 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompileCommon.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompileCommon.kt @@ -30,7 +30,9 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformCommonOptionsImpl import org.jetbrains.kotlin.gradle.dsl.fillDefaultValues import org.jetbrains.kotlin.gradle.internal.tasks.allOutputFiles 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.KotlinTarget import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinCommonCompilation import org.jetbrains.kotlin.gradle.utils.getValue import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllDependsOnSourceSets @@ -78,19 +80,25 @@ open class KotlinCompileCommon : AbstractKotlinCompile): List { - val target = taskData.compilation.target - return sourceSets - .mapNotNull { sourceSet -> target.compilations.findByName(sourceSet.name)?.output?.classesDirs } - .flatten() + val target = taskData.compilation.owner + return when (target) { + is KotlinTarget -> sourceSets + .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:InputFiles 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) { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt index ca6eabd9fc9..4bb3ae4d671 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt @@ -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.mpp.AbstractKotlinCompilation 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.targets.js.ir.isProduceUnzippedKlib import org.jetbrains.kotlin.gradle.utils.* @@ -216,7 +215,9 @@ abstract class AbstractKotlinCompile() : AbstractKo @get:InputFiles @get:Classpath 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 @@ -253,7 +254,7 @@ abstract class AbstractKotlinCompile() : AbstractKo @get:Internal @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 = taskData.destinationDir.get() @@ -293,7 +294,7 @@ abstract class AbstractKotlinCompile() : AbstractKo @get:Internal internal val sourceSetName: String - get() = taskData.compilation.name + get() = taskData.compilation.compilationPurpose @get:InputFiles @get:PathSensitive(PathSensitivity.RELATIVE) @@ -308,7 +309,7 @@ abstract class AbstractKotlinCompile() : AbstractKo val friendPaths: FileCollection = project.files( project.provider { taskData.compilation.run { - if (this !is AbstractKotlinCompilation<*>) return@run project.files() + if (this !is AbstractKotlinCompilation<*>) return@run project.files() // FIXME support PM20 mutableListOf().also { allCollections -> associateWithTransitiveClosure.forEach { allCollections.add(it.output.classesDirs) } allCollections.add(friendArtifacts) @@ -398,7 +399,9 @@ abstract class AbstractKotlinCompile() : AbstractKo internal abstract fun callCompilerAsync(args: T, sourceRoots: SourceRoots, changedFiles: ChangedFiles) @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 internal val abstractKotlinCompileArgumentsContributor by lazy { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/TasksProvider.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/TasksProvider.kt index 5822afe6e93..b007f241026 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/TasksProvider.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/TasksProvider.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider import org.jetbrains.kotlin.gradle.plugin.mapKotlinTaskProperties 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.sources.applyLanguageSettingsToKotlinOptions import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrLink @@ -80,11 +81,11 @@ internal inline fun Project.locateOrRegisterTask(name: String 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( project: Project, name: String, - compilation: KotlinCompilation<*>, + compilation: KotlinCompilationData<*>, configureAction: (KotlinCompile) -> (Unit) ): TaskProvider { val properties = PropertiesProvider(project) @@ -99,7 +100,7 @@ internal open class KotlinTasksProvider(val targetName: String) { fun registerKotlinJSTask( project: Project, name: String, - compilation: KotlinCompilation<*>, + compilation: KotlinCompilationData<*>, configureAction: (Kotlin2JsCompile) -> Unit ): TaskProvider { val properties = PropertiesProvider(project) @@ -114,7 +115,7 @@ internal open class KotlinTasksProvider(val targetName: String) { fun registerKotlinJsIrTask( project: Project, name: String, - compilation: KotlinCompilation<*>, + compilation: KotlinCompilationData<*>, configureAction: (KotlinJsIrLink) -> Unit ): TaskProvider { val properties = PropertiesProvider(project) @@ -129,7 +130,7 @@ internal open class KotlinTasksProvider(val targetName: String) { fun registerKotlinCommonTask( project: Project, name: String, - compilation: KotlinCompilation<*>, + compilation: KotlinCompilationData<*>, configureAction: (KotlinCompileCommon) -> (Unit) ): TaskProvider { val properties = PropertiesProvider(project) @@ -145,13 +146,13 @@ internal open class KotlinTasksProvider(val targetName: String) { kotlinTaskHolder: TaskProvider>, project: Project, propertiesProvider: PropertiesProvider, - compilation: KotlinCompilation<*> + compilation: KotlinCompilationData<*> ) { project.runOnceAfterEvaluated("apply properties and language settings to ${kotlinTaskHolder.name}", kotlinTaskHolder) { propertiesProvider.mapKotlinTaskProperties(kotlinTaskHolder.get()) applyLanguageSettingsToKotlinOptions( - compilation.defaultSourceSet.languageSettings, + compilation.languageSettings, (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 } -internal class AndroidTasksProvider(targetName: String) : KotlinTasksProvider(targetName) { +internal class AndroidTasksProvider : KotlinTasksProvider() { override fun configure( kotlinTaskHolder: TaskProvider>, project: Project, propertiesProvider: PropertiesProvider, - compilation: KotlinCompilation<*> + compilation: KotlinCompilationData<*> ) { super.configure(kotlinTaskHolder, project, propertiesProvider, compilation) kotlinTaskHolder.configure { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/kotlinCompileTaskData.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/kotlinCompileTaskData.kt index 7e2a05fb0b6..41c5b290af9 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/kotlinCompileTaskData.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/kotlinCompileTaskData.kt @@ -10,21 +10,22 @@ import org.gradle.api.plugins.ExtraPropertiesExtension import org.gradle.api.provider.Property import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation 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 java.io.File internal open class KotlinCompileTaskData( val taskName: String, @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, val useModuleDetection: Property ) { private val project: Project - get() = compilation.target.project + get() = compilation.project 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 @@ -42,9 +43,9 @@ internal open class KotlinCompileTaskData( fun register( taskName: String, - compilation: KotlinCompilation<*> + compilation: KotlinCompilationData<*> ): KotlinCompileTaskData { - val project = compilation.target.project + val project = compilation.project val container = project.getTaskDataMap() @Suppress("UnstableApiUsage") diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.jetbrains.kotlin.multiplatform.pm20.properties b/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.jetbrains.kotlin.multiplatform.pm20.properties new file mode 100644 index 00000000000..0e3370e5635 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.jetbrains.kotlin.multiplatform.pm20.properties @@ -0,0 +1 @@ +implementation-class=org.jetbrains.kotlin.gradle.plugin.KotlinPm20PluginWrapper \ No newline at end of file diff --git a/libraries/tools/kotlin-project-model/src/main/kotlin/KotlinModuleFragment.kt b/libraries/tools/kotlin-project-model/src/main/kotlin/KotlinModuleFragment.kt index 254023a78b6..f349a45bf05 100644 --- a/libraries/tools/kotlin-project-model/src/main/kotlin/KotlinModuleFragment.kt +++ b/libraries/tools/kotlin-project-model/src/main/kotlin/KotlinModuleFragment.kt @@ -17,13 +17,12 @@ interface KotlinModuleFragment { // TODO: scopes val declaredModuleDependencies: Iterable + // TODO: should this be source roots or source files? val kotlinSourceRoots: Iterable } interface KotlinModuleVariant : KotlinModuleFragment { val variantAttributes: Map - - var isExported: Boolean } val KotlinModuleFragment.fragmentAttributeSets: Map> @@ -65,7 +64,6 @@ class BasicKotlinModuleVariant( containingModule, fragmentName ), KotlinModuleVariant { - override var isExported: Boolean = true override val variantAttributes: MutableMap = mutableMapOf() override fun toString(): String = "variant $fragmentName" } \ No newline at end of file diff --git a/libraries/tools/kotlin-project-model/src/test/kotlin/org/jetbrains/kotlin/project/model/DummyVariantMatchingImplementations.kt b/libraries/tools/kotlin-project-model/src/test/kotlin/org/jetbrains/kotlin/project/model/DummyVariantMatchingImplementations.kt index 7ca19b93c47..16976ae7625 100644 --- a/libraries/tools/kotlin-project-model/src/test/kotlin/org/jetbrains/kotlin/project/model/DummyVariantMatchingImplementations.kt +++ b/libraries/tools/kotlin-project-model/src/test/kotlin/org/jetbrains/kotlin/project/model/DummyVariantMatchingImplementations.kt @@ -9,7 +9,7 @@ class MatchVariantsByExactAttributes : ModuleVariantResolver { override fun getChosenVariant(requestingVariant: KotlinModuleVariant, dependencyModule: KotlinModule): VariantResolution { val candidates = dependencyModule.variants return candidates.filter { candidate -> - candidate.isExported && candidate.variantAttributes.all { (attributeKey, candidateValue) -> + candidate.variantAttributes.all { (attributeKey, candidateValue) -> attributeKey !in requestingVariant.variantAttributes.keys || candidateValue == requestingVariant.variantAttributes.getValue(attributeKey) }