Fix Kotlin source directories not added into the Java source set srcDirs

Before the new MPP, Kotlin source directories were added to the Java
source set's `allJava` and `allSource` by all of the Kotlin plugins,
including common and JS ones. As it turned out, this was required by the
IntelliJ Gradle import.

* Make all `KotlinSourceSetProcessor`s (not just JVM) check whether a
  compilation has a Java source set and add the Kotlin source
  directories to `allSource` and `allJava`

* Also disable the unclear resource `exclude` for the Java source set
  that filters Kotlin source directories out of the resources

Issue #KT-26020 Fixed
Issue #KT-26267 Fixed
This commit is contained in:
Sergey Igushkin
2018-08-20 19:25:27 +03:00
parent f4eee4c2e4
commit 674e464230
2 changed files with 50 additions and 33 deletions
@@ -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") }
}
}
}
@@ -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<T : AbstractKotlinCompile<*>>(
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<T : AbstractKotlinCompile<*>>(
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<T : AbstractKotlinCompile<*>>(
}
open fun run() {
addKotlinDirectoriesToJavaSourceSet()
doTargetSpecificProcessing()
}
protected abstract fun doCreateTask(project: Project, taskName: String): T
}
internal abstract class KotlinJavaSourceSetProcessor<T : AbstractKotlinCompile<*>>(
project: Project,
tasksProvider: KotlinTasksProvider,
taskDescription: String,
val javaSourceSet: SourceSet?,
kotlinCompilation: KotlinCompilation
): KotlinSourceSetProcessor<T>(
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<T : AbstractKotlinCompile<*
// Build a lazily-resolved file collection that filters out Java sources from sources of this sourceDirectorySet
return getSourceDirectories(sourceDirectorySet).minus(getSourceDirectories(javaSourceSet.java))
}
protected abstract fun doCreateTask(project: Project, taskName: String): T
}
internal class Kotlin2JvmSourceSetProcessor(
@@ -152,10 +136,8 @@ internal class Kotlin2JvmSourceSetProcessor(
tasksProvider: KotlinTasksProvider,
kotlinCompilation: KotlinCompilation,
private val kotlinPluginVersion: String
) : KotlinJavaSourceSetProcessor<KotlinCompile>(
project, tasksProvider, taskDescription = "Compiles the $kotlinCompilation.",
javaSourceSet = if (kotlinCompilation is KotlinWithJavaCompilation) kotlinCompilation.javaSourceSet else null,
kotlinCompilation = kotlinCompilation
) : KotlinSourceSetProcessor<KotlinCompile>(
project, tasksProvider, "Compiles the $kotlinCompilation.", kotlinCompilation
) {
override val defaultKotlinDestinationDir: File
get() = if (!isSeparateClassesDirSupported)