From 020bb72d2bc7d153f194bd02669fbb047c5dcc42 Mon Sep 17 00:00:00 2001 From: Anton Lakotka Date: Wed, 14 Feb 2024 11:27:43 +0100 Subject: [PATCH] [Gradle] Associate Android java sources with related Kotlin Source Set Java sources can be produced by the task or can be configured with task dependencies. Previously sources were included into task directly now they are properly configured with Kotlin Android Source Set. ^KT-63753 Verification Pending ^KT-65426 Verification Pending --- .../gradle/android/KotlinAndroidMppIT.kt | 5 ---- .../android/KotlinAndroidSourceSetLayout.kt | 4 ++- .../KotlinAndroidJavaSourceDirConfigurator.kt | 27 +++++++++++++++++++ ...tiplatformLayoutV1SourceDirConfigurator.kt | 2 -- ...tiplatformLayoutV2SourceDirConfigurator.kt | 1 - .../SingleTargetSourceDirConfigurator.kt | 1 - .../targets/android/AndroidProjectHandler.kt | 12 ++++----- .../kotlin/gradle/utils/fileUtils.kt | 14 +++++++--- 8 files changed, 45 insertions(+), 21 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/configurator/KotlinAndroidJavaSourceDirConfigurator.kt diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/android/KotlinAndroidMppIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/android/KotlinAndroidMppIT.kt index 423a8776d7e..122a09be449 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/android/KotlinAndroidMppIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/android/KotlinAndroidMppIT.kt @@ -973,11 +973,6 @@ class KotlinAndroidMppIT : KGPBaseTest() { defaultBuildOptions.copy(androidVersion = agpVersion), buildJdk = jdkVersion.location ) { - // Hacks for TODO: KT-65426 - val appPath = subProject("app").projectPath - appPath.resolve("src/main/java/app/example/com/app_sample").deleteRecursively() - appPath.resolve("src/commonMain/kotlin/A.kt").replaceText("expect fun f(): Unit", "") - // Code copied from the reproducer from KT-63753 subProject("app").buildGradleKts.appendText( """ diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/KotlinAndroidSourceSetLayout.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/KotlinAndroidSourceSetLayout.kt index fcda8d9bcfe..a7f63b8a1a1 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/KotlinAndroidSourceSetLayout.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/KotlinAndroidSourceSetLayout.kt @@ -28,7 +28,7 @@ internal val singleTargetAndroidSourceSetLayout = KotlinAndroidSourceSetLayout( GradleConventionAddKotlinSourcesToAndroidSourceSetConfigurator, Agp7AddKotlinSourcesToAndroidSourceSetConfigurator .onlyIf { AndroidGradlePluginVersion.current >= "7.0.0" }, - + KotlinAndroidJavaSourceDirConfigurator, SingleTargetSourceDirConfigurator, ), checker = KotlinAndroidSourceSetLayoutChecker() @@ -43,6 +43,7 @@ internal val multiplatformAndroidSourceSetLayoutV1 = KotlinAndroidSourceSetLayou GradleConventionAddKotlinSourcesToAndroidSourceSetConfigurator, Agp7AddKotlinSourcesToAndroidSourceSetConfigurator .onlyIf { AndroidGradlePluginVersion.current >= "7.0.0" }, + KotlinAndroidJavaSourceDirConfigurator, MultiplatformAndroidResourceDirConfigurator, MultiplatformLayoutV1DependsOnConfigurator, MultiplatformLayoutV1SourceDirConfigurator @@ -62,6 +63,7 @@ internal val multiplatformAndroidSourceSetLayoutV2 = KotlinAndroidSourceSetLayou MultiplatformLayoutV2DependsOnConfigurator, Agp7AddKotlinSourcesToAndroidSourceSetConfigurator .onlyIf { AndroidGradlePluginVersion.current >= "7.0.0" }, + KotlinAndroidJavaSourceDirConfigurator, MultiplatformLayoutV2SourceDirConfigurator, MultiplatformLayoutV2DefaultManifestLocationConfigurator ), diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/configurator/KotlinAndroidJavaSourceDirConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/configurator/KotlinAndroidJavaSourceDirConfigurator.kt new file mode 100644 index 00000000000..c9812d8377e --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/configurator/KotlinAndroidJavaSourceDirConfigurator.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +@file:Suppress("TYPEALIAS_EXPANSION_DEPRECATION") + +package org.jetbrains.kotlin.gradle.plugin.sources.android.configurator + +import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget +import org.jetbrains.kotlin.gradle.utils.DeprecatedAndroidSourceSet +import org.jetbrains.kotlin.gradle.utils.fileCollectionFromConfigurableFileTree +import org.jetbrains.kotlin.gradle.utils.filesProvider + +internal object KotlinAndroidJavaSourceDirConfigurator : KotlinAndroidSourceSetConfigurator { + override fun configure(target: KotlinAndroidTarget, kotlinSourceSet: KotlinSourceSet, androidSourceSet: DeprecatedAndroidSourceSet) { + val project = target.project + + kotlinSourceSet.kotlin.srcDir(project.provider { + // getSourceDirectoryTrees() is not lazy, thus it should be wrapped with provider + androidSourceSet.java.getSourceDirectoryTrees().map { sources -> + project.fileCollectionFromConfigurableFileTree(sources) + } + }) + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/configurator/MultiplatformLayoutV1SourceDirConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/configurator/MultiplatformLayoutV1SourceDirConfigurator.kt index 1035bfc0a98..0bd1096ef87 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/configurator/MultiplatformLayoutV1SourceDirConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/configurator/MultiplatformLayoutV1SourceDirConfigurator.kt @@ -27,7 +27,5 @@ internal object MultiplatformLayoutV1SourceDirConfigurator : KotlinAndroidSource if (!androidSourceSet.name.startsWith(target.disambiguationClassifier)) { kotlinSourceSet.kotlin.srcDir("src/${androidSourceSet.name}/kotlin") } - - kotlinSourceSet.kotlin.srcDir(target.project.provider { androidSourceSet.java.srcDirs }) } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/configurator/MultiplatformLayoutV2SourceDirConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/configurator/MultiplatformLayoutV2SourceDirConfigurator.kt index c3caa42c666..e815112194b 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/configurator/MultiplatformLayoutV2SourceDirConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/configurator/MultiplatformLayoutV2SourceDirConfigurator.kt @@ -15,7 +15,6 @@ internal object MultiplatformLayoutV2SourceDirConfigurator : KotlinAndroidSource kotlinSourceSet: KotlinSourceSet, @Suppress("TYPEALIAS_EXPANSION_DEPRECATION") androidSourceSet: DeprecatedAndroidSourceSet ) { - kotlinSourceSet.kotlin.srcDir(target.project.provider { androidSourceSet.java.srcDirs }) kotlinSourceSet.kotlin.srcDir("src/${androidSourceSet.name}/kotlin") } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/configurator/SingleTargetSourceDirConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/configurator/SingleTargetSourceDirConfigurator.kt index 9185e7db24d..30b5dfc7198 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/configurator/SingleTargetSourceDirConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/android/configurator/SingleTargetSourceDirConfigurator.kt @@ -16,6 +16,5 @@ internal object SingleTargetSourceDirConfigurator : KotlinAndroidSourceSetConfig @Suppress("TYPEALIAS_EXPANSION_DEPRECATION") androidSourceSet: DeprecatedAndroidSourceSet ) { kotlinSourceSet.kotlin.srcDir("src/${androidSourceSet.name}/kotlin") - kotlinSourceSet.kotlin.srcDir(target.project.provider { androidSourceSet.java.srcDirs }) } } 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 2e72781f3b8..7dcaa16d61b 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 @@ -230,13 +230,11 @@ internal class AndroidProjectHandler( val javaTask = variantData.javaCompileProvider @Suppress("UNCHECKED_CAST") val kotlinTask = compilation.compileTaskProvider as TaskProvider - compilation.androidVariant.forEachJavaSourceDir { sources -> - // It is important to pass exactly `sources.dir` as provider with explicit task dependency - // Because of the following bugs: - // * https://github.com/gradle/gradle/issues/27881 ConfigurableFileTree.from() doesn't preserve Task Dependencies - // * https://github.com/gradle/gradle/issues/27882 SourceDirectorySet doesn't accept ConfigurableFileTree - val sourceDirWithTaskDependencies = project.filesProvider(sources) { sources.dir } - compilation.defaultSourceSet.kotlin.srcDir(sourceDirWithTaskDependencies) + kotlinTask.configure { task -> + variantData.forEachJavaSourceDir { sources -> + task.source(sources.dir) + task.dependsOn(sources) + } } wireKotlinTasks(project, compilation, androidPlugin, androidExt, variantData, javaTask, kotlinTask) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/fileUtils.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/fileUtils.kt index 8350523a1f6..9e18837d0a2 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/fileUtils.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/utils/fileUtils.kt @@ -6,9 +6,7 @@ package org.jetbrains.kotlin.gradle.utils import org.gradle.api.Project -import org.gradle.api.file.Directory -import org.gradle.api.file.FileCollection -import org.gradle.api.file.RegularFile +import org.gradle.api.file.* import org.gradle.api.provider.Provider import org.jetbrains.kotlin.gradle.plugin.internal.CustomPropertiesFileValueSource import org.jetbrains.kotlin.gradle.plugin.internal.configurationTimePropertiesAccessor @@ -149,4 +147,12 @@ internal val Project.localProperties: Provider> /** * Returns file collection [this] excluding files from [excludes] if not null */ -internal fun FileCollection.exclude(excludes: FileCollection?): FileCollection = if (excludes != null) minus(excludes) else this \ No newline at end of file +internal fun FileCollection.exclude(excludes: FileCollection?): FileCollection = if (excludes != null) minus(excludes) else this + +internal fun Project.fileCollectionFromConfigurableFileTree(fileTree: ConfigurableFileTree): ConfigurableFileCollection { + // It is important to pass exactly `fileTree.dir` as provider with explicit task dependency + // Because of the following bugs: + // * https://github.com/gradle/gradle/issues/27881 ConfigurableFileTree.from() doesn't preserve Task Dependencies + // * https://github.com/gradle/gradle/issues/27882 SourceDirectorySet doesn't accept ConfigurableFileTree + return project.filesProvider(fileTree) { fileTree.dir } +} \ No newline at end of file