diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/Kotlin2JvmSourceSetProcessor.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/Kotlin2JvmSourceSetProcessor.kt index 794124c407f..d4bfe7420ac 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/Kotlin2JvmSourceSetProcessor.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/Kotlin2JvmSourceSetProcessor.kt @@ -13,6 +13,7 @@ import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.compile.AbstractCompile import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompilerOptions import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin +import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle.Stage.AfterEvaluateBuildscript import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle.Stage.AfterFinaliseDsl import org.jetbrains.kotlin.gradle.scripting.internal.ScriptingGradleSubplugin import org.jetbrains.kotlin.gradle.tasks.KotlinCompile @@ -53,14 +54,14 @@ internal class Kotlin2JvmSourceSetProcessor( ScriptingGradleSubplugin.configureForSourceSet(project, compilationInfo.compilationName) - project.whenEvaluated { + project.launchInStage(AfterEvaluateBuildscript) { val subpluginEnvironment = SubpluginEnvironment.loadSubplugins(project) /* Not supported in KPM yet */ compilationInfo.tcsOrNull?.compilation?.let { compilation -> subpluginEnvironment.addSubpluginOptions(project, compilation) } - javaSourceSet?.let { java -> + javaSourceSet.await()?.let { java -> val javaTask = project.tasks.withType().named(java.compileJavaTaskName) javaTask.configure { javaCompile -> javaCompile.classpath += project.files(kotlinTask.flatMap { it.destinationDirectory }) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinSourceSetProcessor.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinSourceSetProcessor.kt index 93b29279605..e94bfbcd763 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinSourceSetProcessor.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinSourceSetProcessor.kt @@ -22,6 +22,8 @@ import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider import org.jetbrains.kotlin.gradle.tasks.configuration.AbstractKotlinCompileConfig import org.jetbrains.kotlin.gradle.tasks.registerTask +import org.jetbrains.kotlin.gradle.utils.Future +import org.jetbrains.kotlin.gradle.utils.future import org.jetbrains.kotlin.utils.addToStdlib.safeAs import java.util.concurrent.Callable @@ -37,11 +39,11 @@ internal abstract class KotlinSourceSetProcessor>( override val kotlinTask: TaskProvider = prepareKotlinCompileTask() - protected val javaSourceSet: SourceSet? + protected val javaSourceSet: Future get() = when (val compilation = compilationInfo.safeAs()?.origin) { - is KotlinWithJavaCompilation<*, *> -> compilation.javaSourceSet + is KotlinWithJavaCompilation<*, *> -> project.future { compilation.javaSourceSet } is KotlinJvmCompilation -> compilation.javaSourceSet - else -> null + else -> project.future { null } } private fun prepareKotlinCompileTask(): TaskProvider = @@ -90,32 +92,26 @@ internal abstract class KotlinSourceSetProcessor>( } override fun run() { - addKotlinDirectoriesToJavaSourceSet() doTargetSpecificProcessing() if (compilationInfo.tcsOrNull?.compilation is KotlinWithJavaCompilation<*, *>) { + project.launch { addKotlinDirectoriesToJavaSourceSet() } createAdditionalClassesTaskForIdeRunner() } } - private fun addKotlinDirectoriesToJavaSourceSet() { - val java = javaSourceSet ?: return + private suspend fun addKotlinDirectoriesToJavaSourceSet() { + val java = javaSourceSet.await() ?: return // Try to avoid duplicate Java sources in allSource; run lazily to allow changing the directory set: val kotlinSrcDirsToAdd = Callable { - compilationInfo.sources.map { filterOutJavaSrcDirsIfPossible(it) } + compilationInfo.sources.map { it.sourceDirectories.minus(java.java.sourceDirectories) } } java.allJava.srcDirs(kotlinSrcDirsToAdd) java.allSource.srcDirs(kotlinSrcDirsToAdd) } - private fun filterOutJavaSrcDirsIfPossible(sourceDirectories: SourceDirectorySet): FileCollection { - val java = javaSourceSet ?: return sourceDirectories - - // Build a lazily-resolved file collection that filters out Java sources from sources of this sourceDirectorySet - return sourceDirectories.sourceDirectories.minus(java.java.sourceDirectories) - } private fun createAdditionalClassesTaskForIdeRunner() { val kotlinCompilation = compilationInfo.tcsOrNull?.compilation ?: return diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmCompilation.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmCompilation.kt index 9ed864b017a..7519763823f 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmCompilation.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmCompilation.kt @@ -12,13 +12,16 @@ import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.compile.JavaCompile import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompilerOptions import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions -import org.jetbrains.kotlin.gradle.plugin.HasCompilerOptions -import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationWithResources +import org.jetbrains.kotlin.gradle.plugin.* +import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle.Stage.AfterFinaliseDsl import org.jetbrains.kotlin.gradle.plugin.internal.JavaSourceSetsAccessor import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationImpl import org.jetbrains.kotlin.gradle.plugin.variantImplementationFactory import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask +import org.jetbrains.kotlin.gradle.utils.CompletableFuture +import org.jetbrains.kotlin.gradle.utils.Future +import org.jetbrains.kotlin.gradle.utils.lenient import javax.inject.Inject open class KotlinJvmCompilation @Inject internal constructor( @@ -64,18 +67,32 @@ open class KotlinJvmCompilation @Inject internal constructor( * will be enabled after call to this method. */ internal val compileJavaTaskProviderSafe: Provider = target.project.providers - .provider { javaSourceSet } + .provider { javaSourceSet.lenient.getOrNull() } .flatMap { javaSourceSet -> checkNotNull(javaSourceSet) project.tasks.named(javaSourceSet.compileJavaTaskName, JavaCompile::class.java) } - internal val javaSourceSet - get() = if (target.withJavaEnabled) maybeCreateJavaSourceSet() else null + + internal val javaSourceSet: Future get() = javaSourceSetImpl + private val javaSourceSetImpl: CompletableFuture = CompletableFuture().also { future -> + /** + * If no SourceSet was set until 'AfterFinaliseDsl', then user really did never call into 'withJava', hence + * we can complete the Future with 'null' notifying everybody, that there won't be any java source set associated with + * this compilation + */ + target.project.launchInStage(AfterFinaliseDsl) { + if (!future.isCompleted) { + future.complete(null) + } + } + } internal fun maybeCreateJavaSourceSet(): SourceSet { check(target.withJavaEnabled) - return target.project.javaSourceSets.maybeCreate(compilationName) + val sourceSet = target.project.javaSourceSets.maybeCreate(compilationName) + javaSourceSetImpl.complete(sourceSet) + return sourceSet } override val processResourcesTaskName: String