diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
index a6cc312853c..b7c117d82c0 100644
--- a/.idea/kotlinc.xml
+++ b/.idea/kotlinc.xml
@@ -8,7 +8,4 @@
-
-
-
-
\ No newline at end of file
+
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/MultiplatformAndroidSourceSetLayoutV2IT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/MultiplatformAndroidSourceSetLayoutV2IT.kt
index 063a96ff526..5b93e3eb024 100644
--- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/MultiplatformAndroidSourceSetLayoutV2IT.kt
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/MultiplatformAndroidSourceSetLayoutV2IT.kt
@@ -8,14 +8,45 @@ package org.jetbrains.kotlin.gradle
import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.gradle.testbase.*
import org.junit.jupiter.api.DisplayName
+import kotlin.test.assertNull
@MppGradlePluginTests
-@DisplayName("Multiplatform Build Reproducibility")
+@DisplayName("Multiplatform Android Source Set Layout 2")
class MultiplatformAndroidSourceSetLayoutV2IT : KGPBaseTest() {
@GradleAndroidTest
+ @DisplayName("test Android project with flavors")
@AndroidTestVersions(minVersion = "7.0.4")
fun testProjectWithFlavors(gradleVersion: GradleVersion, agpVersion: String, jdkVersion: JdkVersions.ProvidedJdk) {
- val buildOptions = defaultBuildOptions.copy(androidVersion = agpVersion)
+ project(
+ "multiplatformAndroidSourceSetLayout2",
+ gradleVersion,
+ defaultBuildOptions.copy(androidVersion = agpVersion),
+ buildJdk = jdkVersion.location
+ ) {
+ build("test") {
+ assertTasksExecuted(":testUsaPaidReleaseUnitTest")
+ assertTasksExecuted(":testUsaPaidDebugUnitTest")
+ assertTasksExecuted(":testUsaFreeReleaseUnitTest")
+ assertTasksExecuted(":testUsaFreeDebugUnitTest")
+
+ assertTasksExecuted(":testGermanPaidReleaseUnitTest")
+ assertTasksExecuted(":testGermanPaidDebugUnitTest")
+ assertTasksExecuted(":testGermanFreeReleaseUnitTest")
+ assertTasksExecuted(":testGermanFreeDebugUnitTest")
+
+ assertNull(task(":assembleUsaPaidDebugAndroidTest"))
+ assertNull(task(":assembleUsaFreeDebugAndroidTest"))
+ assertNull(task(":assembleGermanPaidDebugAndroidTest"))
+ assertNull(task(":assembleGermanFreeDebugAndroidTest"))
+ }
+
+ build("assembleAndroidTest") {
+ assertTasksExecuted(":assembleUsaPaidDebugAndroidTest")
+ assertTasksExecuted(":assembleUsaFreeDebugAndroidTest")
+ assertTasksExecuted(":assembleGermanPaidDebugAndroidTest")
+ assertTasksExecuted(":assembleGermanFreeDebugAndroidTest")
+ }
+ }
}
}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/build.gradle.kts
new file mode 100644
index 00000000000..d83cc673ab6
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/build.gradle.kts
@@ -0,0 +1,63 @@
+@file:OptIn(ExperimentalKotlinGradlePluginApi::class)
+
+import org.jetbrains.kotlin.gradle.plugin.ExperimentalKotlinGradlePluginApi
+
+plugins {
+ id("com.android.library")
+ kotlin("multiplatform")
+}
+
+
+android {
+ compileSdk = 31
+ defaultConfig {
+ minSdk = 31
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ android.flavorDimensions.add("market")
+ android.flavorDimensions.add("price")
+ android.productFlavors.create("german").dimension = "market"
+ android.productFlavors.create("usa").dimension = "market"
+ android.productFlavors.create("paid").dimension = "price"
+ android.productFlavors.create("free").dimension = "price"
+}
+
+repositories {
+ mavenLocal()
+ mavenCentral()
+ google()
+}
+
+kotlin {
+ android()
+ jvm()
+
+ val commonMain by sourceSets.getting
+ val commonTest by sourceSets.getting
+ val androidMain by sourceSets.getting
+
+ val androidUnitTest by sourceSets.getting
+ val androidInstrumentedTest by sourceSets.getting
+
+ commonTest.dependencies {
+ implementation(kotlin("test-junit"))
+ }
+
+ androidUnitTest.dependencies {
+ implementation("org.robolectric:robolectric:4.8")
+ implementation("androidx.test:core:1.4.0")
+ implementation("androidx.test:core-ktx:1.4.0")
+ }
+
+ androidInstrumentedTest.dependencies {
+ implementation("androidx.test:runner:1.4.0")
+ implementation("androidx.test:rules:1.4.0")
+ }
+
+ sourceSets.invokeWhenCreated("androidUnitTestGermanFreeDebug") {
+ dependencies {
+ implementation("com.squareup.okio:okio:3.2.0")
+ }
+ }
+}
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/gradle.properties b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/gradle.properties
new file mode 100644
index 00000000000..df5f3ea09bf
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/gradle.properties
@@ -0,0 +1,2 @@
+kotlin.mpp.androidSourceSetLayoutVersion=2
+android.useAndroidX=true
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidInstrumentedTest/kotlin/AndroidInstrumentedTest.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidInstrumentedTest/kotlin/AndroidInstrumentedTest.kt
new file mode 100644
index 00000000000..150da558edc
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidInstrumentedTest/kotlin/AndroidInstrumentedTest.kt
@@ -0,0 +1,13 @@
+import androidx.test.platform.app.InstrumentationRegistry
+import org.junit.Test
+
+class AndroidInstrumentedTest {
+
+ @Test
+ fun someTest() {
+ commonMainExpect()
+ CommonMain.invoke()
+ AndroidMain.invoke()
+ AndroidMain.invoke(InstrumentationRegistry.getInstrumentation().targetContext.applicationContext)
+ }
+}
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidMain/AndroidManifest.xml b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidMain/AndroidManifest.xml
new file mode 100644
index 00000000000..90c72fdddb1
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidMain/AndroidManifest.xml
@@ -0,0 +1 @@
+
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidMain/kotlin/AndroidMain.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidMain/kotlin/AndroidMain.kt
new file mode 100644
index 00000000000..fead70440b1
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidMain/kotlin/AndroidMain.kt
@@ -0,0 +1,14 @@
+import android.app.Application
+import android.content.Context
+
+object AndroidMain {
+ operator fun invoke(context: Context): AndroidMain {
+ context.applicationContext
+ return this
+ }
+
+ operator fun invoke(): AndroidMain {
+ CommonMain.invoke()
+ return AndroidMain
+ }
+}
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidMain/kotlin/commonMainExpect.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidMain/kotlin/commonMainExpect.kt
new file mode 100644
index 00000000000..63da8a1c5bb
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidMain/kotlin/commonMainExpect.kt
@@ -0,0 +1,3 @@
+actual fun commonMainExpect(): CommonMain {
+ return CommonMain.invoke()
+}
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidUnitTest/kotlin/AndroidUnitTest.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidUnitTest/kotlin/AndroidUnitTest.kt
new file mode 100644
index 00000000000..a0fbc5dedba
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidUnitTest/kotlin/AndroidUnitTest.kt
@@ -0,0 +1,16 @@
+import androidx.test.core.app.ApplicationProvider
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.RobolectricTestRunner
+
+@RunWith(RobolectricTestRunner::class)
+class AndroidUnitTest {
+ @Test
+ fun someTest() {
+ commonMainExpect()
+ CommonMain.invoke()
+ AndroidMain.invoke()
+ AndroidMain.invoke(ApplicationProvider.getApplicationContext())
+ CommonTest().someTest()
+ }
+}
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidUnitTestGermanFreeDebug/kotlin/AndroidUnitTestGermanFreeDebug.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidUnitTestGermanFreeDebug/kotlin/AndroidUnitTestGermanFreeDebug.kt
new file mode 100644
index 00000000000..9e43e671cd3
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/androidUnitTestGermanFreeDebug/kotlin/AndroidUnitTestGermanFreeDebug.kt
@@ -0,0 +1,18 @@
+import androidx.test.core.app.ApplicationProvider
+import okio.Path.Companion.toPath
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.RobolectricTestRunner
+
+@RunWith(RobolectricTestRunner::class)
+class AndroidUnitTestGermanFreeDebug {
+ @Test
+ fun someTest() {
+ "".toPath()
+ commonMainExpect()
+ CommonMain.invoke()
+ AndroidMain.invoke()
+ AndroidMain.invoke(ApplicationProvider.getApplicationContext())
+ CommonTest().someTest()
+ }
+}
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/commonMain/kotlin/CommonMain.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/commonMain/kotlin/CommonMain.kt
new file mode 100644
index 00000000000..628e069e151
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/commonMain/kotlin/CommonMain.kt
@@ -0,0 +1,5 @@
+object CommonMain {
+ operator fun invoke() = CommonMain
+}
+
+expect fun commonMainExpect(): CommonMain
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/commonTest/kotlin/CommonTest.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/commonTest/kotlin/CommonTest.kt
new file mode 100644
index 00000000000..140a6e0de82
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/commonTest/kotlin/CommonTest.kt
@@ -0,0 +1,9 @@
+import kotlin.test.Test
+
+class CommonTest {
+ @Test
+ fun someTest() {
+ commonMainExpect()
+ CommonMain.invoke()
+ }
+}
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/jvmMain/kotlin/commonMainExpect.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/jvmMain/kotlin/commonMainExpect.kt
new file mode 100644
index 00000000000..63da8a1c5bb
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/jvmMain/kotlin/commonMainExpect.kt
@@ -0,0 +1,3 @@
+actual fun commonMainExpect(): CommonMain {
+ return CommonMain.invoke()
+}
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/jvmTest/kotlin/JvmTest.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/jvmTest/kotlin/JvmTest.kt
new file mode 100644
index 00000000000..de95f68dae6
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformAndroidSourceSetLayout2/src/jvmTest/kotlin/JvmTest.kt
@@ -0,0 +1,9 @@
+import org.junit.Test
+
+class JvmTest {
+ @Test
+ fun someTest() {
+ CommonMain.invoke()
+ CommonTest().someTest()
+ }
+}
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/KotlinAndroidSourceSets.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/KotlinAndroidSourceSets.kt
index 9d062609394..4dc50758881 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/KotlinAndroidSourceSets.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/KotlinAndroidSourceSets.kt
@@ -34,7 +34,11 @@ internal object KotlinAndroidSourceSets {
/* Ensures that each KotlinSourceSet only invokes the 'configurator' once */
val configuredKotlinSourceSets = mutableSetOf()
- /* Hook eagerly into AndroidSourceSet creation */
+ /*
+ Hook eagerly into AndroidSourceSet creation
+ Some 'base' source sets shall be created eagerly, as soon as available, too also
+ make them available in the buildscript dsl immediately.
+ */
android.sourceSets.all { androidSourceSet ->
val kotlinSourceSetName = naming.kotlinSourceSetName(target.disambiguationClassifier, androidSourceSet.name) ?: return@all
val kotlinSourceSet = kotlin.getOrCreateKotlinSourceSet(kotlinSourceSetName, androidSourceSet)
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/configurator/KotlinAndroidSourceSetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/configurator/KotlinAndroidSourceSetConfigurator.kt
index 42b4ba748eb..5c3643c498b 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/configurator/KotlinAndroidSourceSetConfigurator.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/configurator/KotlinAndroidSourceSetConfigurator.kt
@@ -35,21 +35,6 @@ internal fun KotlinAndroidSourceSetConfigurator(
return CompositeKotlinAndroidSourceSetConfigurator(configurators.filterNotNull())
}
-internal operator fun KotlinAndroidSourceSetConfigurator.plus(
- other: KotlinAndroidSourceSetConfigurator
-): KotlinAndroidSourceSetConfigurator {
- val configurators = when {
- this is CompositeKotlinAndroidSourceSetConfigurator && other is CompositeKotlinAndroidSourceSetConfigurator ->
- this.configurators + other.configurators
-
- this is CompositeKotlinAndroidSourceSetConfigurator -> this.configurators + other
- other is CompositeKotlinAndroidSourceSetConfigurator -> listOf(this) + other.configurators
- else -> listOf(this, other)
- }
-
- return CompositeKotlinAndroidSourceSetConfigurator(configurators)
-}
-
private class CompositeKotlinAndroidSourceSetConfigurator(
val configurators: List
) : KotlinAndroidSourceSetConfigurator {