Fix Kapt-generated sources not compiled by jvm.withJava(), KT-32804
Given that the Kapt subplugin creates new tasks, it is impossible to run it in the context of lazy task configuration. Disable lazy task configuration for Kotlin/JVM by always accessing the task instance until subplugins are refactored to be able to properly work with task configuration avoidance.
This commit is contained in:
+30
-2
@@ -315,12 +315,31 @@ class NewMultiplatformIT : BaseGradleIT() {
|
|||||||
|
|
||||||
apply plugin: 'com.github.johnrengelman.shadow'
|
apply plugin: 'com.github.johnrengelman.shadow'
|
||||||
apply plugin: 'application'
|
apply plugin: 'application'
|
||||||
|
apply plugin: 'kotlin-kapt' // Check that Kapts works, generates and compiles sources
|
||||||
|
|
||||||
mainClassName = 'com.example.lib.CommonKt'
|
mainClassName = 'com.example.lib.CommonKt'
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
jvm6MainImplementation("com.google.dagger:dagger:2.24")
|
||||||
|
kapt("com.google.dagger:dagger-compiler:2.24")
|
||||||
|
}
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check Kapt:
|
||||||
|
projectDir.resolve("src/jvm6Main/kotlin/Main.kt").appendText(
|
||||||
|
"\n" + """
|
||||||
|
interface Iface
|
||||||
|
|
||||||
|
@dagger.Module
|
||||||
|
object Module {
|
||||||
|
@JvmStatic @dagger.Provides
|
||||||
|
fun provideHeater(): Iface = object : Iface { }
|
||||||
|
}
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
|
||||||
fun javaSourceRootForCompilation(compilationName: String) =
|
fun javaSourceRootForCompilation(compilationName: String) =
|
||||||
if (testJavaSupportInJvmTargets) "src/jvm6${compilationName.capitalize()}/java" else "src/$compilationName/java"
|
if (testJavaSupportInJvmTargets) "src/jvm6${compilationName.capitalize()}/java" else "src/$compilationName/java"
|
||||||
|
|
||||||
@@ -372,6 +391,12 @@ class NewMultiplatformIT : BaseGradleIT() {
|
|||||||
assertSuccessful()
|
assertSuccessful()
|
||||||
val expectedMainClasses =
|
val expectedMainClasses =
|
||||||
classesWithoutJava + setOf(
|
classesWithoutJava + setOf(
|
||||||
|
// classes for Kapt test:
|
||||||
|
"java/main/com/example/lib/Module_ProvideHeaterFactory.class",
|
||||||
|
"kotlin/jvm6/main/com/example/lib/Module\$provideHeater\$1.class",
|
||||||
|
"kotlin/jvm6/main/com/example/lib/Iface.class",
|
||||||
|
"kotlin/jvm6/main/com/example/lib/Module.class",
|
||||||
|
// other added classes:
|
||||||
"kotlin/jvm6/main/com/example/lib/KotlinClassInJava.class",
|
"kotlin/jvm6/main/com/example/lib/KotlinClassInJava.class",
|
||||||
"java/main/com/example/lib/JavaClassInJava.class",
|
"java/main/com/example/lib/JavaClassInJava.class",
|
||||||
"java/test/com/example/lib/JavaTest.class"
|
"java/test/com/example/lib/JavaTest.class"
|
||||||
@@ -381,7 +406,10 @@ class NewMultiplatformIT : BaseGradleIT() {
|
|||||||
|
|
||||||
val jvmTestTaskName = if (testJavaSupportInJvmTargets) "jvm6Test" else "test"
|
val jvmTestTaskName = if (testJavaSupportInJvmTargets) "jvm6Test" else "test"
|
||||||
assertTasksExecuted(":$jvmTestTaskName")
|
assertTasksExecuted(":$jvmTestTaskName")
|
||||||
assertFileExists("build/reports/tests/allTests/classes/com.example.lib.JavaTest.html")
|
|
||||||
|
if (testJavaSupportInJvmTargets) {
|
||||||
|
assertFileExists("build/reports/tests/allTests/classes/com.example.lib.JavaTest.html")
|
||||||
|
}
|
||||||
|
|
||||||
if (testJavaSupportInJvmTargets) {
|
if (testJavaSupportInJvmTargets) {
|
||||||
assertNotContains(KotlinJvmWithJavaTargetPreset.DEPRECATION_WARNING)
|
assertNotContains(KotlinJvmWithJavaTargetPreset.DEPRECATION_WARNING)
|
||||||
@@ -2111,4 +2139,4 @@ class NewMultiplatformIT : BaseGradleIT() {
|
|||||||
checkIntegrationTestOutput(nativeHostTargetName)
|
checkIntegrationTestOutput(nativeHostTargetName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-9
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.gradle.logging.kotlinWarn
|
|||||||
import org.jetbrains.kotlin.gradle.model.builder.KotlinModelBuilder
|
import org.jetbrains.kotlin.gradle.model.builder.KotlinModelBuilder
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
||||||
import org.jetbrains.kotlin.gradle.scripting.internal.ScriptingGradleSubplugin
|
import org.jetbrains.kotlin.gradle.scripting.internal.ScriptingGradleSubplugin
|
||||||
|
import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
|
||||||
import org.jetbrains.kotlin.gradle.tasks.*
|
import org.jetbrains.kotlin.gradle.tasks.*
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||||
import org.jetbrains.kotlin.gradle.utils.*
|
import org.jetbrains.kotlin.gradle.utils.*
|
||||||
@@ -64,7 +65,14 @@ internal abstract class KotlinSourceSetProcessor<T : AbstractKotlinCompile<*>>(
|
|||||||
|
|
||||||
protected val kotlinTask: TaskProvider<out T> = registerKotlinCompileTask()
|
protected val kotlinTask: TaskProvider<out T> = registerKotlinCompileTask()
|
||||||
|
|
||||||
protected val javaSourceSet: SourceSet? = (kotlinCompilation as? KotlinWithJavaCompilation<*>)?.javaSourceSet
|
protected val javaSourceSet: SourceSet?
|
||||||
|
get() =
|
||||||
|
(kotlinCompilation as? KotlinWithJavaCompilation<*>)?.javaSourceSet
|
||||||
|
?: kotlinCompilation.target.let {
|
||||||
|
if (it is KotlinJvmTarget && it.withJavaEnabled)
|
||||||
|
project.convention.getPlugin(JavaPluginConvention::class.java).sourceSets.maybeCreate(kotlinCompilation.name)
|
||||||
|
else null
|
||||||
|
}
|
||||||
|
|
||||||
private val defaultKotlinDestinationDir: File
|
private val defaultKotlinDestinationDir: File
|
||||||
get() {
|
get() {
|
||||||
@@ -102,21 +110,19 @@ internal abstract class KotlinSourceSetProcessor<T : AbstractKotlinCompile<*>>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun addKotlinDirectoriesToJavaSourceSet() {
|
private fun addKotlinDirectoriesToJavaSourceSet() {
|
||||||
if (javaSourceSet == null)
|
val java = javaSourceSet ?: return
|
||||||
return
|
|
||||||
|
|
||||||
// Try to avoid duplicate Java sources in allSource; run lazily to allow changing the directory set:
|
// Try to avoid duplicate Java sources in allSource; run lazily to allow changing the directory set:
|
||||||
val kotlinSrcDirsToAdd = Callable {
|
val kotlinSrcDirsToAdd = Callable {
|
||||||
kotlinCompilation.kotlinSourceSets.map { filterOutJavaSrcDirsIfPossible(it.kotlin) }
|
kotlinCompilation.kotlinSourceSets.map { filterOutJavaSrcDirsIfPossible(it.kotlin) }
|
||||||
}
|
}
|
||||||
|
|
||||||
javaSourceSet.allJava.srcDirs(kotlinSrcDirsToAdd)
|
java.allJava.srcDirs(kotlinSrcDirsToAdd)
|
||||||
javaSourceSet.allSource.srcDirs(kotlinSrcDirsToAdd)
|
java.allSource.srcDirs(kotlinSrcDirsToAdd)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun filterOutJavaSrcDirsIfPossible(sourceDirectorySet: SourceDirectorySet): FileCollection {
|
private fun filterOutJavaSrcDirsIfPossible(sourceDirectorySet: SourceDirectorySet): FileCollection {
|
||||||
if (javaSourceSet == null)
|
val java = javaSourceSet ?: return sourceDirectorySet
|
||||||
return sourceDirectorySet
|
|
||||||
|
|
||||||
// If the API used below is not available, fall back to not filtering the Java sources.
|
// If the API used below is not available, fall back to not filtering the Java sources.
|
||||||
if (SourceDirectorySet::class.java.methods.none { it.name == "getSourceDirectories" }) {
|
if (SourceDirectorySet::class.java.methods.none { it.name == "getSourceDirectories" }) {
|
||||||
@@ -129,7 +135,7 @@ internal abstract class KotlinSourceSetProcessor<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(java.java))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createAdditionalClassesTaskForIdeRunner() {
|
private fun createAdditionalClassesTaskForIdeRunner() {
|
||||||
@@ -177,7 +183,9 @@ internal class Kotlin2JvmSourceSetProcessor(
|
|||||||
|
|
||||||
ScriptingGradleSubplugin.configureForSourceSet(project, kotlinCompilation.compilationName)
|
ScriptingGradleSubplugin.configureForSourceSet(project, kotlinCompilation.compilationName)
|
||||||
|
|
||||||
project.runOnceAfterEvaluated("Kotlin2JvmSourceSetProcessor.doTargetSpecificProcessing", kotlinTask) {
|
// TODO: here, the tasks are always triggered for configuration; once the subplugins are able to work without task instances,
|
||||||
|
// ensure that task configuration is properly avoided here;
|
||||||
|
project.whenEvaluated {
|
||||||
val kotlinTaskInstance = kotlinTask.get()
|
val kotlinTaskInstance = kotlinTask.get()
|
||||||
val javaTask = javaSourceSet?.let { project.tasks.findByName(it.compileJavaTaskName) as JavaCompile }
|
val javaTask = javaSourceSet?.let { project.tasks.findByName(it.compileJavaTaskName) as JavaCompile }
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
|||||||
import org.jetbrains.kotlin.gradle.plugin.*
|
import org.jetbrains.kotlin.gradle.plugin.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmCompilation
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmCompilation
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinOnlyTarget
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinOnlyTarget
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaCompilation
|
||||||
import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation
|
import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation
|
||||||
import java.util.concurrent.Callable
|
import java.util.concurrent.Callable
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -61,7 +62,6 @@ open class KotlinJvmTarget @Inject constructor(
|
|||||||
javaPluginConvention.sourceSets.all { javaSourceSet ->
|
javaPluginConvention.sourceSets.all { javaSourceSet ->
|
||||||
val compilation = compilations.getByName(javaSourceSet.name)
|
val compilation = compilations.getByName(javaSourceSet.name)
|
||||||
val compileJavaTask = project.tasks.getByName(javaSourceSet.compileJavaTaskName) as AbstractCompile
|
val compileJavaTask = project.tasks.getByName(javaSourceSet.compileJavaTaskName) as AbstractCompile
|
||||||
configureJavaTask(compilation.compileKotlinTask, compileJavaTask, project.logger)
|
|
||||||
|
|
||||||
setupJavaSourceSetSourcesAndResources(javaSourceSet, compilation)
|
setupJavaSourceSetSourcesAndResources(javaSourceSet, compilation)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user