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) 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 org.jetbrains.kotlin.gradle.utils.*
import java.io.File import java.io.File
import java.net.URL import java.net.URL
import java.util.*
import java.util.concurrent.Callable import java.util.concurrent.Callable
import java.util.jar.Manifest import java.util.jar.Manifest
@@ -53,7 +52,7 @@ internal abstract class KotlinSourceSetProcessor<T : AbstractKotlinCompile<*>>(
val taskDescription: String, val taskDescription: String,
val kotlinCompilation: KotlinCompilation val kotlinCompilation: KotlinCompilation
) { ) {
abstract protected fun doTargetSpecificProcessing() protected abstract fun doTargetSpecificProcessing()
protected val logger = Logging.getLogger(this.javaClass)!! protected val logger = Logging.getLogger(this.javaClass)!!
protected val isSeparateClassesDirSupported: Boolean by lazy { protected val isSeparateClassesDirSupported: Boolean by lazy {
@@ -65,6 +64,8 @@ internal abstract class KotlinSourceSetProcessor<T : AbstractKotlinCompile<*>>(
protected val kotlinTask: T = createKotlinCompileTask() protected val kotlinTask: T = createKotlinCompileTask()
protected val javaSourceSet: SourceSet? = (kotlinCompilation as? KotlinWithJavaCompilation)?.javaSourceSet
protected open val defaultKotlinDestinationDir: File protected open val defaultKotlinDestinationDir: File
get() { get() {
return if (isSeparateClassesDirSupported) { return if (isSeparateClassesDirSupported) {
@@ -92,40 +93,21 @@ internal abstract class KotlinSourceSetProcessor<T : AbstractKotlinCompile<*>>(
} }
open fun run() { open fun run() {
addKotlinDirectoriesToJavaSourceSet()
doTargetSpecificProcessing() doTargetSpecificProcessing()
} }
protected abstract fun doCreateTask(project: Project, taskName: String): T private fun addKotlinDirectoriesToJavaSourceSet() {
}
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() {
if (javaSourceSet == null) if (javaSourceSet == null)
return return
val kotlinDirSets = kotlinCompilation.kotlinSourceSets.map(KotlinSourceSet::kotlin) // Try to avoid duplicate Java sources in allSource; run lazily to allow changing the directory set:
val kotlinSrcDirsToAdd = Callable {
// Try to avoid duplicate Java sources in allSource: kotlinCompilation.kotlinSourceSets.map { filterOutJavaSrcDirsIfPossible(it.kotlin) }
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 }
} }
javaSourceSet.allJava.srcDirs(kotlinSrcDirsToAdd)
javaSourceSet.allSource.srcDirs(kotlinSrcDirsToAdd)
} }
private fun filterOutJavaSrcDirsIfPossible(sourceDirectorySet: SourceDirectorySet): FileCollection { 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 // Build a lazily-resolved file collection that filters out Java sources from sources of this sourceDirectorySet
return getSourceDirectories(sourceDirectorySet).minus(getSourceDirectories(javaSourceSet.java)) return getSourceDirectories(sourceDirectorySet).minus(getSourceDirectories(javaSourceSet.java))
} }
protected abstract fun doCreateTask(project: Project, taskName: String): T
} }
internal class Kotlin2JvmSourceSetProcessor( internal class Kotlin2JvmSourceSetProcessor(
@@ -152,10 +136,8 @@ internal class Kotlin2JvmSourceSetProcessor(
tasksProvider: KotlinTasksProvider, tasksProvider: KotlinTasksProvider,
kotlinCompilation: KotlinCompilation, kotlinCompilation: KotlinCompilation,
private val kotlinPluginVersion: String private val kotlinPluginVersion: String
) : KotlinJavaSourceSetProcessor<KotlinCompile>( ) : KotlinSourceSetProcessor<KotlinCompile>(
project, tasksProvider, taskDescription = "Compiles the $kotlinCompilation.", project, tasksProvider, "Compiles the $kotlinCompilation.", kotlinCompilation
javaSourceSet = if (kotlinCompilation is KotlinWithJavaCompilation) kotlinCompilation.javaSourceSet else null,
kotlinCompilation = kotlinCompilation
) { ) {
override val defaultKotlinDestinationDir: File override val defaultKotlinDestinationDir: File
get() = if (!isSeparateClassesDirSupported) get() = if (!isSeparateClassesDirSupported)