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 3c2af2bf282..125be56df61 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 @@ -30,7 +30,7 @@ internal class KotlinCommonSourceSetProcessor( } } - project.whenEvaluated { + project.launchInStage(KotlinPluginLifecycle.Stage.AfterEvaluateBuildscript) { val subpluginEnvironment: SubpluginEnvironment = SubpluginEnvironment.loadSubplugins(project) /* Not supported in KPM yet */ compilationInfo.tcs.compilation.let { compilation -> diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/ProjectMetadataProviderImpl.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/ProjectMetadataProviderImpl.kt index 029727ae8b6..b3d38c513f8 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/ProjectMetadataProviderImpl.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/ProjectMetadataProviderImpl.kt @@ -9,13 +9,11 @@ import org.gradle.api.Project import org.gradle.api.file.FileCollection import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull -import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle.Stage.AfterEvaluateBuildscript import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.await import org.jetbrains.kotlin.gradle.plugin.mpp.MetadataDependencyResolution.ChooseVisibleSourceSets.MetadataProvider.ProjectMetadataProvider -import org.jetbrains.kotlin.gradle.targets.metadata.findMetadataCompilation -import org.jetbrains.kotlin.gradle.targets.native.internal.* +import org.jetbrains.kotlin.gradle.targets.metadata.awaitMetadataCompilationsCreated private typealias SourceSetName = String @@ -34,7 +32,7 @@ private class ProjectMetadataProviderImpl( ) : ProjectMetadataProvider() { override fun getSourceSetCompiledMetadata(sourceSetName: String): FileCollection? { - val metadataOutputs = sourceSetMetadataOutputs[sourceSetName] ?: error("Unexpected source set '$sourceSetName'") + val metadataOutputs = sourceSetMetadataOutputs[sourceSetName] ?: return null return metadataOutputs.metadata } @@ -64,14 +62,10 @@ internal suspend fun Project.collectSourceSetMetadataOutputs(): Map { - return awaitSourceSets().associateWith { sourceSet -> - when (val compilation = project.findMetadataCompilation(sourceSet)) { - null -> null - is KotlinCommonCompilation -> compilation.output.classesDirs - is KotlinSharedNativeCompilation -> compilation.output.classesDirs - else -> error("Unexpected compilation type: $compilation") - } - } -} - - + val metadataTarget = metadata() as KotlinMetadataTarget + return metadataTarget + .awaitMetadataCompilationsCreated() + // TODO: KT-62332/Stop-Creating-legacy-metadata-compilation-with-name-main + .filter { if (it is KotlinCommonCompilation) it.isKlibCompilation else true } + .associate { it.defaultSourceSet to it.output.classesDirs } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/regressionTests/KT61652AddSourceSetInSubpluginAndEarlyTaskMaterialization.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/regressionTests/KT61652AddSourceSetInSubpluginAndEarlyTaskMaterialization.kt new file mode 100644 index 00000000000..1195bf3a3ab --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/regressionTests/KT61652AddSourceSetInSubpluginAndEarlyTaskMaterialization.kt @@ -0,0 +1,75 @@ +/* + * Copyright 2010-2023 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.regressionTests + +import org.gradle.api.provider.Provider +import org.jetbrains.kotlin.gradle.dsl.kotlinExtension +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilerPluginSupportPlugin +import org.jetbrains.kotlin.gradle.plugin.SubpluginArtifact +import org.jetbrains.kotlin.gradle.plugin.SubpluginOption +import org.jetbrains.kotlin.gradle.plugin.mpp.GranularMetadataTransformation +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMetadataCompilation +import org.jetbrains.kotlin.gradle.util.buildProject +import org.jetbrains.kotlin.gradle.util.buildProjectWithMPP +import org.jetbrains.kotlin.gradle.util.kotlin +import org.jetbrains.kotlin.util.assertDoesNotThrow +import kotlin.test.Test + +class KT61652AddSourceSetInSubpluginAndEarlyTaskMaterialization { + @Test + fun `test GranularMetadataTransformation doesn't fail when it is created too early and subplugin applied`() { + class TestSubplugin : KotlinCompilerPluginSupportPlugin { + override fun getCompilerPluginId(): String = "test" + override fun getPluginArtifact(): SubpluginArtifact = SubpluginArtifact("test", "test") + + override fun isApplicable(kotlinCompilation: KotlinCompilation<*>): Boolean = true + + override fun applyToCompilation(kotlinCompilation: KotlinCompilation<*>): Provider> { + val project = kotlinCompilation.project + val emptyResult = project.provider { emptyList() } + + if (kotlinCompilation !is KotlinMetadataCompilation) return emptyResult + if (kotlinCompilation.name == "main") return emptyResult + + project + .kotlinExtension + .sourceSets + .create("generatedBy" + kotlinCompilation.defaultSourceSet.name) + + return emptyResult + } + } + + val root = buildProject {} + val lib = buildProjectWithMPP(projectBuilder = { withParent(root).withName("lib") }) { + kotlin { jvm(); linuxX64() } + } + + val app = buildProjectWithMPP(projectBuilder = { withParent(root).withName("app") }) { + kotlin { + jvm() + linuxX64() + sourceSets.getByName("commonMain").dependencies { api(project(":lib")) } + } + } + + lib.plugins.apply(TestSubplugin::class.java) + app.evaluate() + + /** + * Create GranularMetadataTransformation.Params artificially to reproduce real-case scenario when + * either IDE dependencies resolvers create it or transform*DependenciesMetadata + */ + val gmtParams = GranularMetadataTransformation.Params(app, app.kotlinExtension.sourceSets.getByName("commonMain")) + val allProjectsData = gmtParams.projectData + lib.evaluate() + + assertDoesNotThrow { allProjectsData[":lib"]!!.sourceSetMetadataOutputs.getOrThrow() } + } +} \ No newline at end of file