diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kapt3IT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kapt3IT.kt index a074cd8a1f0..f32614005bb 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kapt3IT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kapt3IT.kt @@ -1038,7 +1038,7 @@ open class Kapt3IT : Kapt3BaseIT() { } } - @DisplayName("KT-52761: generated sources attached to compile task are also used by generate stubs task") + @DisplayName("Generated sources attached to KotlinSourceSet are also used by generate stubs task") @GradleTest fun testGeneratedSourcesUsedInGenerateStubsTask(gradleVersion: GradleVersion) { project("generatedSources".withPrefix, gradleVersion) { diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/UpToDateIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/UpToDateIT.kt index 69df1732280..d643402f0ec 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/UpToDateIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/UpToDateIT.kt @@ -192,8 +192,8 @@ class UpToDateIT : KGPBaseTest() { } override fun checkAfterRebuild(buildResult: BuildResult) = with(buildResult) { - assertTasksExecuted(":compileKotlin", ":kaptGenerateStubsKotlin") - assertTasksUpToDate(":kaptKotlin") + assertTasksExecuted(":compileKotlin") + assertTasksUpToDate(":kaptGenerateStubsKotlin", ":kaptKotlin") } } diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/android/Kapt3AndroidIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/android/Kapt3AndroidIT.kt index 71aae9bd80e..9389bcf8f2b 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/android/Kapt3AndroidIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/android/Kapt3AndroidIT.kt @@ -11,7 +11,6 @@ import org.jetbrains.kotlin.gradle.testbase.* import org.jetbrains.kotlin.gradle.util.* import org.junit.jupiter.api.DisplayName import kotlin.io.path.appendText -import kotlin.io.path.readText import kotlin.io.path.writeText @DisplayName("android with kapt3 tests") diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/generatedSources/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/generatedSources/build.gradle index 46c87cb98b9..961a26cd926 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/generatedSources/build.gradle +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/generatedSources/build.gradle @@ -8,8 +8,10 @@ repositories { mavenCentral() } -tasks.named("compileKotlin", org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile.class) { - source("src/proto/generated") +sourceSets { + main { + kotlin.srcDir("src/proto/generated") + } } tasks.withType(JavaCompile.class).configureEach { diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/Kapt3KotlinGradleSubplugin.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/Kapt3KotlinGradleSubplugin.kt index 10f2e5373d0..61db08ab165 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/Kapt3KotlinGradleSubplugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/Kapt3KotlinGradleSubplugin.kt @@ -240,9 +240,10 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To kaptExtension.includeCompileClasspath ?: project.isIncludeCompileClasspath() + @Suppress("UNCHECKED_CAST") val kotlinCompile: TaskProvider // Can't use just kotlinCompilation.compileKotlinTaskProvider, as the latter is not statically-known to be KotlinCompile - get() = checkNotNull(project.locateTask(kotlinCompilation.compileKotlinTaskName)) + get() = kotlinCompilation.compileTaskProvider as TaskProvider } override fun applyToCompilation( @@ -355,7 +356,7 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To private fun Kapt3SubpluginContext.createKaptKotlinTask( generateStubsTask: TaskProvider ): TaskProvider { - val taskName = getKaptTaskName("kapt") + val taskName = kotlinCompile.kaptTaskName @Suppress("UNCHECKED_CAST") val taskConfigAction = KaptWithoutKotlincConfig( kotlinCompilation.project, @@ -432,10 +433,10 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To } private fun Kapt3SubpluginContext.createKaptGenerateStubsTask(): TaskProvider { - val kaptTaskName = getKaptTaskName("kaptGenerateStubs") + val kaptTaskName = kotlinCompile.kaptGenerateStubsTaskName val kaptTaskProvider = project.registerTask(kaptTaskName) - val taskConfig = KaptGenerateStubsConfig(kotlinCompilation, kotlinCompile, classesOutputDir) + val taskConfig = KaptGenerateStubsConfig(kotlinCompilation) taskConfig.configureTask { it.stubsDir.set(getKaptStubsDir()) it.destinationDirectory.set(getKaptIncrementalDataDir()) @@ -451,13 +452,6 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To return kaptTaskProvider } - private fun Kapt3SubpluginContext.getKaptTaskName(prefix: String): String { - // Replace compile*Kotlin to kapt*Kotlin - val baseName = kotlinCompile.name - assert(baseName.startsWith("compile")) - return baseName.replaceFirst("compile", prefix) - } - private fun Kapt3SubpluginContext.disableAnnotationProcessingInJavaTask() { javaCompile?.configure { javaCompileInstance -> if (javaCompileInstance !is JavaCompile) @@ -491,6 +485,24 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To JetBrainsSubpluginArtifact(artifactId = KAPT_ARTIFACT_NAME) } +internal const val KAPT_GENERATE_STUBS_PREFIX = "kaptGenerateStubs" +internal const val KAPT_PREFIX = "kapt" + +internal val TaskProvider.kaptGenerateStubsTaskName + get() = getKaptTaskName(name, KAPT_GENERATE_STUBS_PREFIX) + +internal val TaskProvider.kaptTaskName + get() = getKaptTaskName(name, KAPT_PREFIX) + +internal fun getKaptTaskName( + kotlinCompileName: String, + prefix: String +): String { + // Replace compile*Kotlin to kapt*Kotlin + assert(kotlinCompileName.startsWith("compile")) + return kotlinCompileName.replaceFirst("compile", prefix) +} + internal fun buildKaptSubpluginOptions( kaptExtension: KaptExtension, project: Project, diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptGenerateStubsTask.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptGenerateStubsTask.kt index 03dea277f86..a18bf57a8d6 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptGenerateStubsTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptGenerateStubsTask.kt @@ -25,7 +25,6 @@ import org.gradle.work.Incremental import org.gradle.work.NormalizeLineEndings import org.gradle.workers.WorkerExecutor import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments -import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompilerOptions import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompilerOptionsDefault import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompilerOptionsHelper import org.jetbrains.kotlin.gradle.plugin.KotlinCompilerArgumentsProducer.CreateCompilerArgumentsContext @@ -88,6 +87,9 @@ abstract class KaptGenerateStubsTask @Inject constructor( @get:Internal override val androidLayoutResources: FileCollection = objectFactory.fileCollection() + @get:Internal + abstract val kotlinCompileDestinationDirectory: DirectoryProperty + override val incrementalProps: List get() = listOf( sources, @@ -97,18 +99,10 @@ abstract class KaptGenerateStubsTask @Inject constructor( classpathSnapshotProperties.classpathSnapshot ) - @get:Internal - internal abstract val compileTaskCompilerOptions: Property - override fun createCompilerArguments(context: CreateCompilerArgumentsContext) = context.create { primitive { args -> args.allowNoSourceFiles = true - KotlinJvmCompilerOptionsHelper.fillCompilerArguments(compileTaskCompilerOptions.get(), args) - // Workaround for freeCompiler args duplication when they were configured for both this task - // and linked KotlinCompile task with the same values. For now linked KotlinCompile task - // freeCompilerArgs is used as convention for this task freeCompilerArgs - args.freeArgs = emptyList() KotlinJvmCompilerOptionsHelper.fillCompilerArguments(compilerOptions, args) overrideArgsUsingTaskModuleNameWithWarning(args) 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 311fc6719a1..38af7d69ba3 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 @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin import org.jetbrains.kotlin.gradle.scripting.internal.ScriptingGradleSubplugin import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider +import org.jetbrains.kotlin.gradle.tasks.configuration.KaptGenerateStubsConfig import org.jetbrains.kotlin.gradle.tasks.configuration.KotlinCompileConfig import org.jetbrains.kotlin.gradle.tasks.withType import org.jetbrains.kotlin.gradle.utils.whenKaptEnabled @@ -34,7 +35,14 @@ internal class Kotlin2JvmSourceSetProcessor( taskName, compilationInfo.compilerOptions.options as KotlinJvmCompilerOptions, configAction - ) + ).also { kotlinTask -> + // Configuring here to not interfere with 'kotlin-android' plugin configuration for 'libraries' input + KaptGenerateStubsConfig.configureLibraries( + project, + kotlinTask, + { compilationInfo.compileDependencyFiles } + ) + } } override fun doTargetSpecificProcessing() { @@ -59,6 +67,12 @@ internal class Kotlin2JvmSourceSetProcessor( kotlinTask.configure { kotlinCompile -> kotlinCompile.javaOutputDir.set(javaTask.flatMap { it.destinationDirectory }) } + + KaptGenerateStubsConfig.wireJavaAndKotlinOutputs( + project, + javaTask, + kotlinTask + ) } if (sourceSetName == SourceSet.MAIN_SOURCE_SET_NAME) { diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilations.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilations.kt index 5d826c3c0da..55be88cfad5 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilations.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilations.kt @@ -9,6 +9,8 @@ import org.gradle.api.Project import org.gradle.api.provider.Provider import org.jetbrains.kotlin.gradle.dsl.KotlinCommonCompilerOptions import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions +import org.jetbrains.kotlin.gradle.internal.KAPT_GENERATE_STUBS_PREFIX +import org.jetbrains.kotlin.gradle.internal.getKaptTaskName import org.jetbrains.kotlin.gradle.plugin.HasCompilerOptions import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.archivesName @@ -52,16 +54,20 @@ internal fun addSourcesToKotlinCompileTask( // The `commonSourceSet` is passed to the compiler as-is, converted with toList commonSourceSet.from( - Callable { if (addAsCommonSources.value) sources else emptyList() } + { if (addAsCommonSources.value) sources else emptyList() } ) } project.tasks - // To configure a task that may have not yet been created at this point, use 'withType-matching-configureEach`: .withType(AbstractKotlinCompile::class.java) - .matching { it.name == taskName } .configureEach { compileKotlinTask -> - compileKotlinTask.configureAction() + val compileTaskName = compileKotlinTask.name + // We also should configure related Kapt* tasks as they are not pickup configuration from + // related KotlinJvmCompile to avoid circular task dependencies + val kaptGenerateStubsTaskName = getKaptTaskName(compileTaskName, KAPT_GENERATE_STUBS_PREFIX) + if (compileTaskName == taskName || kaptGenerateStubsTaskName == taskName) { + compileKotlinTask.configureAction() + } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/android/AndroidProjectHandler.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/android/AndroidProjectHandler.kt index 7ccb442e17c..55eaef46c89 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/android/AndroidProjectHandler.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/android/AndroidProjectHandler.kt @@ -26,7 +26,7 @@ import org.gradle.api.tasks.bundling.AbstractArchiveTask import org.gradle.api.tasks.compile.AbstractCompile import org.gradle.api.tasks.compile.JavaCompile import org.jetbrains.kotlin.gradle.dsl.* -import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin +import org.jetbrains.kotlin.gradle.internal.* import org.jetbrains.kotlin.gradle.internal.checkAndroidAnnotationProcessorDependencyUsage import org.jetbrains.kotlin.gradle.logging.kotlinDebug import org.jetbrains.kotlin.gradle.plugin.android.AndroidGradleWrapper @@ -37,6 +37,7 @@ import org.jetbrains.kotlin.gradle.plugin.sources.android.KotlinAndroidSourceSet import org.jetbrains.kotlin.gradle.plugin.sources.android.findKotlinSourceSet import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider +import org.jetbrains.kotlin.gradle.tasks.configuration.KaptGenerateStubsConfig import org.jetbrains.kotlin.gradle.tasks.configuration.KotlinCompileConfig import org.jetbrains.kotlin.gradle.tasks.thisTaskProvider import org.jetbrains.kotlin.gradle.testing.internal.kotlinTestRegistry @@ -46,7 +47,6 @@ import java.io.File import java.io.ObjectInputStream import java.io.ObjectOutputStream import java.io.Serializable -import java.util.concurrent.Callable internal class AndroidProjectHandler( private val kotlinTasksProvider: KotlinTasksProvider @@ -186,13 +186,22 @@ internal class AndroidProjectHandler( task.destinationDirectory.set(project.layout.buildDirectory.dir("tmp/kotlin-classes/$variantDataName")) task.description = "Compiles the $variantDataName kotlin." } - tasksProvider.registerKotlinJVMTask( + val kotlinTask = tasksProvider.registerKotlinJVMTask( project, compilation.compileKotlinTaskName, compilation.compilerOptions.options as KotlinJvmCompilerOptions, configAction ) + // Need to move it into afterEvaluate, so it will be executed after KaptGenerateStubsConfig config actions + // Otherwise build will fail within AbstractKotlinCompileConfig trying to modify value with 'disallowChanges()' state + project.afterEvaluate { + KaptGenerateStubsConfig.configureUseModuleDetection( + project, + kotlinTask + ) { value(true).disallowChanges() } + } + // Register the source only after the task is created, because the task is required for that: compilation.source(defaultSourceSet) @@ -250,11 +259,23 @@ internal class AndroidProjectHandler( kotlinTask.configure { kotlinTaskInstance -> kotlinTaskInstance.libraries .from(variantData.getCompileClasspath(preJavaClasspathKey)) - .from(Callable { AndroidGradleWrapper.getRuntimeJars(androidPlugin, androidExt) }) + .from({ AndroidGradleWrapper.getRuntimeJars(androidPlugin, androidExt) }) kotlinTaskInstance.javaOutputDir.set(javaTask.flatMap { it.destinationDirectory }) } + KaptGenerateStubsConfig.configureLibraries( + project, + kotlinTask, + variantData.getCompileClasspath(preJavaClasspathKey), + { AndroidGradleWrapper.getRuntimeJars(androidPlugin, androidExt) } + ) + KaptGenerateStubsConfig.wireJavaAndKotlinOutputs( + project, + javaTask, + kotlinTask + ) + // Find the classpath entries that come from the tested variant and register them as the friend paths, lazily val originalArtifactCollection = variantData.getCompileClasspathArtifacts(preJavaClasspathKey) val testedVariantDataIsNotNull = getTestedVariantData(variantData) != null @@ -306,7 +327,7 @@ internal class AndroidProjectHandler( project.addExtendsFromRelation(name, compilation.runtimeDependencyConfigurationName) } - val buildTypeAttrValue = project.objects.named(BuildTypeAttr::class.java, variant.buildType.name) + val buildTypeAttrValue = project.objects.named(variant.buildType.name) listOf(compilation.compileDependencyConfigurationName, compilation.runtimeDependencyConfigurationName).forEach { project.configurations.findByName(it)?.attributes?.attribute(Attribute.of(BuildTypeAttr::class.java), buildTypeAttrValue) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KaptGenerateStubsConfig.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KaptGenerateStubsConfig.kt index d151a9657cd..e525891fe89 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KaptGenerateStubsConfig.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KaptGenerateStubsConfig.kt @@ -6,11 +6,12 @@ package org.jetbrains.kotlin.gradle.tasks.configuration import org.gradle.api.Project -import org.gradle.api.file.DirectoryProperty -import org.gradle.api.file.FileCollection +import org.gradle.api.provider.Property import org.gradle.api.provider.Provider -import org.gradle.api.specs.Spec 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.dsl.KotlinJvmCompilerOptionsHelper import org.jetbrains.kotlin.gradle.dsl.KotlinTopLevelExtension import org.jetbrains.kotlin.gradle.internal.* import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.KAPT_SUBPLUGIN_ID @@ -19,66 +20,29 @@ import org.jetbrains.kotlin.gradle.plugin.KaptExtension import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationInfo import org.jetbrains.kotlin.gradle.tasks.CompilerPluginOptions -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile -import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompilerArgumentsProvider -import org.jetbrains.kotlin.gradle.utils.isConfigurationCacheAvailable -import org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast -import org.jetbrains.kotlin.gradle.utils.isParentOf -import java.io.File -import java.nio.file.Files -import java.util.concurrent.ConcurrentHashMap +import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile +import org.jetbrains.kotlin.gradle.tasks.withType +import org.jetbrains.kotlin.gradle.utils.whenKaptEnabled internal class KaptGenerateStubsConfig : BaseKotlinCompileConfig { constructor( - compilation: KotlinCompilation<*>, - kotlinTaskProvider: TaskProvider, - kaptClassesDir: File + compilation: KotlinCompilation<*> ) : super(KotlinCompilationInfo(compilation)) { configureFromExtension(project.extensions.getByType(KaptExtension::class.java)) - configureTask { task -> - val kotlinCompileTask = kotlinTaskProvider.get() - task.useModuleDetection.value(kotlinCompileTask.useModuleDetection).disallowChanges() - @Suppress("DEPRECATION") - task.moduleName.value(kotlinCompileTask.moduleName).disallowChanges() - task.libraries.from({ kotlinCompileTask.libraries - project.files(kaptClassesDir) }) - task.compileTaskCompilerOptions.set(providers.provider { kotlinCompileTask.compilerOptions }) - task.pluginOptions.addAll(kotlinCompileTask.pluginOptions) - task.compilerOptions.moduleName.convention(kotlinCompileTask.compilerOptions.moduleName) - task.compilerOptions.freeCompilerArgs.convention(kotlinCompileTask.compilerOptions.freeCompilerArgs) - // KotlinCompile will also have as input output from KaptGenerateStubTask and KaptTask - // We are filtering them to avoid failed UP-TO-DATE checks - val kaptJavaSourcesDir = Kapt3GradleSubplugin.getKaptGeneratedSourcesDir( - project, - compilation.compilationName - ) - val kaptKotlinSourcesDir = Kapt3GradleSubplugin.getKaptGeneratedKotlinSourcesDir( - project, - compilation.compilationName - ) - val destinationDirectory = task.destinationDirectory - val stubsDir = task.stubsDir - val kaptFilterSpec = KaptFilterSpec(destinationDirectory, stubsDir, kaptJavaSourcesDir, kaptKotlinSourcesDir) - // FileTree filtering approach fails with configuration cache until Gradle 7.5 leading to failed UP-TO-DATE checks - val kaptFilter = if (shouldUseFileTreeKaptFilter) { - FileTreeKaptInputsFilter(kaptFilterSpec) - } else { - FileCollectionKaptInputsFilter(kaptFilterSpec) - } - task.source( - kaptFilter.filtered(kotlinCompileTask.javaSources), - kaptFilter.filtered(kotlinCompileTask.sources), + + configureTask { kaptGenerateStubsTask -> + // Syncing compiler options from related KotlinJvmCompile task + val jvmCompilerOptions = compilation.compilerOptions.options as KotlinJvmCompilerOptions + KotlinJvmCompilerOptionsHelper.syncOptionsAsConvention( + from = jvmCompilerOptions, + into = kaptGenerateStubsTask.compilerOptions ) } } constructor(project: Project, ext: KotlinTopLevelExtension, kaptExtension: KaptExtension) : super(project, ext) { configureFromExtension(kaptExtension) - configureTask { task -> - task.compileTaskCompilerOptions.set( - providers.provider { task.compilerOptions } - ) - } } private fun configureFromExtension(kaptExtension: KaptExtension) { @@ -118,53 +82,51 @@ internal class KaptGenerateStubsConfig : BaseKotlinCompileConfig() - abstract fun filtered(fileCollection: FileCollection): FileCollection - - protected fun isSatisfiedBy(file: File) = filterCache[file] ?: predicate(file).also { filterCache[file] = it } - - abstract fun predicate(file: File): Boolean - } - - // Drop `isEmptyDirectory` check after min supported Gradle version will be bumped to 6.8 - // It will be covered by '@IgnoreEmptyDirectories' input annotation - private class FileCollectionKaptInputsFilter(val spec: KaptFilterSpec) : CachingKaptInputsFilter() { - override fun filtered(fileCollection: FileCollection): FileCollection { - return fileCollection.filter(::isSatisfiedBy) - } - - override fun predicate(file: File) = !file.isEmptyDirectory && spec.isSatisfiedBy(file) - - private val File.isEmptyDirectory: Boolean - get() = with(toPath()) { - Files.isDirectory(this) && !Files.list(this).use { it.findFirst().isPresent } + companion object { + internal fun wireJavaAndKotlinOutputs( + project: Project, + javaCompileTask: TaskProvider, + kotlinCompileTask: TaskProvider + ) { + project.whenKaptEnabled { + val kaptGenerateStubsTaskName = getKaptTaskName(kotlinCompileTask.name, KAPT_GENERATE_STUBS_PREFIX) + project.tasks.withType().configureEach { task -> + if (task.name == kaptGenerateStubsTaskName) { + task.javaOutputDir.set(javaCompileTask.flatMap { it.destinationDirectory }) + task.kotlinCompileDestinationDirectory.set(kotlinCompileTask.flatMap { it.destinationDirectory }) + } + } } - } - - private val shouldUseFileTreeKaptFilter - get() = isGradleVersionAtLeast(7, 5) || !isConfigurationCacheAvailable(project.gradle) - - private class FileTreeKaptInputsFilter(val spec: KaptFilterSpec) : CachingKaptInputsFilter() { - override fun filtered(fileCollection: FileCollection): FileCollection { - return fileCollection.asFileTree.matching { it.include { elem -> isSatisfiedBy(elem.file) } } } - override fun predicate(file: File) = spec.isSatisfiedBy(file) - } + internal fun configureLibraries( + project: Project, + kotlinCompileTask: TaskProvider, + vararg paths: Any + ) { + project.whenKaptEnabled { + val kaptGenerateStubsTaskName = getKaptTaskName(kotlinCompileTask.name, KAPT_GENERATE_STUBS_PREFIX) + project.tasks.withType().configureEach { task -> + if (task.name == kaptGenerateStubsTaskName) { + task.libraries.from(paths) + } + } + } + } - private class KaptFilterSpec( - private val destinationDirectory: DirectoryProperty, - private val stubsDir: DirectoryProperty, - private val kaptJavaSourcesDir: File, - private val kaptKotlinSourcesDir: File, - ) : Spec { - override fun isSatisfiedBy(element: File) = element.isSourceRootAllowed() - - private fun File.isSourceRootAllowed(): Boolean = - !destinationDirectory.get().asFile.isParentOf(this) && - !stubsDir.asFile.get().isParentOf(this) && - !kaptJavaSourcesDir.isParentOf(this) && - !kaptKotlinSourcesDir.isParentOf(this) + internal fun configureUseModuleDetection( + project: Project, + kotlinCompileTask: TaskProvider, + config: Property.() -> Unit + ) { + project.whenKaptEnabled { + val kaptGenerateStubsTaskName = getKaptTaskName(kotlinCompileTask.name, KAPT_GENERATE_STUBS_PREFIX) + project.tasks.withType().configureEach { task -> + if (task.name == kaptGenerateStubsTaskName) { + config(task.useModuleDetection) + } + } + } + } } -} \ No newline at end of file +}