From a67b2a8be501eb2e0f7e86145aa028d63d481561 Mon Sep 17 00:00:00 2001 From: Sebastian Sellmair Date: Wed, 28 Sep 2022 13:40:54 +0200 Subject: [PATCH] [Gradle] Implement KotlinJvmCompilation with new underlying KotlinCompilationImpl KT-54312 --- .idea/dictionaries/sebastiansellmair.xml | 1 + .../kotlin/gradle/plugin/KotlinCompilation.kt | 15 +- .../kotlin/gradle/plugin/Kotlin2JsPlugin.kt | 3 +- .../plugin/Kotlin2JsSourceSetProcessor.kt | 21 +- .../plugin/Kotlin2JvmSourceSetProcessor.kt | 18 +- .../gradle/plugin/KotlinCommonPlugin.kt | 2 +- .../plugin/KotlinCommonSourceSetProcessor.kt | 26 +- .../plugin/KotlinCompilationProcessor.kt | 14 +- .../plugin/KotlinCompilationProjection.kt | 155 ++++++++++++ .../plugin/KotlinJsIrSourceSetProcessor.kt | 19 +- .../kotlin/gradle/plugin/KotlinJvmPlugin.kt | 2 +- .../gradle/plugin/KotlinSourceSetProcessor.kt | 37 +-- .../gradle/plugin/KotlinTargetConfigurator.kt | 7 + .../plugin/mpp/AbstractKotlinCompilation.kt | 3 +- .../gradle/plugin/mpp/CompilationDetails.kt | 2 +- .../plugin/mpp/InternalKotlinCompilation.kt | 21 +- .../AbstractCompilationDetails.kt | 2 +- .../DefaultCompilationDetails.kt | 31 ++- .../KotlinCompilationDependencyAssociation.kt | 95 ++++++++ ...lationDependencyConfigurationsContainer.kt | 53 +++++ .../KotlinCompilationFriendPathsResolver.kt | 41 ++++ .../compilationImpl/KotlinCompilationImpl.kt | 223 ++++++++++++++++++ .../KotlinCompilationModuleManager.kt | 62 +++++ .../KotlinCompilationSourceSetInclusion.kt | 100 ++++++++ .../KotlinCompilationSourceSetsContainer.kt | 56 +++++ .../KotlinCompilationTaskContainer.kt | 11 + .../KotlinCompilationsModuleGroups.kt | 74 ------ .../GradleKpmCompilationTaskConfigurator.kt | 3 +- .../setupFragmentsMetadataForKpmModules.kt | 10 +- .../targets/android/AndroidProjectHandler.kt | 2 +- .../targets/js/KotlinJsTargetConfigurator.kt | 2 +- .../js/ir/KotlinJsIrTargetConfigurator.kt | 2 +- .../targets/jvm/KotlinJvmCompilation.kt | 91 ++++++- .../jvm/KotlinJvmCompilationFactory.kt | 183 ++++++++++++-- .../jvm/KotlinJvmTargetConfigurator.kt | 4 +- .../jvm/KotlinJvmWithJavaTargetPreset.kt | 2 +- .../KotlinMetadataTargetConfigurator.kt | 6 +- .../AbstractKotlinCompileConfig.kt | 17 +- .../configuration/KaptGenerateStubsConfig.kt | 20 +- .../configuration/Kotlin2JsCompileConfig.kt | 16 +- .../KotlinCompileCommonConfig.kt | 28 +-- .../configuration/KotlinCompileConfig.kt | 12 +- .../configuration/KotlinJsIrLinkConfig.kt | 8 +- .../kotlin/gradle/utils/providerApiUtils.kt | 4 +- .../KotlinCompilationsModuleGroupsTest.kt | 23 +- 45 files changed, 1246 insertions(+), 281 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCompilationProjection.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationDependencyAssociation.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationDependencyConfigurationsContainer.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationFriendPathsResolver.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationImpl.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationModuleManager.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationSourceSetInclusion.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationSourceSetsContainer.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationTaskContainer.kt delete mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/internal/KotlinCompilationsModuleGroups.kt diff --git a/.idea/dictionaries/sebastiansellmair.xml b/.idea/dictionaries/sebastiansellmair.xml index 1942f5d4e53..75a2abae6dc 100644 --- a/.idea/dictionaries/sebastiansellmair.xml +++ b/.idea/dictionaries/sebastiansellmair.xml @@ -2,6 +2,7 @@ actuals + associator cinterops instantiator interops diff --git a/libraries/tools/kotlin-gradle-plugin-api/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCompilation.kt b/libraries/tools/kotlin-gradle-plugin-api/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCompilation.kt index d22bf05fe1e..9806ce4b52d 100644 --- a/libraries/tools/kotlin-gradle-plugin-api/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCompilation.kt +++ b/libraries/tools/kotlin-gradle-plugin-api/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCompilation.kt @@ -9,6 +9,7 @@ package org.jetbrains.kotlin.gradle.plugin import org.gradle.api.Action import org.gradle.api.Named +import org.gradle.api.Project import org.gradle.api.attributes.AttributeContainer import org.gradle.api.attributes.HasAttributes import org.gradle.api.file.FileCollection @@ -20,6 +21,9 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask interface KotlinCompilation : Named, HasAttributes, HasKotlinDependencies { + + val project: Project + val target: KotlinTarget val compilationName: String @@ -40,6 +44,10 @@ interface KotlinCompilation : Named, var compileDependencyFiles: FileCollection + val runtimeDependencyConfigurationName: String? + + val runtimeDependencyFiles: FileCollection? + val output: KotlinCompilationOutput val platformType get() = target.platformType @@ -113,15 +121,18 @@ interface KotlinCompilation : Named, get() = target.disambiguationClassifier + name } +// TODO NOW: Revisit/Remove? interface KotlinCompilationToRunnableFiles : KotlinCompilation { - val runtimeDependencyConfigurationName: String + override val runtimeDependencyConfigurationName: String - var runtimeDependencyFiles: FileCollection + override var runtimeDependencyFiles: FileCollection override val relatedConfigurationNames: List get() = super.relatedConfigurationNames + runtimeDependencyConfigurationName } +@Deprecated("Scheduled for removal with Kotlin 1.9") +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") // kept for compatibility val KotlinCompilation.runtimeDependencyConfigurationName: String? get() = (this as? KotlinCompilationToRunnableFiles)?.runtimeDependencyConfigurationName diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/Kotlin2JsPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/Kotlin2JsPlugin.kt index 79990bd530b..68ecf3bc737 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/Kotlin2JsPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/Kotlin2JsPlugin.kt @@ -8,7 +8,6 @@ package org.jetbrains.kotlin.gradle.plugin import org.gradle.api.Project import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry import org.jetbrains.kotlin.gradle.dsl.* -import org.jetbrains.kotlin.gradle.dsl.CompilerJsOptionsDefault import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinCompilation import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaTarget import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider @@ -29,7 +28,7 @@ internal open class Kotlin2JsPlugin( project: Project, compilation: AbstractKotlinCompilation<*> ): KotlinSourceSetProcessor<*> = - Kotlin2JsSourceSetProcessor(tasksProvider, compilation) + Kotlin2JsSourceSetProcessor(tasksProvider, KotlinCompilationProjection(compilation)) override fun apply(project: Project) { @Suppress("UNCHECKED_CAST") diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/Kotlin2JsSourceSetProcessor.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/Kotlin2JsSourceSetProcessor.kt index 4299259972e..0ab69728b55 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/Kotlin2JsSourceSetProcessor.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/Kotlin2JsSourceSetProcessor.kt @@ -10,7 +10,6 @@ import org.gradle.api.tasks.SourceSet import org.gradle.api.tasks.TaskProvider import org.jetbrains.kotlin.gradle.dsl.CompilerJsOptions import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaCompilation -import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider import org.jetbrains.kotlin.gradle.tasks.configuration.Kotlin2JsCompileConfig @@ -18,41 +17,39 @@ import java.io.File internal class Kotlin2JsSourceSetProcessor( tasksProvider: KotlinTasksProvider, - kotlinCompilation: KotlinCompilationData<*> + kotlinCompilation: KotlinCompilationProjection ) : KotlinSourceSetProcessor( tasksProvider, taskDescription = "Compiles the Kotlin sources in $kotlinCompilation to JavaScript.", kotlinCompilation = kotlinCompilation ) { override fun doRegisterTask(project: Project, taskName: String): TaskProvider { - val configAction = Kotlin2JsCompileConfig(kotlinCompilation) + val configAction = Kotlin2JsCompileConfig(compilationProjection) applyStandardTaskConfiguration(configAction) return tasksProvider.registerKotlinJSTask( project, taskName, - kotlinCompilation.compilerOptions.options as CompilerJsOptions, + compilationProjection.compilerOptions.options as CompilerJsOptions, configAction ) } override fun doTargetSpecificProcessing() { - project.tasks.named(kotlinCompilation.compileAllTaskName).configure { + project.tasks.named(compilationProjection.compileAllTaskName).configure { it.dependsOn(kotlinTask) } - if (kotlinCompilation is KotlinWithJavaCompilation<*, *>) { - kotlinCompilation.javaSourceSet.clearJavaSrcDirs() - } - + compilationProjection.tcsOrNull?.compilation?.run { this as? KotlinWithJavaCompilation<*, *> }?.javaSourceSet?.clearJavaSrcDirs() project.whenEvaluated { val subpluginEnvironment: SubpluginEnvironment = SubpluginEnvironment.loadSubplugins(project) - if (kotlinCompilation is KotlinCompilation<*>) { // FIXME support compiler plugins with PM20 - subpluginEnvironment.addSubpluginOptions(project, kotlinCompilation) + + /* Not supported in KPM */ + compilationProjection.tcsOrNull?.compilation?.let { compilation -> + subpluginEnvironment.addSubpluginOptions(project, compilation) } } } - } private fun SourceSet.clearJavaSrcDirs() { diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/Kotlin2JvmSourceSetProcessor.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/Kotlin2JvmSourceSetProcessor.kt index 67fe2969020..662088fbc80 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/Kotlin2JvmSourceSetProcessor.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/Kotlin2JvmSourceSetProcessor.kt @@ -13,7 +13,6 @@ import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.compile.AbstractCompile import org.jetbrains.kotlin.gradle.dsl.CompilerJvmOptions import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin -import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData import org.jetbrains.kotlin.gradle.scripting.internal.ScriptingGradleSubplugin import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider @@ -23,33 +22,34 @@ import org.jetbrains.kotlin.gradle.utils.whenKaptEnabled internal class Kotlin2JvmSourceSetProcessor( tasksProvider: KotlinTasksProvider, - kotlinCompilation: KotlinCompilationData<*> + kotlinCompilation: KotlinCompilationProjection ) : KotlinSourceSetProcessor( tasksProvider, "Compiles the $kotlinCompilation.", kotlinCompilation ) { override fun doRegisterTask(project: Project, taskName: String): TaskProvider { - val configAction = KotlinCompileConfig(kotlinCompilation) + val configAction = KotlinCompileConfig(compilationProjection) applyStandardTaskConfiguration(configAction) return tasksProvider.registerKotlinJVMTask( project, taskName, - kotlinCompilation.compilerOptions.options as CompilerJvmOptions, + compilationProjection.compilerOptions.options as CompilerJvmOptions, configAction ) } override fun doTargetSpecificProcessing() { project.whenKaptEnabled { - Kapt3GradleSubplugin.createAptConfigurationIfNeeded(project, kotlinCompilation.compilationPurpose) + Kapt3GradleSubplugin.createAptConfigurationIfNeeded(project, compilationProjection.compilationName) } - ScriptingGradleSubplugin.configureForSourceSet(project, kotlinCompilation.compilationPurpose) + ScriptingGradleSubplugin.configureForSourceSet(project, compilationProjection.compilationName) project.whenEvaluated { val subpluginEnvironment = SubpluginEnvironment.loadSubplugins(project) - - if (kotlinCompilation is KotlinCompilation<*>) // FIXME support compiler plugins with PM20 - subpluginEnvironment.addSubpluginOptions(project, kotlinCompilation) + /* Not supported in KPM yet */ + compilationProjection.tcsOrNull?.compilation?.let { compilation -> + subpluginEnvironment.addSubpluginOptions(project, compilation) + } javaSourceSet?.let { java -> val javaTask = project.tasks.withType().named(java.compileJavaTaskName) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCommonPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCommonPlugin.kt index 7b4cd0a7435..c9054924edd 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCommonPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCommonPlugin.kt @@ -24,7 +24,7 @@ internal open class KotlinCommonPlugin( project: Project, compilation: AbstractKotlinCompilation<*> ): KotlinSourceSetProcessor<*> = - KotlinCommonSourceSetProcessor(compilation, tasksProvider) + KotlinCommonSourceSetProcessor(KotlinCompilationProjection(compilation), tasksProvider) override fun apply(project: Project) { @Suppress("UNCHECKED_CAST") diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCommonSourceSetProcessor.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCommonSourceSetProcessor.kt index 84dfcff676f..b38e540560d 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCommonSourceSetProcessor.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCommonSourceSetProcessor.kt @@ -9,9 +9,6 @@ import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.tasks.TaskProvider import org.jetbrains.kotlin.gradle.dsl.CompilerMultiplatformCommonOptions -import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinCompilation -import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData -import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.isMainCompilationData import org.jetbrains.kotlin.gradle.tasks.KotlinCompileCommon import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider import org.jetbrains.kotlin.gradle.tasks.configuration.KotlinCompileCommonConfig @@ -19,33 +16,36 @@ import org.jetbrains.kotlin.gradle.tasks.dependsOn import org.jetbrains.kotlin.gradle.tasks.locateTask internal class KotlinCommonSourceSetProcessor( - compilation: KotlinCompilationData<*>, + compilation: KotlinCompilationProjection, tasksProvider: KotlinTasksProvider ) : KotlinSourceSetProcessor( tasksProvider, taskDescription = "Compiles the kotlin sources in $compilation to Metadata.", kotlinCompilation = compilation ) { override fun doTargetSpecificProcessing() { - project.tasks.named(kotlinCompilation.compileAllTaskName).dependsOn(kotlinTask) + project.tasks.named(compilationProjection.compileAllTaskName).dependsOn(kotlinTask) // can be missing (e.g. in case of tests) - if ((kotlinCompilation as? AbstractKotlinCompilation<*>)?.isMainCompilationData() == true) { - project.locateTask(kotlinCompilation.target.artifactsTaskName)?.dependsOn(kotlinTask) + if (compilationProjection.isMain) { + compilationProjection.tcsOrNull?.compilation?.target?.let { target -> + project.locateTask(target.artifactsTaskName)?.dependsOn(kotlinTask) + } } - if (kotlinCompilation is KotlinCompilation<*>) { - project.whenEvaluated { - val subpluginEnvironment: SubpluginEnvironment = SubpluginEnvironment.loadSubplugins(project) - subpluginEnvironment.addSubpluginOptions(project, kotlinCompilation) + project.whenEvaluated { + val subpluginEnvironment: SubpluginEnvironment = SubpluginEnvironment.loadSubplugins(project) + /* Not supported in KPM yet */ + compilationProjection.tcsOrNull?.compilation?.let { compilation -> + subpluginEnvironment.addSubpluginOptions(project, compilation) } } } override fun doRegisterTask(project: Project, taskName: String): TaskProvider { - val configAction = KotlinCompileCommonConfig(kotlinCompilation) + val configAction = KotlinCompileCommonConfig(compilationProjection) applyStandardTaskConfiguration(configAction) return tasksProvider.registerKotlinCommonTask( project, taskName, - kotlinCompilation.compilerOptions.options as CompilerMultiplatformCommonOptions, + compilationProjection.compilerOptions.options as CompilerMultiplatformCommonOptions, configAction ) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCompilationProcessor.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCompilationProcessor.kt index 3f45c8ab2a3..3a52ef5a7e2 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCompilationProcessor.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCompilationProcessor.kt @@ -11,17 +11,17 @@ import org.gradle.api.provider.Provider import org.gradle.api.tasks.TaskProvider import org.jetbrains.kotlin.gradle.dsl.KotlinSingleJavaTargetExtension import org.jetbrains.kotlin.gradle.dsl.topLevelExtension -import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompileTool -abstract class KotlinCompilationProcessor>( - open val kotlinCompilation: KotlinCompilationData<*> +abstract class KotlinCompilationProcessor> internal constructor( + internal val compilationProjection: KotlinCompilationProjection ) { + abstract val kotlinTask: TaskProvider abstract fun run() protected val project: Project - get() = kotlinCompilation.project + get() = compilationProjection.project protected val defaultKotlinDestinationDir: Provider get() { @@ -30,7 +30,7 @@ abstract class KotlinCompilationProcessor>( if (kotlinExt is KotlinSingleJavaTargetExtension) "" // In single-target projects, don't add the target name part to this path else - kotlinCompilation.compilationClassifier?.let { "$it/" }.orEmpty() - return project.layout.buildDirectory.dir("classes/kotlin/$targetSubDirectory${kotlinCompilation.compilationPurpose}") + compilationProjection.targetDisambiguationClassifier?.let { "$it/" }.orEmpty() + return project.layout.buildDirectory.dir("classes/kotlin/$targetSubDirectory${compilationProjection.compilationName}") } -} \ No newline at end of file +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCompilationProjection.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCompilationProjection.kt new file mode 100644 index 00000000000..5445010dcde --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCompilationProjection.kt @@ -0,0 +1,155 @@ +/* + * Copyright 2010-2022 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. + */ + +@file:Suppress("FunctionName") + +package org.jetbrains.kotlin.gradle.plugin + +import org.gradle.api.Project +import org.gradle.api.file.ConfigurableFileCollection +import org.gradle.api.file.FileCollection +import org.gradle.api.file.SourceDirectorySet +import org.jetbrains.kotlin.gradle.plugin.mpp.internal +import org.jetbrains.kotlin.gradle.plugin.mpp.isMain +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.isMainCompilationData +import org.jetbrains.kotlin.gradle.utils.filesProvider +import org.jetbrains.kotlin.project.model.LanguageSettings + +internal sealed class KotlinCompilationProjection { + abstract val origin: Any + abstract val project: Project + abstract val platformType: KotlinPlatformType + abstract val targetDisambiguationClassifier: String? + abstract val compilationName: String + abstract val ownModuleName: String + abstract val moduleName: String + abstract val compilerOptions: HasCompilerOptions<*> + abstract val compileKotlinTaskName: String + abstract val compileAllTaskName: String + abstract val languageSettings: LanguageSettings + abstract val friendPaths: FileCollection + abstract val isMain: Boolean + abstract val classesDirs: ConfigurableFileCollection + abstract val compileDependencyFiles: FileCollection + abstract val sources: List + + class TCS(val compilation: KotlinCompilation<*>) : KotlinCompilationProjection() { + + override val origin: KotlinCompilation<*> = compilation + + override val project: Project + get() = origin.project + + override val platformType: KotlinPlatformType + get() = origin.platformType + + override val targetDisambiguationClassifier: String? + get() = origin.target.disambiguationClassifier + + override val compilationName: String + get() = origin.compilationName + + override val ownModuleName: String + get() = origin.internal.compilationModule.ownModuleName.get() + + override val moduleName: String + get() = origin.internal.moduleName + + override val compilerOptions: HasCompilerOptions<*> + get() = origin.compilerOptions + + override val compileKotlinTaskName: String + get() = origin.compileKotlinTaskName + + override val compileAllTaskName: String + get() = origin.compileAllTaskName + + override val languageSettings: LanguageSettings + get() = origin.defaultSourceSet.languageSettings + + override val friendPaths: FileCollection + get() = project.filesProvider { origin.internal.friendPaths } + + override val isMain: Boolean + get() = origin.isMain() + + override val classesDirs: ConfigurableFileCollection + get() = origin.output.classesDirs + + override val compileDependencyFiles: FileCollection + get() = project.filesProvider { origin.compileDependencyFiles } + + override val sources: List + get() = origin.allKotlinSourceSets.map { it.kotlin } + } + + class KPM(val compilationData: KotlinCompilationData<*>) : KotlinCompilationProjection() { + + override val origin: KotlinCompilationData<*> = compilationData + + override val project: Project + get() = origin.project + + override val platformType: KotlinPlatformType + get() = origin.platformType + + override val targetDisambiguationClassifier: String? + get() = origin.compilationClassifier + + override val compilationName: String + get() = origin.compilationPurpose + + override val ownModuleName: String + get() = origin.ownModuleName + + override val moduleName: String + get() = origin.moduleName + + override val compilerOptions: HasCompilerOptions<*> + get() = origin.compilerOptions + + override val compileKotlinTaskName: String + get() = origin.compileKotlinTaskName + + override val compileAllTaskName: String + get() = origin.compileAllTaskName + + override val languageSettings: LanguageSettings + get() = origin.languageSettings + + override val friendPaths: FileCollection + get() = project.filesProvider { origin.friendPaths } + + override val isMain: Boolean + get() = origin.isMainCompilationData() + + override val classesDirs: ConfigurableFileCollection + get() = origin.output.classesDirs + + override val compileDependencyFiles: FileCollection + get() = project.filesProvider { origin.compileDependencyFiles } + + override val sources: List + get() = origin.kotlinSourceDirectoriesByFragmentName.values.toList() + + } +} + +internal fun KotlinCompilationProjection(compilation: KotlinCompilation<*>): KotlinCompilationProjection.TCS { + return KotlinCompilationProjection.TCS(compilation) +} + +internal val KotlinCompilationProjection.tcsOrNull: KotlinCompilationProjection.TCS? + get() = when (this) { + is KotlinCompilationProjection.KPM -> null + is KotlinCompilationProjection.TCS -> this + } + +internal val KotlinCompilationProjection.kpmOrNull: KotlinCompilationProjection.KPM? + get() = when (this) { + is KotlinCompilationProjection.KPM -> this + is KotlinCompilationProjection.TCS -> null + } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinJsIrSourceSetProcessor.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinJsIrSourceSetProcessor.kt index e2acebb95f3..337bf394a6a 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinJsIrSourceSetProcessor.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinJsIrSourceSetProcessor.kt @@ -8,7 +8,6 @@ package org.jetbrains.kotlin.gradle.plugin import org.gradle.api.Project import org.gradle.api.tasks.TaskProvider import org.jetbrains.kotlin.gradle.dsl.CompilerJsOptions -import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinCompilation import org.jetbrains.kotlin.gradle.targets.js.ir.JsIrBinary import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrCompilation import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile @@ -18,28 +17,28 @@ import org.jetbrains.kotlin.gradle.tasks.configuration.KotlinJsIrLinkConfig internal class KotlinJsIrSourceSetProcessor( tasksProvider: KotlinTasksProvider, - kotlinCompilation: AbstractKotlinCompilation<*> + kotlinCompilation: KotlinCompilationProjection ) : KotlinSourceSetProcessor( tasksProvider, taskDescription = "Compiles the Kotlin sources in $kotlinCompilation to JavaScript.", kotlinCompilation = kotlinCompilation ) { override fun doRegisterTask(project: Project, taskName: String): TaskProvider { - val configAction = Kotlin2JsCompileConfig(kotlinCompilation) + val configAction = Kotlin2JsCompileConfig(compilationProjection) applyStandardTaskConfiguration(configAction) return tasksProvider.registerKotlinJSTask( project, taskName, - kotlinCompilation.compilerOptions.options as CompilerJsOptions, + compilationProjection.compilerOptions.options as CompilerJsOptions, configAction ) } override fun doTargetSpecificProcessing() { - project.tasks.named(kotlinCompilation.compileAllTaskName).configure { + project.tasks.named(compilationProjection.compileAllTaskName).configure { it.dependsOn(kotlinTask) } - val compilation = kotlinCompilation as KotlinJsIrCompilation + val compilation = compilationProjection.tcsOrNull?.compilation as KotlinJsIrCompilation compilation.binaries .withType(JsIrBinary::class.java) @@ -47,7 +46,7 @@ internal class KotlinJsIrSourceSetProcessor( val configAction = KotlinJsIrLinkConfig(binary) configAction.configureTask { it.description = taskDescription - it.libraries.from({ kotlinCompilation.compileDependencyFiles }) + it.libraries.from({ compilationProjection.compileDependencyFiles }) } configAction.configureTask { task -> task.modeProperty.set(binary.mode) @@ -59,7 +58,11 @@ internal class KotlinJsIrSourceSetProcessor( project.whenEvaluated { val subpluginEnvironment: SubpluginEnvironment = SubpluginEnvironment.loadSubplugins(project) - subpluginEnvironment.addSubpluginOptions(project, kotlinCompilation) + /* Not supported in KPM, yet */ + compilationProjection.tcsOrNull?.compilation?.let { compilation -> + subpluginEnvironment.addSubpluginOptions(project, compilation) + + } } } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinJvmPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinJvmPlugin.kt index 5b23a925b55..637aff2c814 100755 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinJvmPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinJvmPlugin.kt @@ -38,7 +38,7 @@ internal open class KotlinJvmPlugin( } override fun buildSourceSetProcessor(project: Project, compilation: AbstractKotlinCompilation<*>) = - Kotlin2JvmSourceSetProcessor(tasksProvider, compilation) + Kotlin2JvmSourceSetProcessor(tasksProvider, KotlinCompilationProjection(compilation)) override fun apply(project: Project) { @Suppress("UNCHECKED_CAST") diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinSourceSetProcessor.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinSourceSetProcessor.kt index 370625954b0..d59334bbbc4 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinSourceSetProcessor.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinSourceSetProcessor.kt @@ -15,7 +15,6 @@ import org.gradle.api.tasks.TaskProvider import org.jetbrains.kotlin.gradle.plugin.internal.JavaSourceSetsAccessor import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmCompilation import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaCompilation -import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile @@ -27,39 +26,41 @@ import java.util.concurrent.Callable internal abstract class KotlinSourceSetProcessor>( val tasksProvider: KotlinTasksProvider, val taskDescription: String, - kotlinCompilation: KotlinCompilationData<*> + kotlinCompilation: KotlinCompilationProjection ) : KotlinCompilationProcessor(kotlinCompilation) { protected abstract fun doTargetSpecificProcessing() protected val logger = Logging.getLogger(this.javaClass)!! - protected val sourceSetName: String = kotlinCompilation.compilationPurpose + protected val sourceSetName: String = kotlinCompilation.compilationName override val kotlinTask: TaskProvider = prepareKotlinCompileTask() protected val javaSourceSet: SourceSet? get() { - val compilation = kotlinCompilation + if (compilationProjection !is KotlinCompilationProjection.TCS) return null + val compilation = compilationProjection.origin + val target = compilationProjection.origin.target + return (compilation as? KotlinWithJavaCompilation<*, *>)?.javaSourceSet - ?: kotlinCompilation.owner.let { - if (it is KotlinJvmTarget && it.withJavaEnabled && compilation is KotlinJvmCompilation) - project.gradle.variantImplementationFactory() - .getInstance(project) - .sourceSets - .maybeCreate(compilation.name) - else null - } + ?: if (target is KotlinJvmTarget && target.withJavaEnabled && compilation is KotlinJvmCompilation) + project.gradle.variantImplementationFactory() + .getInstance(project) + .sourceSets + .maybeCreate(compilation.name) + else null + } private fun prepareKotlinCompileTask(): TaskProvider = - doRegisterTask(project, kotlinCompilation.compileKotlinTaskName).also { task -> - kotlinCompilation.output.classesDirs.from(task.flatMap { it.destinationDirectory }) + doRegisterTask(project, compilationProjection.compileKotlinTaskName).also { task -> + compilationProjection.classesDirs.from(task.flatMap { it.destinationDirectory }) } override fun run() { addKotlinDirectoriesToJavaSourceSet() doTargetSpecificProcessing() - if (kotlinCompilation is KotlinWithJavaCompilation<*, *>) { + if (compilationProjection.tcsOrNull?.compilation is KotlinWithJavaCompilation<*, *>) { createAdditionalClassesTaskForIdeRunner() } } @@ -69,7 +70,7 @@ internal abstract class KotlinSourceSetProcessor>( // Try to avoid duplicate Java sources in allSource; run lazily to allow changing the directory set: val kotlinSrcDirsToAdd = Callable { - kotlinCompilation.kotlinSourceDirectoriesByFragmentName.values.map { filterOutJavaSrcDirsIfPossible(it) } + compilationProjection.sources.map { filterOutJavaSrcDirsIfPossible(it) } } java.allJava.srcDirs(kotlinSrcDirsToAdd) @@ -84,7 +85,7 @@ internal abstract class KotlinSourceSetProcessor>( } private fun createAdditionalClassesTaskForIdeRunner() { - val kotlinCompilation = kotlinCompilation as? KotlinCompilation<*> ?: return + val kotlinCompilation = compilationProjection.tcsOrNull?.compilation ?: 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 @@ -108,7 +109,7 @@ internal abstract class KotlinSourceSetProcessor>( } else { it.destinationDirectory.convention(defaultKotlinDestinationDir) } - it.libraries.from({ kotlinCompilation.compileDependencyFiles }) + it.libraries.from({ compilationProjection.compileDependencyFiles }) } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetConfigurator.kt index 6980d258a5e..cf30ea9f87d 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetConfigurator.kt @@ -30,6 +30,7 @@ import org.gradle.language.jvm.tasks.ProcessResources import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions import org.jetbrains.kotlin.gradle.internal.reorderPluginClasspathDependencies import org.jetbrains.kotlin.gradle.plugin.mpp.* +import org.jetbrains.kotlin.gradle.plugin.sources.internal import org.jetbrains.kotlin.gradle.targets.js.KotlinJsCompilerAttribute import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget @@ -106,6 +107,10 @@ abstract class AbstractKotlinTargetConfigurator val project = target.project target.compilations.all { compilation -> + compilation.internal.allKotlinSourceSets.forAll { sourceSet -> + sourceSet.internal.compilations.add(compilation) + } + defineConfigurationsForCompilation(compilation) if (compilation is KotlinCompilationWithResources) { @@ -297,6 +302,8 @@ abstract class AbstractKotlinTargetConfigurator val apiConfiguration = configurations.maybeCreate(compilation.apiConfigurationName).apply { compileConfiguration?.let { extendsFrom(it) } + + // TODP NOW: Remove duplicate isVisible = false isCanBeConsumed = false isCanBeResolved = false diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/AbstractKotlinCompilation.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/AbstractKotlinCompilation.kt index def31711841..d1731e9f15f 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/AbstractKotlinCompilation.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/AbstractKotlinCompilation.kt @@ -50,6 +50,7 @@ abstract class AbstractKotlinCompilation( final override val output: KotlinCompilationOutput get() = compilationData.output final override val compileKotlinTaskName: String get() = compilationData.compileKotlinTaskName + override val compilerOptions: HasCompilerOptions<*> get() = compilationData.compilerOptions @@ -71,7 +72,7 @@ abstract class AbstractKotlinCompilation( } final override val kotlinSourceSets: ObservableSet - get() = compilationDetails.directlyIncludedKotlinSourceSets + get() = compilationDetails.kotlinSourceSets override val allKotlinSourceSets: ObservableSet get() = compilationDetails.allKotlinSourceSets diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/CompilationDetails.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/CompilationDetails.kt index 5ec81b63a75..f0feee0d074 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/CompilationDetails.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/CompilationDetails.kt @@ -28,7 +28,7 @@ interface CompilationDetails { fun source(sourceSet: KotlinSourceSet) - val directlyIncludedKotlinSourceSets: ObservableSet + val kotlinSourceSets: ObservableSet val allKotlinSourceSets: ObservableSet diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/InternalKotlinCompilation.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/InternalKotlinCompilation.kt index 30e28abd3be..f3ac87786db 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/InternalKotlinCompilation.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/InternalKotlinCompilation.kt @@ -5,14 +5,33 @@ package org.jetbrains.kotlin.gradle.plugin.mpp +import org.gradle.api.file.FileCollection import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationModuleManager +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationModuleManager.CompilationModule.Type.Auxiliary +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationModuleManager.CompilationModule.Type.Main import org.jetbrains.kotlin.gradle.utils.ObservableSet -internal interface InternalKotlinCompilation : KotlinCompilation { +internal interface InternalKotlinCompilation : KotlinCompilation { override val kotlinSourceSets: ObservableSet override val allKotlinSourceSets: ObservableSet + val friendPaths: Iterable + + // TODO NOW: Remove default impl + val compilationModule: KotlinCompilationModuleManager.CompilationModule + get() = KotlinCompilationModuleManager.CompilationModule( + compilationName = compilationName, + ownModuleName = project.provider { (this as AbstractKotlinCompilation<*>).ownModuleName }, + type = if (isMain()) Main else Auxiliary + ) + + // TODO NOW: Remove default impl + override val runtimeDependencyFiles: FileCollection? get() = null + override val runtimeDependencyConfigurationName: String? get() = null + val processResourcesTaskName: String? get() = null + } internal val KotlinCompilation.internal: InternalKotlinCompilation diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationDetailsImpl/AbstractCompilationDetails.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationDetailsImpl/AbstractCompilationDetails.kt index ad0c4139012..87e0e7b9857 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationDetailsImpl/AbstractCompilationDetails.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationDetailsImpl/AbstractCompilationDetails.kt @@ -18,7 +18,7 @@ internal abstract class AbstractCompilationDetails( ) : CompilationDetails { private val directlyIncludedKotlinSourceSetsImpl: MutableObservableSet = MutableObservableSetImpl(defaultSourceSet) - final override val directlyIncludedKotlinSourceSets: ObservableSet + final override val kotlinSourceSets: ObservableSet get() = directlyIncludedKotlinSourceSetsImpl private val allKotlinSourceSetsImpl: MutableObservableSet = MutableObservableSetImpl().also { set -> diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationDetailsImpl/DefaultCompilationDetails.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationDetailsImpl/DefaultCompilationDetails.kt index 58ceedc7c00..9795598c4fb 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationDetailsImpl/DefaultCompilationDetails.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationDetailsImpl/DefaultCompilationDetails.kt @@ -17,10 +17,9 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions import org.jetbrains.kotlin.gradle.dsl.kotlinExtension import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.mpp.* -import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinDependencyConfigurationsHolder -import org.jetbrains.kotlin.gradle.plugin.mpp.addSourcesToKotlinCompileTask -import org.jetbrains.kotlin.gradle.plugin.mpp.filterModuleName -import org.jetbrains.kotlin.gradle.plugin.mpp.internal.KotlinCompilationsModuleGroups +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationModuleManager +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationModuleManager.CompilationModule.Type +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.kotlinCompilationModuleManager import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.isMainCompilationData import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.GradleKpmDependencyFilesHolder @@ -80,7 +79,7 @@ internal open class DefaultCompilationDetails - get() = directlyIncludedKotlinSourceSets.withDependsOnClosure.associate { it.name to it.kotlin } + get() = kotlinSourceSets.withDependsOnClosure.associate { it.name to it.kotlin } override val compileKotlinTaskName: String get() = lowerCamelCaseName( @@ -107,16 +106,22 @@ internal open class DefaultCompilationDetails get() = mutableListOf().also { allCollections -> @@ -169,7 +174,7 @@ internal open class DefaultCompilationDetails, second: InternalKotlinCompilation<*>) +} + +internal object DefaultKotlinCompilationAssociator : KotlinCompilationAssociator { + override fun associate(target: KotlinTarget, first: InternalKotlinCompilation<*>, second: InternalKotlinCompilation<*>) { + target.project.kotlinCompilationModuleManager.unionModules(first.compilationModule, second.compilationModule) + val project = target.project + + /* + we add dependencies to compileDependencyConfiguration ('compileClasspath' usually) and runtimeDependency + ('runtimeClasspath') instead of modifying respective api/implementation/compileOnly/runtimeOnly configs + + This is needed because api/implementation/compileOnly/runtimeOnly are used in IDE Import and will leak + to dependencies of IDE modules. But they are not needed here, because IDE resolution works inherently + transitively and symbols from associated compilation will be resolved from source sets of associated + compilation itself (moreover, direct dependencies are not equivalent to transitive ones because of + resolution order - e.g. in case of FQNs clash, so it's even harmful) + */ + project.dependencies.add(first.compileOnlyConfigurationName, project.files({ second.output.classesDirs })) + project.dependencies.add(first.runtimeOnlyConfigurationName, project.files({ second.output.allOutputs })) + + first.compileDependencyConfigurationName.addAllDependenciesFromOtherConfigurations( + project, + second.apiConfigurationName, + second.implementationConfigurationName, + second.compileOnlyConfigurationName + ) + + first.runtimeDependencyConfigurationName?.addAllDependenciesFromOtherConfigurations( + project, + second.apiConfigurationName, + second.implementationConfigurationName, + second.runtimeOnlyConfigurationName + ) + } + + /** + * Adds `allDependencies` of configurations mentioned in `configurationNames` to configuration named [this] in + * a lazy manner + */ + private fun String.addAllDependenciesFromOtherConfigurations(project: Project, vararg configurationNames: String) { + project.configurations.named(this).configure { receiverConfiguration -> + receiverConfiguration.dependencies.addAllLater( + project.objects.listProperty(Dependency::class.java).apply { + set( + project.provider { + configurationNames + .map { project.configurations.getByName(it) } + .flatMap { it.allDependencies } + } + ) + } + ) + } + } +} + +internal object KotlinNativeCompilationAssociator : KotlinCompilationAssociator { + override fun associate(target: KotlinTarget, first: InternalKotlinCompilation<*>, second: InternalKotlinCompilation<*>) { + target.project.kotlinCompilationModuleManager.unionModules(first.compilationModule, second.compilationModule) + + first.compileDependencyFiles += + second.output.classesDirs + target.project.filesProvider { second.compileDependencyFiles } + + target.project.configurations.named(first.implementationConfigurationName).configure { configuration -> + configuration.extendsFrom(target.project.configurations.findByName(second.implementationConfigurationName)) + } + } +} + +internal object KotlinJvmWithJavaCompilationAssociator : KotlinCompilationAssociator { + override fun associate(target: KotlinTarget, first: InternalKotlinCompilation<*>, second: InternalKotlinCompilation<*>) { + target.project.kotlinCompilationModuleManager.unionModules(first.compilationModule, second.compilationModule) + if (first.compilationName != SourceSet.TEST_SOURCE_SET_NAME || second.compilationName != SourceSet.MAIN_SOURCE_SET_NAME) { + DefaultKotlinCompilationAssociator.associate(target, first, second) + } // otherwise, do nothing: the Java Gradle plugin adds these dependencies for us, we don't need to add them to the classpath + } +} + + diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationDependencyConfigurationsContainer.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationDependencyConfigurationsContainer.kt new file mode 100644 index 00000000000..421087e5dda --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationDependencyConfigurationsContainer.kt @@ -0,0 +1,53 @@ +/* + * Copyright 2010-2022 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.compilationImpl + +import org.gradle.api.Action +import org.gradle.api.Project +import org.gradle.api.artifacts.Configuration +import org.jetbrains.kotlin.gradle.plugin.HasKotlinDependencies +import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler +import org.jetbrains.kotlin.gradle.plugin.mpp.DefaultKotlinDependencyHandler + +internal interface KotlinCompilationDependencyConfigurationsContainer { + val apiConfiguration: Configuration + val implementationConfiguration: Configuration + val compileOnlyConfiguration: Configuration + val runtimeOnlyConfiguration: Configuration + val compileDependencyConfiguration: Configuration + val runtimeDependencyConfiguration: Configuration? +} + +internal class DefaultKotlinCompilationDependencyConfigurationsContainer( + override val apiConfiguration: Configuration, + override val implementationConfiguration: Configuration, + override val compileOnlyConfiguration: Configuration, + override val runtimeOnlyConfiguration: Configuration, + override val compileDependencyConfiguration: Configuration, + override val runtimeDependencyConfiguration: Configuration? +) : KotlinCompilationDependencyConfigurationsContainer + +internal fun HasKotlinDependencies( + project: Project, compilationDependencyContainer: KotlinCompilationDependencyConfigurationsContainer +): HasKotlinDependencies = object : HasKotlinDependencies { + override fun dependencies(configure: KotlinDependencyHandler.() -> Unit): Unit = + DefaultKotlinDependencyHandler(this, project).run(configure) + + override fun dependencies(configure: Action) = + dependencies { configure.execute(this) } + + override val apiConfigurationName: String + get() = compilationDependencyContainer.apiConfiguration.name + + override val implementationConfigurationName: String + get() = compilationDependencyContainer.implementationConfiguration.name + + override val compileOnlyConfigurationName: String + get() = compilationDependencyContainer.compileOnlyConfiguration.name + + override val runtimeOnlyConfigurationName: String + get() = compilationDependencyContainer.runtimeOnlyConfiguration.name +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationFriendPathsResolver.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationFriendPathsResolver.kt new file mode 100644 index 00000000000..23b4440bcd5 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationFriendPathsResolver.kt @@ -0,0 +1,41 @@ +/* + * Copyright 2010-2022 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.compilationImpl + +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.mpp.InternalKotlinCompilation +import org.jetbrains.kotlin.gradle.plugin.mpp.associateWithClosure +import org.jetbrains.kotlin.gradle.plugin.mpp.isMain +import org.jetbrains.kotlin.gradle.utils.filesProvider + +internal interface KotlinCompilationFriendPathsResolver { + fun resolveFriendPaths(compilation: InternalKotlinCompilation<*>): Iterable +} + +internal object DefaultKotlinCompilationFriendPathsResolver : KotlinCompilationFriendPathsResolver { + override fun resolveFriendPaths(compilation: InternalKotlinCompilation<*>): Iterable { + return mutableListOf().also { allCollections -> + compilation.associateWithClosure.forEach { allCollections.add(it.output.classesDirs) } + allCollections.add(resolveFriendArtifacts(compilation)) + } + } + + private fun resolveFriendArtifacts(compilation: InternalKotlinCompilation<*>): FileCollection { + return with(compilation.project) { + val friendArtifactsTaskProvider = resolveFriendArtifactsTask(compilation) ?: return files() + filesProvider { friendArtifactsTaskProvider.flatMap { it.archiveFile } } + } + } + + private fun resolveFriendArtifactsTask(compilation: InternalKotlinCompilation<*>): TaskProvider? { + if (compilation.associateWithClosure.none { it.isMain() }) return null + val archiveTasks = compilation.project.tasks.withType(AbstractArchiveTask::class.java) + if (compilation.target.artifactsTaskName !in archiveTasks.names) return null + return archiveTasks.named(compilation.target.artifactsTaskName) + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationImpl.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationImpl.kt new file mode 100644 index 00000000000..1544d4e566c --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationImpl.kt @@ -0,0 +1,223 @@ +/* + * Copyright 2010-2022 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. + */ + +@file:Suppress("DEPRECATION") + +package org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl + +import org.gradle.api.Action +import org.gradle.api.GradleException +import org.gradle.api.attributes.AttributeContainer +import org.gradle.api.file.FileCollection +import org.gradle.api.tasks.TaskProvider +import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions +import org.jetbrains.kotlin.gradle.dsl.KotlinCompile +import org.jetbrains.kotlin.gradle.plugin.* +import org.jetbrains.kotlin.gradle.plugin.mpp.HierarchyAttributeContainer +import org.jetbrains.kotlin.gradle.plugin.mpp.InternalKotlinCompilation +import org.jetbrains.kotlin.gradle.plugin.mpp.internal +import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask +import org.jetbrains.kotlin.gradle.tasks.locateTask +import org.jetbrains.kotlin.gradle.utils.ObservableSet +import javax.inject.Inject + + +internal class KotlinCompilationImpl @Inject constructor( + private val params: Params +) : InternalKotlinCompilation { + + //region Params + + data class Params( + val target: KotlinTarget, + val compilationModule: KotlinCompilationModuleManager.CompilationModule, + val sourceSets: KotlinCompilationSourceSetsContainer, + val dependencyConfigurations: KotlinCompilationDependencyConfigurationsContainer, + val compilationTaskNames: KotlinCompilationTaskNameContainer, + val processResourcesTaskName: String?, + val output: KotlinCompilationOutput, + val compilerOptions: HasCompilerOptions<*>, + val kotlinOptions: KotlinCommonOptions, + val compilationAssociator: KotlinCompilationAssociator, + val compilationFriendPathsResolver: KotlinCompilationFriendPathsResolver, + val compilationSourceSetInclusion: KotlinCompilationSourceSetInclusion + ) + + //endregion + + + //region direct access / convenience properties + + override val project get() = params.target.project + + override val target: KotlinTarget + get() = params.target + + val sourceSets get() = params.sourceSets + + val dependencyConfigurations: KotlinCompilationDependencyConfigurationsContainer + get() = params.dependencyConfigurations + + override val compilationName: String + get() = params.compilationModule.compilationName + + override val output: KotlinCompilationOutput + get() = params.output + + override val processResourcesTaskName: String? + get() = params.processResourcesTaskName + + override val friendPaths: Iterable + get() = params.compilationFriendPathsResolver.resolveFriendPaths(this) + + //endregion + + + //region Implement Source Set Management + + + override val defaultSourceSet: KotlinSourceSet + get() = sourceSets.defaultSourceSet + + override val allKotlinSourceSets: ObservableSet + get() = sourceSets.allKotlinSourceSets + + override val kotlinSourceSets: ObservableSet + get() = sourceSets.kotlinSourceSets + + override fun source(sourceSet: KotlinSourceSet) { + sourceSets.source(sourceSet) + } + + override fun defaultSourceSet(configure: KotlinSourceSet.() -> Unit) { + defaultSourceSet.configure() + } + + + //endregion + + + //region Dependency Configuration Management + + override val apiConfigurationName: String + get() = dependencyConfigurations.apiConfiguration.name + + override val implementationConfigurationName: String + get() = dependencyConfigurations.implementationConfiguration.name + + override val compileOnlyConfigurationName: String + get() = dependencyConfigurations.compileOnlyConfiguration.name + + override val runtimeOnlyConfigurationName: String + get() = dependencyConfigurations.runtimeOnlyConfiguration.name + + override val compileDependencyConfigurationName: String + get() = dependencyConfigurations.compileDependencyConfiguration.name + + override val runtimeDependencyConfigurationName: String? + get() = dependencyConfigurations.runtimeDependencyConfiguration?.name + + override var compileDependencyFiles: FileCollection = dependencyConfigurations.compileDependencyConfiguration + + override var runtimeDependencyFiles: FileCollection? = dependencyConfigurations.runtimeDependencyConfiguration + + override val relatedConfigurationNames: List = listOfNotNull( + apiConfigurationName, + implementationConfigurationName, + compileOnlyConfigurationName, + runtimeOnlyConfigurationName, + compileDependencyConfigurationName, + runtimeDependencyConfigurationName + ) + + override fun dependencies(configure: KotlinDependencyHandler.() -> Unit) { + HasKotlinDependencies(project, dependencyConfigurations).dependencies(configure) + } + + override fun dependencies(configure: Action) { + HasKotlinDependencies(project, dependencyConfigurations).dependencies(configure) + } + + //endregion + + + //region Compiler Module Management + + override val compilationModule: KotlinCompilationModuleManager.CompilationModule + get() = params.compilationModule + + override val moduleName: String + get() = project.kotlinCompilationModuleManager.getModuleLeader(compilationModule).ownModuleName.get() + + //endregion + + + //region Compile Tasks + + override val compileKotlinTaskName: String + get() = params.compilationTaskNames.compileTaskName + + + override val compileAllTaskName: String + get() = params.compilationTaskNames.compileAllTaskName + + @Suppress("deprecation") + @Deprecated("Accessing task instance directly is deprecated", replaceWith = ReplaceWith("compileTaskProvider")) + override val compileKotlinTask: KotlinCompile + get() = compileKotlinTaskProvider.get() + + @Suppress("deprecation") + @Deprecated("Replaced with compileTaskProvider", replaceWith = ReplaceWith("compileTaskProvider")) + override val compileKotlinTaskProvider: TaskProvider> + get() = target.project.locateTask(compileKotlinTaskName) ?: throw GradleException("Couldn't locate task $compileKotlinTaskName") + + override val compileTaskProvider: TaskProvider> + get() = target.project.locateTask(compileKotlinTaskName) ?: throw GradleException("Couldn't locate task $compileKotlinTaskName") + + //endregion + + + //region CompilerOptions & KotlinOptions + + @Deprecated(message = "Replaced by compilerOptions", replaceWith = ReplaceWith("compilerOptions.options")) + override val kotlinOptions: KotlinCommonOptions + get() = params.kotlinOptions + + override val compilerOptions: HasCompilerOptions<*> + get() = params.compilerOptions + + //endregion + + //region Attributes + + private val attributes by lazy { HierarchyAttributeContainer(target.attributes) } + + override fun getAttributes(): AttributeContainer = attributes + + // endregion + + private val associateWithImpl = mutableSetOf>() + + override val associateWith: List> + get() = associateWithImpl.toList() + + override fun associateWith(other: KotlinCompilation<*>) { + require(other.target == target) { "Only associations between compilations of a single target are supported" } + if (!associateWithImpl.add(other)) return + project.kotlinCompilationModuleManager.unionModules(this.compilationModule, other.internal.compilationModule) + params.compilationAssociator.associate(target, this, other.internal) + } + + + //region final init + + init { + sourceSets.allKotlinSourceSets.forAll { sourceSet -> + params.compilationSourceSetInclusion.include(this, sourceSet) + } + } + + //endregion +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationModuleManager.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationModuleManager.kt new file mode 100644 index 00000000000..1d1ebf941a8 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationModuleManager.kt @@ -0,0 +1,62 @@ +/* + * Copyright 2010-2022 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.compilationImpl + +import org.gradle.api.Project +import org.gradle.api.provider.Provider +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationModuleManager.CompilationModule +import org.jetbrains.kotlin.gradle.utils.getOrPut +import org.jetbrains.kotlin.tooling.core.withLinearClosure + +/** + * This is a disjoint-set union-like approach to having a module name that is equal across associated compilations, as the compiler + * now requires that to properly compile internal calls to friend classes. Associating a compilation with another one leads to their + * disjoint sets being united, so their module names become equal, taken from the new leader compilation. + */ +internal interface KotlinCompilationModuleManager { + class CompilationModule(val compilationName: String, val ownModuleName: Provider, val type: Type) { + enum class Type { + Main, /* Including tests */ Auxiliary + } + } + + fun unionModules(first: CompilationModule, second: CompilationModule) + fun getModuleLeader(compilation: CompilationModule): CompilationModule +} + +internal val Project.kotlinCompilationModuleManager: KotlinCompilationModuleManager + get() = extensions.extraProperties.getOrPut(KotlinCompilationModuleManager::class.java.name) { + DefaultKotlinCompilationModuleManager() + } + +private class DefaultKotlinCompilationModuleManager : KotlinCompilationModuleManager { + private val leadingReferenceMap = mutableMapOf() + + override fun getModuleLeader(compilation: CompilationModule): CompilationModule { + return compilation.withLinearClosure { next -> leadingReferenceMap[next.compilationName] }.last() + } + + override fun unionModules(first: CompilationModule, second: CompilationModule) { + val firstLeader = getModuleLeader(first) + val secondLeader = getModuleLeader(second) + if (firstLeader == secondLeader) return + + val newLeaderCandidates = listOf(firstLeader, secondLeader) + + /* + heuristically choose the new leader: choose `main` when possible, don't choose `*test*` when there's an alternative, + if that didn't work, choose the first name lexicographically + */ + val newLeader = newLeaderCandidates.singleOrNull { it.type == CompilationModule.Type.Main } + ?: newLeaderCandidates.singleOrNull { it.compilationName.contains("main", true) } + ?: newLeaderCandidates.singleOrNull { !it.compilationName.contains("test", true) } + ?: checkNotNull(newLeaderCandidates.minByOrNull { it.compilationName }) + + setOf(first, second, firstLeader, secondLeader).forEach { compilationInfo -> + leadingReferenceMap[compilationInfo.compilationName] = newLeader + } + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationSourceSetInclusion.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationSourceSetInclusion.kt new file mode 100644 index 00000000000..08ebf8d3276 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationSourceSetInclusion.kt @@ -0,0 +1,100 @@ +/* + * Copyright 2010-2022 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. + */ + +@file:Suppress("MoveLambdaOutsideParentheses") + +package org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl + +import org.jetbrains.kotlin.gradle.dsl.kotlinExtension +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation +import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet +import org.jetbrains.kotlin.gradle.plugin.mpp.InternalKotlinCompilation +import org.jetbrains.kotlin.gradle.plugin.mpp.addSourcesToKotlinCompileTask +import org.jetbrains.kotlin.gradle.plugin.mpp.addSourcesToKotlinNativeCompileTask +import org.jetbrains.kotlin.gradle.plugin.sources.defaultSourceSetLanguageSettingsChecker +import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation + +internal interface KotlinCompilationSourceSetInclusion { + fun include(compilation: InternalKotlinCompilation<*>, sourceSet: KotlinSourceSet) +} + +internal class DefaultKotlinCompilationSourceSetInclusion( + private val addSourcesToCompileTask: AddSourcesToCompileTask +) : KotlinCompilationSourceSetInclusion { + + + interface AddSourcesToCompileTask { + fun addSources(compilation: KotlinCompilation<*>, sourceSet: KotlinSourceSet, addAsCommonSources: Lazy) + + object Default : AddSourcesToCompileTask { + override fun addSources( + compilation: KotlinCompilation<*>, sourceSet: KotlinSourceSet, addAsCommonSources: Lazy + ) { + addSourcesToKotlinCompileTask( + compilation.project, + compilation.compileKotlinTaskName, + sourceSet.customSourceFilesExtensions, + addAsCommonSources, + { sourceSet.kotlin } + ) + } + } + + object Native : AddSourcesToCompileTask { + override fun addSources(compilation: KotlinCompilation<*>, sourceSet: KotlinSourceSet, addAsCommonSources: Lazy) { + addSourcesToKotlinNativeCompileTask( + compilation.project, compilation.compileKotlinTaskName, { sourceSet.kotlin }, addAsCommonSources + ) + } + } + } + + private val processedSourceSets = hashSetOf() + + override fun include(compilation: InternalKotlinCompilation<*>, sourceSet: KotlinSourceSet) { + if (!processedSourceSets.add(sourceSet)) return + + addSourcesToCompileTask.addSources( + compilation, sourceSet, + addAsCommonSources = lazy { + compilation.project.kotlinExtension.sourceSets.any { otherSourceSet -> + sourceSet in otherSourceSet.dependsOn + } + } + ) + + // Use `forced = false` since `api`, `implementation`, and `compileOnly` may be missing in some cases like + // old Java & Android projects: + compilation.project.addExtendsFromRelation( + compilation.apiConfigurationName, + sourceSet.apiConfigurationName, + forced = false + ) + + compilation.project.addExtendsFromRelation( + compilation.implementationConfigurationName, + sourceSet.implementationConfigurationName, + forced = false + ) + compilation.project.addExtendsFromRelation( + compilation.compileOnlyConfigurationName, + sourceSet.compileOnlyConfigurationName, + forced = false + ) + + compilation.project.addExtendsFromRelation( + compilation.runtimeOnlyConfigurationName, + sourceSet.runtimeOnlyConfigurationName, + forced = false + ) + + if (sourceSet.name != compilation.defaultSourceSet.name) { + // Temporary solution for checking consistency across source sets participating in a compilation that may + // not be interconnected with the dependsOn relation: check the settings as if the default source set of + // the compilation depends on the one added to the compilation: + defaultSourceSetLanguageSettingsChecker.runAllChecks(compilation.defaultSourceSet, sourceSet) + } + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationSourceSetsContainer.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationSourceSetsContainer.kt new file mode 100644 index 00000000000..c8044a915c0 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationSourceSetsContainer.kt @@ -0,0 +1,56 @@ +/* + * Copyright 2010-2022 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.compilationImpl + +import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet +import org.jetbrains.kotlin.gradle.plugin.sources.internal +import org.jetbrains.kotlin.gradle.utils.MutableObservableSet +import org.jetbrains.kotlin.gradle.utils.MutableObservableSetImpl +import org.jetbrains.kotlin.gradle.utils.ObservableSet + +internal fun KotlinCompilationSourceSetsContainer( + defaultSourceSet: KotlinSourceSet +): KotlinCompilationSourceSetsContainer { + return DefaultKotlinCompilationSourceSetsContainer(defaultSourceSet) +} + +internal interface KotlinCompilationSourceSetsContainer { + val defaultSourceSet: KotlinSourceSet + val kotlinSourceSets: ObservableSet + val allKotlinSourceSets: ObservableSet + fun source(sourceSet: KotlinSourceSet) +} + +private class DefaultKotlinCompilationSourceSetsContainer( + override val defaultSourceSet: KotlinSourceSet +) : KotlinCompilationSourceSetsContainer { + private val kotlinSourceSetsImpl: MutableObservableSet = MutableObservableSetImpl(defaultSourceSet) + + private val allKotlinSourceSetsImpl: MutableObservableSet = MutableObservableSetImpl().also { set -> + defaultSourceSet.internal.withDependsOnClosure.forAll(set::add) + } + + override val kotlinSourceSets: ObservableSet + get() = kotlinSourceSetsImpl + + override val allKotlinSourceSets: ObservableSet + get() = allKotlinSourceSetsImpl + + /** + * All SourceSets that have been processed by [source] already. + * [directlyIncludedKotlinSourceSets] cannot be used in this case, because + * the [defaultSourceSet] will always be already included. + */ + private val sourcedKotlinSourceSets = hashSetOf() + + override fun source(sourceSet: KotlinSourceSet) { + if (!sourcedKotlinSourceSets.add(sourceSet)) return + kotlinSourceSetsImpl.add(sourceSet) + sourceSet.internal.withDependsOnClosure.forAll { inDependsOnClosure -> + allKotlinSourceSetsImpl.add(inDependsOnClosure) + } + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationTaskContainer.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationTaskContainer.kt new file mode 100644 index 00000000000..553ae8ad72c --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationTaskContainer.kt @@ -0,0 +1,11 @@ +/* + * Copyright 2010-2022 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.compilationImpl + +data class KotlinCompilationTaskNameContainer( + val compileTaskName: String, + val compileAllTaskName: String +) \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/internal/KotlinCompilationsModuleGroups.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/internal/KotlinCompilationsModuleGroups.kt deleted file mode 100644 index 4ed1b6c66dd..00000000000 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/internal/KotlinCompilationsModuleGroups.kt +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2010-2020 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.internal - -import org.gradle.api.Project -import org.gradle.api.plugins.ExtraPropertiesExtension -import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation -import org.jetbrains.kotlin.gradle.plugin.mpp.isMain -import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData -import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.isMainCompilationData - -/** This is a disjoint-set union-like approach to having a module name that is equal across associated compilations, as the compiler - * now requires that to properly compile internal calls to friend classes. Associating a compilation with another one leads to their - * disjoint sets being united, so their module names become equal, taken from the new leader compilation. - * - * TODO: once the compiler is able to correctly generate calls to internals in other modules, remove this logic. - */ -internal class KotlinCompilationsModuleGroups { - private val moduleLeaderCompilationMap: MutableMap, KotlinCompilationData<*>> = - mutableMapOf() - - fun getModuleLeader(compilation: KotlinCompilationData<*>): KotlinCompilationData<*> { - if (compilation !in moduleLeaderCompilationMap) { - moduleLeaderCompilationMap[compilation] = compilation - } - val leader = moduleLeaderCompilationMap.getValue(compilation) - return when { - leader == compilation -> leader - else -> getModuleLeader(leader).also { moduleLeaderCompilationMap[compilation] = it } - } - } - - fun unionModules(compilationA: KotlinCompilationData<*>, compilationB: KotlinCompilationData<*>) { - val aLeader = getModuleLeader(compilationA) - val bLeader = getModuleLeader(compilationB) - - if (aLeader == bLeader) - return - - listOf(aLeader, bLeader).run { - /** heuristically choose the new leader: choose `main` when possible, don't choose `*test*` when there's an alternative, - * if that didn't work, choose the first name lexicographically */ - val newLeader = singleOrNull { it.isMainCompilationData() } - ?: singleOrNull { it.compilationPurpose.contains("main", true) } - ?: singleOrNull { !it.compilationPurpose.contains("test", true) } - ?: minByOrNull { it.compilationPurpose }!! - - forEach { moduleLeaderCompilationMap[it] = newLeader } - } - } - - companion object { - private const val EXT_NAME = "kotlin.compilations.moduleGroups" - - fun getModuleLeaderCompilation(compilation: KotlinCompilationData<*>): KotlinCompilationData<*> = - getInstance(compilation.project).getModuleLeader(compilation) - - fun unionModules(compilationA: KotlinCompilationData<*>, compilationB: KotlinCompilationData<*>) { - getInstance(compilationA.project).unionModules(compilationA, compilationB) - } - - private fun getInstance(project: Project): KotlinCompilationsModuleGroups { - val ext = project.extensions.getByType(ExtraPropertiesExtension::class.java) - if (!ext.has(EXT_NAME)) { - ext.set(EXT_NAME, KotlinCompilationsModuleGroups()) - } - @Suppress("UNCHECKED_CAST") - return ext.get(EXT_NAME) as KotlinCompilationsModuleGroups - } - } -} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradleKpmCompilationTaskConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradleKpmCompilationTaskConfigurator.kt index 0818b13a113..36c90a662f8 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradleKpmCompilationTaskConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradleKpmCompilationTaskConfigurator.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.pm20 import org.gradle.api.Project import org.gradle.api.tasks.TaskProvider import org.jetbrains.kotlin.gradle.plugin.Kotlin2JvmSourceSetProcessor +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationProjection import org.jetbrains.kotlin.gradle.plugin.KotlinNativeTargetConfigurator import org.jetbrains.kotlin.gradle.plugin.mpp.addCommonSourcesToKotlinCompileTask import org.jetbrains.kotlin.gradle.plugin.mpp.addSourcesToKotlinCompileTask @@ -30,7 +31,7 @@ open class GradleKpmCompilationTaskConfigurator( variant: GradleKpmVariant, compilationData: KotlinCompilationData<*> ): TaskProvider { - Kotlin2JvmSourceSetProcessor(KotlinTasksProvider(), compilationData).run() + Kotlin2JvmSourceSetProcessor(KotlinTasksProvider(), KotlinCompilationProjection.KPM(compilationData)).run() val allSources = getSourcesForFragmentCompilation(variant) val commonSources = getCommonSourcesForFragmentCompilation(variant) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/setupFragmentsMetadataForKpmModules.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/setupFragmentsMetadataForKpmModules.kt index 7542dfaed56..c986045edef 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/setupFragmentsMetadataForKpmModules.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/setupFragmentsMetadataForKpmModules.kt @@ -12,13 +12,10 @@ import org.gradle.api.attributes.Usage import org.gradle.api.tasks.TaskProvider import org.gradle.jvm.tasks.Jar import org.jetbrains.kotlin.gradle.dsl.pm20Extension -import org.jetbrains.kotlin.gradle.plugin.KotlinCommonSourceSetProcessor -import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType -import org.jetbrains.kotlin.gradle.plugin.categoryByName +import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.mpp.* import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.ComputedCapability import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.disambiguateName -import org.jetbrains.kotlin.gradle.plugin.usageByName import org.jetbrains.kotlin.gradle.targets.metadata.KotlinMetadataTargetConfigurator import org.jetbrains.kotlin.gradle.targets.metadata.createGenerateProjectStructureMetadataTask import org.jetbrains.kotlin.gradle.targets.metadata.filesWithUnpackedArchives @@ -221,10 +218,7 @@ private class GradleKpmMetadataCompilationTasksConfigurator(project: Project) : fragment: GradleKpmFragment, compilationData: KotlinCommonFragmentMetadataCompilationData ) { - KotlinCommonSourceSetProcessor( - compilationData, - KotlinTasksProvider() - ).run() + KotlinCommonSourceSetProcessor(KotlinCompilationProjection.KPM(compilationData), KotlinTasksProvider()).run() val allSources = getSourcesForFragmentCompilation(fragment) val commonSources = getCommonSourcesForFragmentCompilation(fragment) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/android/AndroidProjectHandler.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/android/AndroidProjectHandler.kt index 4a957c55eaa..38068470cce 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/android/AndroidProjectHandler.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/android/AndroidProjectHandler.kt @@ -224,7 +224,7 @@ internal class AndroidProjectHandler( val defaultSourceSet = project.kotlinExtension.sourceSets.maybeCreate(compilation.defaultSourceSetName) - val configAction = KotlinCompileConfig(compilation) + val configAction = KotlinCompileConfig(KotlinCompilationProjection(compilation)) configAction.configureTask { task -> task.useModuleDetection.value(true).disallowChanges() // store kotlin classes in separate directory. They will serve as class-path to java compiler diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/KotlinJsTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/KotlinJsTargetConfigurator.kt index d52bbc1eac9..f0ed1bb493e 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/KotlinJsTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/KotlinJsTargetConfigurator.kt @@ -54,7 +54,7 @@ open class KotlinJsTargetConfigurator : override fun buildCompilationProcessor(compilation: KotlinJsCompilation): KotlinSourceSetProcessor<*> { val tasksProvider = KotlinTasksProvider() - return Kotlin2JsSourceSetProcessor(tasksProvider, compilation) + return Kotlin2JsSourceSetProcessor(tasksProvider, KotlinCompilationProjection(compilation)) } override fun configureCompilationDefaults(target: KotlinJsTarget) { diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTargetConfigurator.kt index bb01f4e8881..33451fe0e12 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTargetConfigurator.kt @@ -56,7 +56,7 @@ open class KotlinJsIrTargetConfigurator() : override fun buildCompilationProcessor(compilation: KotlinJsIrCompilation): KotlinSourceSetProcessor<*> { val tasksProvider = KotlinTasksProvider() - return KotlinJsIrSourceSetProcessor(tasksProvider, compilation) + return KotlinJsIrSourceSetProcessor(tasksProvider, KotlinCompilationProjection(compilation)) } override fun createArchiveTasks(target: KotlinJsIrTarget): TaskProvider { diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmCompilation.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmCompilation.kt index 8b31d2b9eb1..d5d039d38d9 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmCompilation.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmCompilation.kt @@ -6,26 +6,93 @@ @file:Suppress("PackageDirectoryMismatch") // Old package for compatibility package org.jetbrains.kotlin.gradle.plugin.mpp -import org.gradle.api.tasks.compile.JavaCompile +import org.gradle.api.file.FileCollection import org.gradle.api.tasks.TaskProvider -import org.jetbrains.kotlin.gradle.dsl.* +import org.gradle.api.tasks.compile.JavaCompile +import org.jetbrains.kotlin.gradle.dsl.CompilerCommonOptions +import org.jetbrains.kotlin.gradle.dsl.CompilerJvmOptions +import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions +import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions import org.jetbrains.kotlin.gradle.plugin.HasCompilerOptions +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationToRunnableFiles import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationWithResources import org.jetbrains.kotlin.gradle.plugin.internal.JavaSourceSetsAccessor +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationImpl import org.jetbrains.kotlin.gradle.plugin.variantImplementationFactory import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask import javax.inject.Inject -abstract class KotlinJvmCompilation @Inject constructor( +open class KotlinJvmCompilation @Inject internal constructor( + private val compilation: KotlinCompilationImpl +) : InternalKotlinCompilation by compilation.castKotlinOptionsType(), + KotlinCompilationWithResources, + KotlinCompilationToRunnableFiles { + + override val target: KotlinJvmTarget = compilation.target as KotlinJvmTarget + + override val compilerOptions: HasCompilerOptions = + compilation.compilerOptions.castCompilerOptionsType() + + @Deprecated("Replaced with compileTaskProvider", replaceWith = ReplaceWith("compileTaskProvider")) + @Suppress("UNCHECKED_CAST", "DEPRECATION") + override val compileKotlinTaskProvider: TaskProvider + get() = compilation.compileKotlinTaskProvider as TaskProvider + + @Suppress("DEPRECATION") + @Deprecated("Accessing task instance directly is deprecated", replaceWith = ReplaceWith("compileTaskProvider")) + override val compileKotlinTask: org.jetbrains.kotlin.gradle.tasks.KotlinCompile + get() = compilation.compileKotlinTask as org.jetbrains.kotlin.gradle.tasks.KotlinCompile + + @Suppress("UNCHECKED_CAST") + override val compileTaskProvider: TaskProvider> + get() = compilation.compileTaskProvider as TaskProvider> + + val compileJavaTaskProvider: TaskProvider? + get() = if (target.withJavaEnabled) { + val project = target.project + val javaSourceSets = project.gradle.variantImplementationFactory() + .getInstance(project) + .sourceSets + val javaSourceSet = javaSourceSets.getByName(compilationName) + project.tasks.withType(JavaCompile::class.java).named(javaSourceSet.compileJavaTaskName) + } else null + + override val runtimeDependencyConfigurationName: String + get() = compilation.runtimeDependencyConfigurationName ?: error("Missing 'runtimeDependencyConfigurationName'") + + override var runtimeDependencyFiles: FileCollection = compilation.runtimeDependencyFiles ?: error("Missing 'runtimeDependencyFiles'") + + override val processResourcesTaskName: String + get() = compilation.processResourcesTaskName ?: error("Missing 'processResourcesTaskName'") + + override val relatedConfigurationNames: List + get() = compilation.relatedConfigurationNames +} + + +private inline fun InternalKotlinCompilation<*>.castKotlinOptionsType(): InternalKotlinCompilation { + this.kotlinOptions as T + @Suppress("UNCHECKED_CAST") + return this as InternalKotlinCompilation +} + +private inline fun HasCompilerOptions<*>.castCompilerOptionsType(): HasCompilerOptions { + this.options as T + @Suppress("UNCHECKED_CAST") + return this as HasCompilerOptions +} + + +abstract class oKotlinJvmCompilation @Inject constructor( compilationDetails: CompilationDetailsWithRuntime, ) : AbstractKotlinCompilationToRunnableFiles(compilationDetails), KotlinCompilationWithResources { override val target: KotlinJvmTarget get() = compilationDetails.target as KotlinJvmTarget @Suppress("UNCHECKED_CAST") - override val compilerOptions: HasCompilerOptions - get() = super.compilerOptions as HasCompilerOptions + override val compilerOptions: HasCompilerOptions + get() = super.compilerOptions as HasCompilerOptions override val processResourcesTaskName: String get() = disambiguateName("processResources") @@ -41,16 +108,18 @@ abstract class KotlinJvmCompilation @Inject constructor( get() = super.compileKotlinTask as org.jetbrains.kotlin.gradle.tasks.KotlinCompile @Suppress("UNCHECKED_CAST") - override val compileTaskProvider: TaskProvider> - get() = super.compileTaskProvider as TaskProvider> + override val compileTaskProvider: TaskProvider> + get() = super.compileTaskProvider as TaskProvider> val compileJavaTaskProvider: TaskProvider? get() = if (target.withJavaEnabled) { val project = target.project - val javaSourceSets = project.gradle.variantImplementationFactory() - .getInstance(project) - .sourceSets + val javaSourceSets = + project.gradle.variantImplementationFactory() + .getInstance(project) + .sourceSets 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/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmCompilationFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmCompilationFactory.kt index 574bb1e34b1..281c3230e50 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmCompilationFactory.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmCompilationFactory.kt @@ -6,10 +6,20 @@ @file:Suppress("PackageDirectoryMismatch") // Old package for compatibility package org.jetbrains.kotlin.gradle.plugin.mpp -import org.jetbrains.kotlin.gradle.dsl.* -import org.jetbrains.kotlin.gradle.plugin.HasCompilerOptions -import org.jetbrains.kotlin.gradle.plugin.mpp.compilationDetailsImpl.DefaultCompilationDetailsWithRuntime +import org.gradle.api.attributes.Category +import org.gradle.api.attributes.Usage +import org.gradle.api.provider.Provider +import org.jetbrains.kotlin.gradle.dsl.CompilerJvmOptions +import org.jetbrains.kotlin.gradle.dsl.CompilerJvmOptionsDefault +import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions +import org.jetbrains.kotlin.gradle.plugin.* +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.* +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationModuleManager.CompilationModule.Type.Auxiliary +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationModuleManager.CompilationModule.Type.Main +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.archivesName import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget +import org.jetbrains.kotlin.gradle.utils.* +import java.util.concurrent.Callable open class KotlinJvmCompilationFactory( override val target: KotlinJvmTarget @@ -17,26 +27,151 @@ open class KotlinJvmCompilationFactory( override val itemClass: Class get() = KotlinJvmCompilation::class.java - @Suppress("DEPRECATION") - override fun create(name: String): KotlinJvmCompilation = - target.project.objects.newInstance( - KotlinJvmCompilation::class.java, - DefaultCompilationDetailsWithRuntime( - target, - name, - getOrCreateDefaultSourceSet(name), - { - object : HasCompilerOptions { - override val options: KotlinJvmCompilerOptions = - target.project.objects.newInstance(KotlinJvmCompilerOptionsDefault::class.java) - } - }, - { - object : KotlinJvmOptions { - override val options: KotlinJvmCompilerOptions - get() = compilerOptions.options - } - } + override fun create(name: String): KotlinJvmCompilation { + val compilerOptions = createCompilerOptions() + + val params = KotlinCompilationImpl.Params( + target = target, + compilationModule = KotlinCompilationModuleManager.CompilationModule( + compilationName = name, + ownModuleName = ownModuleName(target, name), + type = if (name == KotlinCompilation.MAIN_COMPILATION_NAME) Main else Auxiliary + ), + sourceSets = KotlinCompilationSourceSetsContainer(getOrCreateDefaultSourceSet(name)), + dependencyConfigurations = createDependencyConfigurations(name), + compilationTaskNames = KotlinCompilationTaskNameContainer( + compileTaskName = lowerCamelCaseName( + "compile", name.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, "Kotlin", target.targetName + ), + compileAllTaskName = lowerCamelCaseName(target.disambiguationClassifier, name, "classes") + ), + processResourcesTaskName = lowerCamelCaseName( + target.disambiguationClassifier, + name.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, + "processResources" + ), + output = DefaultKotlinCompilationOutput( + project, Callable { target.project.buildDir.resolve("processedResources/${target.targetName}/$name") } + ), + compilerOptions = compilerOptions, + kotlinOptions = compilerOptions.asKotlinJvmOptions(), + compilationAssociator = if (target.withJavaEnabled) KotlinJvmWithJavaCompilationAssociator else + DefaultKotlinCompilationAssociator, + compilationFriendPathsResolver = DefaultKotlinCompilationFriendPathsResolver, + compilationSourceSetInclusion = DefaultKotlinCompilationSourceSetInclusion( + DefaultKotlinCompilationSourceSetInclusion.AddSourcesToCompileTask.Default ) ) -} \ No newline at end of file + + return target.project.objects.newInstance(KotlinJvmCompilation::class.java, KotlinCompilationImpl(params)) + } + + private fun createDependencyConfigurations( + compilationName: String + ): KotlinCompilationDependencyConfigurationsContainer { + val compilation = "${target.disambiguationClassifier}/$compilationName" + val prefix = lowerCamelCaseName( + target.disambiguationClassifier, + compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, + "compilation" + ) + + val apiConfiguration = target.project.configurations.maybeCreate(lowerCamelCaseName(prefix, API)).apply { + isVisible = false + isCanBeConsumed = false + isCanBeResolved = false + description = "API dependencies for $compilation" + } + + val implementationConfiguration = target.project.configurations.maybeCreate(lowerCamelCaseName(prefix, IMPLEMENTATION)).apply { + extendsFrom(apiConfiguration) + isVisible = false + isCanBeConsumed = false + isCanBeResolved = false + description = "Implementation only dependencies for $compilation." + } + + val compileOnlyConfiguration = target.project.configurations.maybeCreate(lowerCamelCaseName(prefix, COMPILE_ONLY)).apply { + isCanBeConsumed = false + setupAsLocalTargetSpecificConfigurationIfSupported(target) + attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) + isVisible = false + isCanBeResolved = false + description = "Compile only dependencies for $compilation." + } + + val runtimeOnlyConfiguration = target.project.configurations.maybeCreate(lowerCamelCaseName(prefix, RUNTIME_ONLY)).apply { + isVisible = false + isCanBeConsumed = false + isCanBeResolved = false + description = "Runtime only dependencies for $compilation." + } + + val compileDependencyConfiguration = target.project.configurations.maybeCreate( + lowerCamelCaseName( + target.disambiguationClassifier, + compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, + "compileClasspath" + ) + ).apply { + extendsFrom(compileOnlyConfiguration, implementationConfiguration) + usesPlatformOf(target) + isVisible = false + isCanBeConsumed = false + attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerApiUsage(target)) + if (target.platformType != KotlinPlatformType.androidJvm) { + attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) + } + description = "Compile classpath for $compilation." + } + + val runtimeDependencyConfiguration = target.project.configurations.maybeCreate( + lowerCamelCaseName( + target.disambiguationClassifier, + compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, + "runtimeClasspath" + ) + ).apply { + extendsFrom(runtimeOnlyConfiguration, implementationConfiguration) + usesPlatformOf(target) + isVisible = false + isCanBeConsumed = false + isCanBeResolved = true + attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerRuntimeUsage(target)) + if (target.platformType != KotlinPlatformType.androidJvm) { + attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) + } + description = "Runtime classpath of $compilation." + } + + return DefaultKotlinCompilationDependencyConfigurationsContainer( + apiConfiguration = apiConfiguration, + implementationConfiguration = implementationConfiguration, + compileOnlyConfiguration = compileOnlyConfiguration, + runtimeOnlyConfiguration = runtimeOnlyConfiguration, + compileDependencyConfiguration = compileDependencyConfiguration, + runtimeDependencyConfiguration = runtimeDependencyConfiguration + ) + } + + private fun createCompilerOptions(): HasCompilerOptions { + return object : HasCompilerOptions { + override val options: CompilerJvmOptions = + target.project.objects.newInstance(CompilerJvmOptionsDefault::class.java) + } + } + + private fun HasCompilerOptions.asKotlinJvmOptions(): KotlinJvmOptions { + return object : KotlinJvmOptions { + override val options: CompilerJvmOptions + get() = this@asKotlinJvmOptions.options + } + } +} + +private fun ownModuleName(target: KotlinTarget, compilationName: String): Provider = target.project.provider { + val baseName = target.project.archivesName.orNull + ?: target.project.name + val suffix = if (compilationName == KotlinCompilation.MAIN_COMPILATION_NAME) "" else "_$compilationName" + filterModuleName("$baseName$suffix") +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTargetConfigurator.kt index c560f0e63c1..ddc07c0850b 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTargetConfigurator.kt @@ -8,8 +8,6 @@ package org.jetbrains.kotlin.gradle.targets.jvm import org.gradle.api.Task import org.gradle.api.plugins.JavaBasePlugin import org.jetbrains.kotlin.gradle.plugin.* -import org.jetbrains.kotlin.gradle.plugin.Kotlin2JvmSourceSetProcessor -import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetProcessor import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmCompilation import org.jetbrains.kotlin.gradle.targets.jvm.tasks.KotlinJvmTest import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider @@ -74,6 +72,6 @@ open class KotlinJvmTargetConfigurator : override fun buildCompilationProcessor(compilation: KotlinJvmCompilation): KotlinSourceSetProcessor<*> { val tasksProvider = KotlinTasksProvider() - return Kotlin2JvmSourceSetProcessor(tasksProvider, compilation) + return Kotlin2JvmSourceSetProcessor(tasksProvider, KotlinCompilationProjection(compilation)) } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmWithJavaTargetPreset.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmWithJavaTargetPreset.kt index 1e0957abbea..ace3f97ac4a 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmWithJavaTargetPreset.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmWithJavaTargetPreset.kt @@ -53,7 +53,7 @@ class KotlinJvmWithJavaTargetPreset( } AbstractKotlinPlugin.configureTarget(target) { compilation -> - Kotlin2JvmSourceSetProcessor(KotlinTasksProvider(), compilation) + Kotlin2JvmSourceSetProcessor(KotlinTasksProvider(), KotlinCompilationProjection(compilation)) } target.compilations.getByName("test").run { diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt index 9fce0529b7e..cd955012d10 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt @@ -118,7 +118,7 @@ class KotlinMetadataTargetConfigurator : override fun buildCompilationProcessor(compilation: AbstractKotlinCompilation<*>): KotlinCompilationProcessor<*> = when (compilation) { is KotlinCommonCompilation -> { val tasksProvider = KotlinTasksProvider() - KotlinCommonSourceSetProcessor(compilation, tasksProvider) + KotlinCommonSourceSetProcessor(KotlinCompilationProjection(compilation), tasksProvider) } is KotlinSharedNativeCompilation -> NativeSharedCompilationProcessor(compilation) @@ -486,8 +486,8 @@ class KotlinMetadataTargetConfigurator : } internal class NativeSharedCompilationProcessor( - override val kotlinCompilation: KotlinNativeFragmentMetadataCompilationData -) : KotlinCompilationProcessor(kotlinCompilation) { + private val kotlinCompilation: KotlinSharedNativeCompilation +) : KotlinCompilationProcessor(KotlinCompilationProjection(kotlinCompilation)) { override val kotlinTask: TaskProvider = KotlinNativeTargetConfigurator.createKlibCompilationTask(kotlinCompilation) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/AbstractKotlinCompileConfig.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/AbstractKotlinCompileConfig.kt index c9ba7abc582..de3607cdc06 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/AbstractKotlinCompileConfig.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/AbstractKotlinCompileConfig.kt @@ -17,7 +17,6 @@ import org.jetbrains.kotlin.gradle.dsl.topLevelExtension import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider import org.jetbrains.kotlin.gradle.plugin.mpp.associateWithClosure -import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData import org.jetbrains.kotlin.gradle.plugin.sources.applyLanguageSettingsToCompilerOptions import org.jetbrains.kotlin.gradle.report.BuildMetricsService import org.jetbrains.kotlin.gradle.report.BuildReportsService @@ -85,12 +84,12 @@ internal abstract class AbstractKotlinCompileConfig = getKotlinBuildDir(task).map { it.dir("classpath-snapshot") } - constructor(compilation: KotlinCompilationData<*>) : this( - compilation.project, compilation.project.topLevelExtension, compilation.project.provider { compilation.languageSettings } + constructor(compilationProjection: KotlinCompilationProjection) : this( + compilationProjection.project, compilationProjection.project.topLevelExtension, compilationProjection.project.provider { compilationProjection.languageSettings } ) { configureTask { task -> - task.friendPaths.from({ compilation.friendPaths }) - if (compilation is KotlinCompilation<*>) { + task.friendPaths.from({ compilationProjection.friendPaths }) + compilationProjection.tcsOrNull?.compilation?.let { compilation -> task.friendSourceSets .value(providers.provider { compilation.associateWithClosure.map { it.name } }) .disallowChanges() @@ -98,12 +97,12 @@ internal abstract class AbstractKotlinCompileConfig { constructor( - compilation: KotlinCompilationData<*>, + compilation: KotlinCompilation<*>, kotlinTaskProvider: TaskProvider, - kaptClassesDir: File, - ) : super(compilation) { + kaptClassesDir: File + ) : super(KotlinCompilationProjection(compilation)) { configureFromExtension(project.extensions.getByType(KaptExtension::class.java)) configureTask { task -> val kotlinCompileTask = kotlinTaskProvider.get() @@ -48,11 +47,11 @@ internal class KaptGenerateStubsConfig : BaseKotlinCompileConfig { val javacOptions = project.provider { kaptExtension.getJavacOptions() } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/Kotlin2JsCompileConfig.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/Kotlin2JsCompileConfig.kt index 7162ba73a7d..cfeb21a6cd8 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/Kotlin2JsCompileConfig.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/Kotlin2JsCompileConfig.kt @@ -5,12 +5,8 @@ package org.jetbrains.kotlin.gradle.tasks.configuration -import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData -import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.isMainCompilationData +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationProjection import org.jetbrains.kotlin.gradle.targets.js.ir.* -import org.jetbrains.kotlin.gradle.targets.js.ir.PRODUCE_JS -import org.jetbrains.kotlin.gradle.targets.js.ir.PRODUCE_UNZIPPED_KLIB -import org.jetbrains.kotlin.gradle.targets.js.ir.PRODUCE_ZIPPED_KLIB import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile import org.jetbrains.kotlin.gradle.utils.klibModuleName import java.io.File @@ -18,7 +14,7 @@ import java.io.File internal typealias Kotlin2JsCompileConfig = BaseKotlin2JsCompileConfig internal open class BaseKotlin2JsCompileConfig( - compilation: KotlinCompilationData<*> + compilation: KotlinCompilationProjection ) : AbstractKotlinCompileConfig(compilation) { init { @@ -75,7 +71,7 @@ internal open class BaseKotlin2JsCompileConfig( protected open fun configureAdditionalFreeCompilerArguments( task: TASK, - compilation: KotlinCompilationData<*> + compilation: KotlinCompilationProjection ) { task.enhancedFreeCompilerArgs.value( task.compilerOptions.freeCompilerArgs.map { freeArgs -> @@ -87,7 +83,7 @@ internal open class BaseKotlin2JsCompileConfig( } protected fun MutableList.commonJsAdditionalCompilerFlags( - compilation: KotlinCompilationData<*> + compilation: KotlinCompilationProjection ) { if (contains(DISABLE_PRE_IR) && !contains(PRODUCE_UNZIPPED_KLIB) && @@ -101,10 +97,10 @@ internal open class BaseKotlin2JsCompileConfig( contains(PRODUCE_ZIPPED_KLIB) ) { // Configure FQ module name to avoid cyclic dependencies in klib manifests (see KT-36721). - val baseName = if (compilation.isMainCompilationData()) { + val baseName = if (compilation.isMain) { project.name } else { - "${project.name}_${compilation.compilationPurpose}" + "${project.name}_${compilation.compilationName}" } if (none { it.startsWith(KLIB_MODULE_NAME) }) { add("$KLIB_MODULE_NAME=${project.klibModuleName(baseName)}") diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KotlinCompileCommonConfig.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KotlinCompileCommonConfig.kt index fe03024e05a..5c82114bd35 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KotlinCompileCommonConfig.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KotlinCompileCommonConfig.kt @@ -7,25 +7,24 @@ package org.jetbrains.kotlin.gradle.tasks.configuration import org.gradle.api.Project import org.gradle.api.provider.Provider -import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationProjection import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet -import org.jetbrains.kotlin.gradle.plugin.KotlinTarget import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinCommonCompilation import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.AbstractKotlinFragmentMetadataCompilationData -import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinMetadataCompilationData import org.jetbrains.kotlin.gradle.plugin.sources.internal import org.jetbrains.kotlin.gradle.tasks.KotlinCompileCommon import java.io.File internal class KotlinCompileCommonConfig( - private val compilation: KotlinCompilationData<*>, -) : AbstractKotlinCompileConfig(compilation) { + private val compilationProjection: KotlinCompilationProjection, +) : AbstractKotlinCompileConfig(compilationProjection) { init { configureTask { task -> task.expectActualLinker.value( providers.provider { - (compilation as? KotlinCommonCompilation)?.isKlibCompilation == true || compilation is KotlinMetadataCompilationData + (compilationProjection.origin as? KotlinCommonCompilation)?.isKlibCompilation == true || + compilationProjection.origin is KotlinMetadataCompilationData<*> } ).disallowChanges() task.refinesMetadataPaths.from(getRefinesMetadataPaths(project)).disallowChanges() @@ -34,25 +33,26 @@ internal class KotlinCompileCommonConfig( private fun getRefinesMetadataPaths(project: Project): Provider> { return project.provider { - when (compilation) { - is KotlinCompilation<*> -> { - val defaultKotlinSourceSet: KotlinSourceSet = compilation.defaultSourceSet - val metadataTarget = compilation.owner as KotlinTarget + when (compilationProjection) { + is KotlinCompilationProjection.TCS -> { + val defaultKotlinSourceSet: KotlinSourceSet = compilationProjection.compilation.defaultSourceSet + val metadataTarget = compilationProjection.compilation.target defaultKotlinSourceSet.internal.dependsOnClosure .mapNotNull { sourceSet -> metadataTarget.compilations.findByName(sourceSet.name)?.output?.classesDirs } .flatten() } - is AbstractKotlinFragmentMetadataCompilationData -> { - val fragment = compilation.fragment + + is KotlinCompilationProjection.KPM -> { + val compilationData = compilationProjection.compilationData as AbstractKotlinFragmentMetadataCompilationData<*> + val fragment = compilationData.fragment project.files( fragment.refinesClosure.minus(fragment).map { - val compilation = compilation.metadataCompilationRegistry.getForFragmentOrNull(it) + val compilation = compilationData.metadataCompilationRegistry.getForFragmentOrNull(it) ?: return@map project.files() compilation.output.classesDirs } ) } - else -> error("unexpected compilation type") } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KotlinCompileConfig.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KotlinCompileConfig.kt index b16c373f344..5695bf991d7 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KotlinCompileConfig.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KotlinCompileConfig.kt @@ -8,14 +8,15 @@ package org.jetbrains.kotlin.gradle.tasks.configuration import org.gradle.api.Project import org.gradle.api.attributes.Attribute import org.gradle.api.provider.Provider -import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompilerOptions +import org.jetbrains.kotlin.gradle.dsl.CompilerJvmOptions import org.jetbrains.kotlin.gradle.dsl.KotlinTopLevelExtension import org.jetbrains.kotlin.gradle.internal.transforms.ClasspathEntrySnapshotTransform +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationProjection import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmAndroidCompilation import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmCompilation import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaCompilation -import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData import org.jetbrains.kotlin.gradle.plugin.sources.DefaultLanguageSettingsBuilder +import org.jetbrains.kotlin.gradle.plugin.tcsOrNull import org.jetbrains.kotlin.gradle.report.BuildMetricsService import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.project.model.LanguageSettings @@ -60,8 +61,8 @@ internal open class BaseKotlinCompileConfig : AbstractKotl } } - constructor(compilation: KotlinCompilationData<*>) : super(compilation) { - val javaTaskProvider = when (compilation) { + constructor(compilationProjection: KotlinCompilationProjection) : super(compilationProjection) { + val javaTaskProvider = when (val compilation = compilationProjection.tcsOrNull?.compilation) { is KotlinJvmCompilation -> compilation.compileJavaTaskProvider is KotlinJvmAndroidCompilation -> compilation.compileJavaTaskProvider is KotlinWithJavaCompilation<*, *> -> compilation.compileJavaTaskProvider @@ -76,12 +77,13 @@ internal open class BaseKotlinCompileConfig : AbstractKotl task.associatedJavaCompileTaskName.value(javaTaskProvider.name) } task.ownModuleName.value( - (compilation.compilerOptions.options as KotlinJvmCompilerOptions).moduleName.convention(compilation.ownModuleName) + (compilationProjection.compilerOptions.options as CompilerJvmOptions).moduleName.convention(compilationProjection.ownModuleName) ) } } } + constructor(project: Project, ext: KotlinTopLevelExtension) : super( project, ext, languageSettings = getDefaultLangSetting(project, ext) ) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KotlinJsIrLinkConfig.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KotlinJsIrLinkConfig.kt index 056262c1c52..eaccc5c61b5 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KotlinJsIrLinkConfig.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KotlinJsIrLinkConfig.kt @@ -6,8 +6,8 @@ package org.jetbrains.kotlin.gradle.tasks.configuration import org.gradle.api.InvalidUserDataException +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationProjection import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType -import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryMode import org.jetbrains.kotlin.gradle.targets.js.ir.* import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject @@ -15,7 +15,7 @@ import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject internal open class KotlinJsIrLinkConfig( private val binary: JsIrBinary -) : BaseKotlin2JsCompileConfig(binary.compilation) { +) : BaseKotlin2JsCompileConfig(KotlinCompilationProjection(binary.compilation)) { private val compilation get() = binary.compilation @@ -49,7 +49,7 @@ internal open class KotlinJsIrLinkConfig( override fun configureAdditionalFreeCompilerArguments( task: KotlinJsIrLink, - compilation: KotlinCompilationData<*> + compilation: KotlinCompilationProjection ) { task.enhancedFreeCompilerArgs.value( task.compilerOptions.freeCompilerArgs.zip(task.modeProperty) { freeArgs, mode -> @@ -85,7 +85,7 @@ internal open class KotlinJsIrLinkConfig( } private fun MutableList.configureOptions( - compilation: KotlinCompilationData<*>, + compilation: KotlinCompilationProjection, vararg additionalCompilerArgs: String ) { additionalCompilerArgs.forEach { arg -> diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/providerApiUtils.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/providerApiUtils.kt index 8f36e2154c9..8c689816589 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/providerApiUtils.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/providerApiUtils.kt @@ -83,12 +83,12 @@ internal fun > T.chainedFinalizeValu finalizeValueOnRead() } -internal fun > T.chainedFinalizeValue(): T = +internal fun > T.chainedFinalizeValue(): T = apply { finalizeValue() } -internal fun > T.chainedDisallowChanges(): T = +internal fun > T.chainedDisallowChanges(): T = apply { disallowChanges() } diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/KotlinCompilationsModuleGroupsTest.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/KotlinCompilationsModuleGroupsTest.kt index 6e90421e6f0..a0c2d5f2e17 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/KotlinCompilationsModuleGroupsTest.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/KotlinCompilationsModuleGroupsTest.kt @@ -6,29 +6,34 @@ package org.jetbrains.kotlin.gradle import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension -import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinCompilation -import org.jetbrains.kotlin.gradle.plugin.mpp.internal.KotlinCompilationsModuleGroups -import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData +import org.jetbrains.kotlin.gradle.plugin.mpp.InternalKotlinCompilation +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationModuleManager +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.kotlinCompilationModuleManager +import org.jetbrains.kotlin.gradle.plugin.mpp.internal import org.junit.Test import kotlin.test.assertEquals class KotlinCompilationsModuleGroupsTest { private val project = buildProjectWithMPP() private val kotlin = project.multiplatformExtension - private val instance: KotlinCompilationsModuleGroups = KotlinCompilationsModuleGroups() + private val instance: KotlinCompilationModuleManager = project.kotlinCompilationModuleManager - private fun compilation(name: String): AbstractKotlinCompilation<*> = + private fun compilation(name: String): InternalKotlinCompilation<*> = kotlin.jvm().compilations.maybeCreate(name) + private fun KotlinCompilationModuleManager.unionModules(first: InternalKotlinCompilation<*>, second: InternalKotlinCompilation<*>) { + unionModules(first.compilationModule, second.compilationModule) + } + @Test fun testIdentityAsModuleLeaderForNewCompilation() { val a = compilation("a") - assertEquals(a, instance.getModuleLeader(a)) + assertEquals(a.internal.compilationModule, instance.getModuleLeader(a.compilationModule)) } - private fun assertLeader(leader: KotlinCompilationData<*>, vararg ofCompilations: KotlinCompilationData<*>) { - val leadersForModules = ofCompilations.map { instance.getModuleLeader(it) } - assertEquals(leadersForModules.map { leader }, leadersForModules) + private fun assertLeader(leader: InternalKotlinCompilation<*>, vararg ofCompilations: InternalKotlinCompilation<*>) { + val leadersForModules = ofCompilations.map { instance.getModuleLeader(it.compilationModule) } + assertEquals(leadersForModules.map { leader.compilationModule }, leadersForModules) } @Test