diff --git a/idea/idea-gradle/tests/org/jetbrains/kotlin/gradle/NewMultiplatformProjectImportingTest.kt b/idea/idea-gradle/tests/org/jetbrains/kotlin/gradle/NewMultiplatformProjectImportingTest.kt index 6cac7b9e562..78375bee289 100644 --- a/idea/idea-gradle/tests/org/jetbrains/kotlin/gradle/NewMultiplatformProjectImportingTest.kt +++ b/idea/idea-gradle/tests/org/jetbrains/kotlin/gradle/NewMultiplatformProjectImportingTest.kt @@ -800,7 +800,27 @@ class NewMultiplatformProjectImportingTest : MultiplePluginVersionGradleImportin module("jvm-on-mpp.mpp-mod-a.test") { } } + } + @Test + fun testCommonTestTargetPlatform() { + configureByFiles() + importProject(true) + checkProjectStructure(true, false, false) { + module("KotlinMPPL") {} + module("com.example.KotlinMPPL.commonMain") { + platform(CommonPlatforms.defaultCommonPlatform) + } + module("com.example.KotlinMPPL.commonTest") { + platform(CommonPlatforms.defaultCommonPlatform) + } + module("com.example.KotlinMPPL.jsMain") { + platform(JsPlatforms.defaultJsPlatform) + } + module("com.example.KotlinMPPL.jsTest") { + platform(JsPlatforms.defaultJsPlatform) + } + } } private fun checkProjectStructure( diff --git a/idea/kotlin-gradle-tooling/src/KotlinMPPGradleModelBuilder.kt b/idea/kotlin-gradle-tooling/src/KotlinMPPGradleModelBuilder.kt index 646460cd3f5..bcded8dbc30 100644 --- a/idea/kotlin-gradle-tooling/src/KotlinMPPGradleModelBuilder.kt +++ b/idea/kotlin-gradle-tooling/src/KotlinMPPGradleModelBuilder.kt @@ -257,7 +257,8 @@ class KotlinMPPGradleModelBuilder : ModelBuilderService { project: Project, dependencyMapper: KotlinDependencyMapper ): Collection? { - return projectTargets.mapNotNull { buildTarget(it, sourceSetMap, dependencyResolver, project, dependencyMapper) } + val isHMPPEnabled = isHMPPEnabled(project) + return projectTargets.mapNotNull { buildTarget(it, sourceSetMap, dependencyResolver, project, dependencyMapper, isHMPPEnabled) } } private operator fun Any?.get(methodName: String, vararg params: Any): Any? { @@ -312,7 +313,8 @@ class KotlinMPPGradleModelBuilder : ModelBuilderService { sourceSetMap: Map, dependencyResolver: DependencyResolver, project: Project, - dependencyMapper: KotlinDependencyMapper + dependencyMapper: KotlinDependencyMapper, + isHMPPEnabled: Boolean ): KotlinTarget? { val targetClass = gradleTarget.javaClass val getPlatformType = targetClass.getMethodOrNull("getPlatformType") ?: return null @@ -336,7 +338,7 @@ class KotlinMPPGradleModelBuilder : ModelBuilderService { if (compilation == null || platform != KotlinPlatform.ANDROID) { compilation } else { - compilation.addDependsOnSourceSetsToCompilation(sourceSetMap) + compilation.addDependsOnSourceSetsToCompilation(sourceSetMap, isHMPPEnabled) } } val jar = buildTargetJar(gradleTarget, project) @@ -359,9 +361,26 @@ class KotlinMPPGradleModelBuilder : ModelBuilderService { return target } - private fun KotlinCompilationImpl.addDependsOnSourceSetsToCompilation(sourceSetMap: Map): KotlinCompilationImpl { - val closedSourceSets = this.sourceSets.union(this.sourceSets.flatMap { it.dependsOnSourceSets }.mapNotNull { sourceSetMap[it] }) - return KotlinCompilationImpl(this.name, closedSourceSets, this.dependencies, this.output, this.arguments, this.dependencyClasspath, this.kotlinTaskProperties, this.nativeExtensions) + private fun KotlinCompilationImpl.addDependsOnSourceSetsToCompilation(sourceSetMap: Map, isHMPPEnabled: Boolean): KotlinCompilationImpl { + val dependsOnSourceSets = this.sourceSets.flatMap { it.dependsOnSourceSets }.mapNotNull { sourceSetMap[it] } + + if (!isHMPPEnabled) { + // intermediate source sets should be common if HMPP is disabled + dependsOnSourceSets.subtract(this.sourceSets).forEach { + it.actualPlatforms.addSimplePlatforms(listOf(KotlinPlatform.COMMON)) + } + } + + return KotlinCompilationImpl( + this.name, + this.sourceSets.union(dependsOnSourceSets), + this.dependencies, + this.output, + this.arguments, + this.dependencyClasspath, + this.kotlinTaskProperties, + this.nativeExtensions + ) } private fun buildTestTasks(project: Project, gradleTarget: Named): Collection { @@ -632,44 +651,32 @@ class KotlinMPPGradleModelBuilder : ModelBuilderService { targets: Collection, isHMPPEnabled: Boolean ) { - val sourceSetToCompilations = LinkedHashMap>() + // includes only compilations where source set is listed + val compiledSourceSetToCompilations = LinkedHashMap>() + // includes compilations where source set is included via dependsOn + val allSourceSetToCompilations = LinkedHashMap>() for (target in targets) { for (compilation in target.compilations) { for (sourceSet in compilation.sourceSets) { - sourceSetToCompilations.getOrPut(sourceSet) { LinkedHashSet() } += compilation + compiledSourceSetToCompilations.getOrPut(sourceSet) { LinkedHashSet() } += compilation + allSourceSetToCompilations.getOrPut(sourceSet) { LinkedHashSet() } += compilation sourceSet.dependsOnSourceSets.mapNotNull { sourceSets[it] }.forEach { - sourceSetToCompilations.getOrPut(it) { LinkedHashSet() } += compilation + allSourceSetToCompilations.getOrPut(it) { LinkedHashSet() } += compilation } } } } for (sourceSet in sourceSets.values) { - val compilations = sourceSetToCompilations[sourceSet] - if (compilations != null) { + (allSourceSetToCompilations[sourceSet]?.all { it.isTestModule } + ?: if (!isHMPPEnabled && sourceSet.name == KotlinSourceSet.COMMON_TEST_SOURCE_SET_NAME) true else null)?.let { isTest -> + sourceSet.isTestModule = isTest + } + (if (isHMPPEnabled) allSourceSetToCompilations[sourceSet] else compiledSourceSetToCompilations[sourceSet])?.let { compilations -> val platforms = compilations.map { it.platform } sourceSet.actualPlatforms.addSimplePlatforms(platforms) - - sourceSet.dependsOnSourceSets.mapNotNull { sourceSets[it] }.forEach { - it?.actualPlatforms?.addSimplePlatforms(platforms) - } - - - sourceSet.isTestModule = compilations.all { it.isTestModule } - } else { - //TODO(auskov): remove this branch as far as import of orphan source sets is dropped - val name = sourceSet.name - if (name == KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME) { - sourceSet.isTestModule = false - continue - } - if (name == KotlinSourceSet.COMMON_TEST_SOURCE_SET_NAME) { - sourceSet.isTestModule = true - continue - } } - - if ((! isHMPPEnabled) && sourceSet.actualPlatforms.platforms.size > 1) { + if ((!isHMPPEnabled) && sourceSet.actualPlatforms.platforms.size != 1) { sourceSet.actualPlatforms.addSimplePlatforms(listOf(KotlinPlatform.COMMON)) } } diff --git a/idea/testData/gradle/newMultiplatformImport/commonTestTargetPlatform/build.gradle b/idea/testData/gradle/newMultiplatformImport/commonTestTargetPlatform/build.gradle new file mode 100644 index 00000000000..7388a0ca6b5 --- /dev/null +++ b/idea/testData/gradle/newMultiplatformImport/commonTestTargetPlatform/build.gradle @@ -0,0 +1,51 @@ +buildscript { + repositories { + mavenLocal() + jcenter() + mavenCentral() + maven { url 'http://dl.bintray.com/kotlin/kotlin-dev' } + maven { url 'http://dl.bintray.com/kotlin/kotlin-eap' } + } + dependencies { + apply from: "include.gradle" + def kotlinVersion = gradleKotlinPluginVersion('1.3.50') + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion") + } +} +apply plugin: 'kotlin-multiplatform' + +group 'com.example' +version '0.0.1' + +kotlin { + js { + browser { + } + nodejs { + } + } + + sourceSets { + commonMain { + dependencies { + implementation kotlin('stdlib-common') + } + } + commonTest { + dependencies { + implementation kotlin('test-common') + implementation kotlin('test-annotations-common') + } + } + jsMain { + dependencies { + implementation kotlin('stdlib-js') + } + } + jsTest { + dependencies { + implementation kotlin('test-js') + } + } + } +} \ No newline at end of file diff --git a/idea/testData/gradle/newMultiplatformImport/commonTestTargetPlatform/settings.gradle b/idea/testData/gradle/newMultiplatformImport/commonTestTargetPlatform/settings.gradle new file mode 100644 index 00000000000..35831dacbfb --- /dev/null +++ b/idea/testData/gradle/newMultiplatformImport/commonTestTargetPlatform/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'KotlinMPPL' +enableFeaturePreview('GRADLE_METADATA')