diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt index 0fcface2746..f7b340bf85d 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt @@ -826,4 +826,39 @@ class KotlinGradleIT : BaseGradleIT() { assertTasksExecuted(compileKotlinTasks) } } + + @Test + fun testKotlinSourceInJavaSourceSet() = with(Project("multiplatformProject")) { + setupWorkingDir() + + val srcDirPrefix = "srcDir: " + + gradleBuildScript().appendText( + "\n" + """ + subprojects { project -> + project.afterEvaluate { + project.sourceSets.each { sourceSet -> + sourceSet.allJava.srcDirs.each { srcDir -> + println "$srcDirPrefix" + srcDir.canonicalPath + } + } + } + } + """.trimIndent() + ) + val srcDirRegex = "$srcDirPrefix(.*)".toRegex() + + build("help") { + assertSuccessful() + val reportedSrcDirs = srcDirRegex.findAll(output).map { it.groupValues[1] }.toSet() + + val expectedKotlinDirs = listOf("lib", "libJvm", "libJs").flatMap { module -> + listOf("main", "test").map { sourceSet -> + projectDir.resolve("$module/src/$sourceSet/kotlin").absolutePath + } + } + + expectedKotlinDirs.forEach { assertTrue(it in reportedSrcDirs, "$it should be included into the Java source sets") } + } + } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt index ed1e69d485b..d82a61e0156 100755 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt @@ -37,7 +37,6 @@ import org.jetbrains.kotlin.gradle.tasks.* import org.jetbrains.kotlin.gradle.utils.* import java.io.File import java.net.URL -import java.util.* import java.util.concurrent.Callable import java.util.jar.Manifest @@ -53,7 +52,7 @@ internal abstract class KotlinSourceSetProcessor>( val taskDescription: String, val kotlinCompilation: KotlinCompilation ) { - abstract protected fun doTargetSpecificProcessing() + protected abstract fun doTargetSpecificProcessing() protected val logger = Logging.getLogger(this.javaClass)!! protected val isSeparateClassesDirSupported: Boolean by lazy { @@ -65,6 +64,8 @@ internal abstract class KotlinSourceSetProcessor>( protected val kotlinTask: T = createKotlinCompileTask() + protected val javaSourceSet: SourceSet? = (kotlinCompilation as? KotlinWithJavaCompilation)?.javaSourceSet + protected open val defaultKotlinDestinationDir: File get() { return if (isSeparateClassesDirSupported) { @@ -92,40 +93,21 @@ internal abstract class KotlinSourceSetProcessor>( } open fun run() { + addKotlinDirectoriesToJavaSourceSet() doTargetSpecificProcessing() } - protected abstract fun doCreateTask(project: Project, taskName: String): T -} - -internal abstract class KotlinJavaSourceSetProcessor>( - project: Project, - tasksProvider: KotlinTasksProvider, - taskDescription: String, - val javaSourceSet: SourceSet?, - kotlinCompilation: KotlinCompilation -): KotlinSourceSetProcessor( - project, tasksProvider, taskDescription, kotlinCompilation -) { - override fun run() { - addKotlinDirSetToSources() - super.run() - } - - private fun addKotlinDirSetToSources() { + private fun addKotlinDirectoriesToJavaSourceSet() { if (javaSourceSet == null) return - val kotlinDirSets = kotlinCompilation.kotlinSourceSets.map(KotlinSourceSet::kotlin) - - // Try to avoid duplicate Java sources in allSource: - val kotlinSrcDirsToAdd = kotlinDirSets.map { filterOutJavaSrcDirsIfPossible(it) } - - kotlinSrcDirsToAdd.forEach { kotlinSrcDirs -> - javaSourceSet.allJava.srcDirs(kotlinSrcDirs) - javaSourceSet.allSource.srcDirs(kotlinSrcDirs) - javaSourceSet.resources.filter.exclude { it.file in kotlinSrcDirs } + // Try to avoid duplicate Java sources in allSource; run lazily to allow changing the directory set: + val kotlinSrcDirsToAdd = Callable { + kotlinCompilation.kotlinSourceSets.map { filterOutJavaSrcDirsIfPossible(it.kotlin) } } + + javaSourceSet.allJava.srcDirs(kotlinSrcDirsToAdd) + javaSourceSet.allSource.srcDirs(kotlinSrcDirsToAdd) } private fun filterOutJavaSrcDirsIfPossible(sourceDirectorySet: SourceDirectorySet): FileCollection { @@ -145,6 +127,8 @@ internal abstract class KotlinJavaSourceSetProcessor( - project, tasksProvider, taskDescription = "Compiles the $kotlinCompilation.", - javaSourceSet = if (kotlinCompilation is KotlinWithJavaCompilation) kotlinCompilation.javaSourceSet else null, - kotlinCompilation = kotlinCompilation +) : KotlinSourceSetProcessor( + project, tasksProvider, "Compiles the $kotlinCompilation.", kotlinCompilation ) { override val defaultKotlinDestinationDir: File get() = if (!isSeparateClassesDirSupported)