From f2d2fb9e6bf0f8fbe76e7edf178ba3f02dd77366 Mon Sep 17 00:00:00 2001 From: Sergey Igushkin Date: Mon, 2 Sep 2019 20:55:13 +0300 Subject: [PATCH] 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. --- .../kotlin/gradle/NewMultiplatformIT.kt | 32 +++++++++++++++++-- .../kotlin/gradle/plugin/KotlinPlugin.kt | 26 +++++++++------ .../gradle/targets/jvm/KotlinJvmTarget.kt | 2 +- 3 files changed, 48 insertions(+), 12 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt index 0a157b3a0e3..28ca144e7f8 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt @@ -315,12 +315,31 @@ class NewMultiplatformIT : BaseGradleIT() { apply plugin: 'com.github.johnrengelman.shadow' apply plugin: 'application' + apply plugin: 'kotlin-kapt' // Check that Kapts works, generates and compiles sources mainClassName = 'com.example.lib.CommonKt' + + dependencies { + jvm6MainImplementation("com.google.dagger:dagger:2.24") + kapt("com.google.dagger:dagger-compiler:2.24") + } """.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) = if (testJavaSupportInJvmTargets) "src/jvm6${compilationName.capitalize()}/java" else "src/$compilationName/java" @@ -372,6 +391,12 @@ class NewMultiplatformIT : BaseGradleIT() { assertSuccessful() val expectedMainClasses = 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", "java/main/com/example/lib/JavaClassInJava.class", "java/test/com/example/lib/JavaTest.class" @@ -381,7 +406,10 @@ class NewMultiplatformIT : BaseGradleIT() { val jvmTestTaskName = if (testJavaSupportInJvmTargets) "jvm6Test" else "test" 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) { assertNotContains(KotlinJvmWithJavaTargetPreset.DEPRECATION_WARNING) @@ -2111,4 +2139,4 @@ class NewMultiplatformIT : BaseGradleIT() { checkIntegrationTestOutput(nativeHostTargetName) } } -} \ No newline at end of file +} 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 afd24f47e47..5cd79174db7 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 @@ -36,6 +36,7 @@ import org.jetbrains.kotlin.gradle.logging.kotlinWarn import org.jetbrains.kotlin.gradle.model.builder.KotlinModelBuilder import org.jetbrains.kotlin.gradle.plugin.mpp.* 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.KotlinCompile import org.jetbrains.kotlin.gradle.utils.* @@ -64,7 +65,14 @@ internal abstract class KotlinSourceSetProcessor>( protected val kotlinTask: TaskProvider = 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 get() { @@ -102,21 +110,19 @@ internal abstract class KotlinSourceSetProcessor>( } private fun addKotlinDirectoriesToJavaSourceSet() { - if (javaSourceSet == null) - return + val java = javaSourceSet ?: return // 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) + java.allJava.srcDirs(kotlinSrcDirsToAdd) + java.allSource.srcDirs(kotlinSrcDirsToAdd) } private fun filterOutJavaSrcDirsIfPossible(sourceDirectorySet: SourceDirectorySet): FileCollection { - if (javaSourceSet == null) - return sourceDirectorySet + val java = javaSourceSet ?: return sourceDirectorySet // 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" }) { @@ -129,7 +135,7 @@ internal abstract class KotlinSourceSetProcessor>( } // 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() { @@ -177,7 +183,9 @@ internal class Kotlin2JvmSourceSetProcessor( 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 javaTask = javaSourceSet?.let { project.tasks.findByName(it.compileJavaTaskName) as JavaCompile } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTarget.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTarget.kt index 764d2e3182a..c532d7d80ca 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTarget.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTarget.kt @@ -19,6 +19,7 @@ import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmCompilation import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinOnlyTarget +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaCompilation import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation import java.util.concurrent.Callable import javax.inject.Inject @@ -61,7 +62,6 @@ open class KotlinJvmTarget @Inject constructor( javaPluginConvention.sourceSets.all { javaSourceSet -> val compilation = compilations.getByName(javaSourceSet.name) val compileJavaTask = project.tasks.getByName(javaSourceSet.compileJavaTaskName) as AbstractCompile - configureJavaTask(compilation.compileKotlinTask, compileJavaTask, project.logger) setupJavaSourceSetSourcesAndResources(javaSourceSet, compilation)