diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/HierarchicalMppIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/HierarchicalMppIT.kt index d1b66269b5c..4d9bb0144b5 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/HierarchicalMppIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/HierarchicalMppIT.kt @@ -570,6 +570,7 @@ class HierarchicalMppIT : KGPBaseTest() { sourceSetCInteropMetadataDirectory = mapOf(), hostSpecificSourceSets = emptySet(), sourceSetBinaryLayout = sourceSetModuleDependencies.mapValues { SourceSetMetadataLayout.KLIB }, + sourceSetNames = setOf("commonMain", "jvmAndJsMain", "linuxAndJsMain"), isPublishedAsRoot = true ) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinProjectStructureMetadata.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinProjectStructureMetadata.kt index 09c8dab99a6..554a9272e11 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinProjectStructureMetadata.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinProjectStructureMetadata.kt @@ -114,8 +114,11 @@ data class KotlinProjectStructureMetadata( @get:Input val isPublishedAsRoot: Boolean, + @get:Input + val sourceSetNames: Set, + @Input - val formatVersion: String = FORMAT_VERSION_0_3_2 + val formatVersion: String = FORMAT_VERSION_0_3_3 ) : Serializable { @Suppress("UNUSED") // Gradle input @get:Input @@ -136,9 +139,13 @@ data class KotlinProjectStructureMetadata( // + 'sourceSetCInteropMetadataDirectory' map internal const val FORMAT_VERSION_0_3_2 = "0.3.2" + + // + 'sourceSetsNames' + internal const val FORMAT_VERSION_0_3_3 = "0.3.3" } } + internal val KotlinMultiplatformExtension.kotlinProjectStructureMetadata: KotlinProjectStructureMetadata get() = project.extensions.extraProperties.getOrPut("org.jetbrains.kotlin.gradle.plugin.mpp.kotlinProjectStructureMetadata") { buildKotlinProjectStructureMetadata(this) @@ -193,7 +200,8 @@ private fun buildKotlinProjectStructureMetadata(extension: KotlinMultiplatformEx sourceSetBinaryLayout = sourceSetsWithMetadataCompilations.keys.associate { sourceSet -> sourceSet.name to SourceSetMetadataLayout.chooseForProducingProject() }, - isPublishedAsRoot = true + isPublishedAsRoot = true, + sourceSetNames = sourceSetsWithMetadataCompilations.keys.map { it.name }.toSet(), ) } @@ -226,7 +234,8 @@ internal fun buildProjectStructureMetadata(module: GradleKpmModule): KotlinProje sourceSetModuleDependencies = fragmentDependencies, sourceSetCInteropMetadataDirectory = emptyMap(), // Not supported yet hostSpecificSourceSets = getHostSpecificFragments(module).mapTo(mutableSetOf()) { it.name }, - isPublishedAsRoot = true + isPublishedAsRoot = true, + sourceSetNames = module.fragments.map { it.name }.toSet() ) } @@ -253,8 +262,7 @@ internal fun KotlinProjectStructureMetadata.serialize( } multiNodes(SOURCE_SETS_NODE_NAME) { - val keys = sourceSetsDependsOnRelation.keys + sourceSetModuleDependencies.keys - for (sourceSet in keys) { + for (sourceSet in sourceSetNames) { multiNodesItem(SOURCE_SET_NODE_NAME) { value(NAME_NODE_NAME, sourceSet) multiValue(DEPENDS_ON_NODE_NAME, sourceSetsDependsOnRelation[sourceSet].orEmpty().toList()) @@ -304,7 +312,7 @@ internal fun KotlinProjectStructureMetadata.toJson(): String { private val NodeList.elements: Iterable get() = (0 until length).map { this@elements.item(it) }.filterIsInstance() -internal fun parseKotlinSourceSetMetadataFromJson(string: String): KotlinProjectStructureMetadata? { +internal fun parseKotlinSourceSetMetadataFromJson(string: String): KotlinProjectStructureMetadata { @Suppress("DEPRECATION") // The replacement doesn't compile against old dependencies such as AS 4.0 val json = JsonParser().parse(string).asJsonObject val valueNamed: JsonObject.(String) -> String? = { name -> get(name)?.asString } @@ -314,7 +322,7 @@ internal fun parseKotlinSourceSetMetadataFromJson(string: String): KotlinProject return parseKotlinSourceSetMetadata({ json.get(ROOT_NODE_NAME).asJsonObject }, valueNamed, multiObjects, multiValues) } -internal fun parseKotlinSourceSetMetadataFromXml(document: Document): KotlinProjectStructureMetadata? { +internal fun parseKotlinSourceSetMetadataFromXml(document: Document): KotlinProjectStructureMetadata { val nodeNamed: Element.(String) -> Element? = { name -> getElementsByTagName(name).elements.singleOrNull() } val valueNamed: Element.(String) -> String? = { name -> getElementsByTagName(name).run { if (length > 0) item(0).textContent else null } } @@ -334,7 +342,7 @@ internal fun parseKotlinSourceSetMetadata( valueNamed: ParsingContext.(key: String) -> String?, multiObjects: ParsingContext.(named: String) -> Iterable, multiValues: ParsingContext.(named: String) -> Iterable -): KotlinProjectStructureMetadata? { +): KotlinProjectStructureMetadata { val projectStructureNode = getRoot() val formatVersion = checkNotNull(projectStructureNode.valueNamed(FORMAT_VERSION_NODE_NAME)) @@ -355,11 +363,13 @@ internal fun parseKotlinSourceSetMetadata( val sourceSetBinaryLayout = mutableMapOf() val sourceSetCInteropMetadataDirectory = mutableMapOf() val hostSpecificSourceSets = mutableSetOf() + val sourceSetNames = mutableSetOf() val sourceSetsNode = projectStructureNode.multiObjects(SOURCE_SETS_NODE_NAME) sourceSetsNode.forEach { sourceSetNode -> val sourceSetName = checkNotNull(sourceSetNode.valueNamed(NAME_NODE_NAME)) + sourceSetNames.add(sourceSetName) val dependsOn = sourceSetNode.multiValues(DEPENDS_ON_NODE_NAME).toSet() val moduleDependencies = sourceSetNode.multiValues(MODULE_DEPENDENCY_NODE_NAME).mapTo(mutableSetOf()) { @@ -390,6 +400,7 @@ internal fun parseKotlinSourceSetMetadata( sourceSetCInteropMetadataDirectory = sourceSetCInteropMetadataDirectory, hostSpecificSourceSets = hostSpecificSourceSets, isPublishedAsRoot = isPublishedAsRoot, + sourceSetNames = sourceSetNames, formatVersion = formatVersion ) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/KotlinProjectStructureMetadataSerializationTest.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/KotlinProjectStructureMetadataSerializationTest.kt index ebcedac13fe..c2797a3adbd 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/KotlinProjectStructureMetadataSerializationTest.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/KotlinProjectStructureMetadataSerializationTest.kt @@ -35,7 +35,8 @@ class KotlinProjectStructureMetadataSerializationTest { ), sourceSetCInteropMetadataDirectory = mapOf("sourceSetB" to "xx/cinterop/", "sourceSetC" to "cinterops/C"), hostSpecificSourceSets = setOf("sourceSetC"), - isPublishedAsRoot = true + isPublishedAsRoot = true, + sourceSetNames = setOf("sourceSetA", "sourceSetB", "sourceSetC"), ) @Test @@ -64,6 +65,10 @@ class KotlinProjectStructureMetadataSerializationTest { We expect no 'cinterop metadata' in artifacts with older format versions */ assertEquals(emptyMap(), deserialized.sourceSetCInteropMetadataDirectory) + assertEquals( + setOf("commonMain", "concurrentMain", "nativeDarwinMain", "nativeMain", "nativeOtherMain"), + deserialized.sourceSetNames + ) } }