diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/AbstractKotlinAndroidGradleTests.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/AbstractKotlinAndroidGradleTests.kt index 66164ecbc96..0fc081d0c38 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/AbstractKotlinAndroidGradleTests.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/AbstractKotlinAndroidGradleTests.kt @@ -1027,12 +1027,12 @@ abstract class AbstractKotlinAndroidGradleTests : BaseGradleIT() { project.projectDir.resolve("app/build.gradle").appendText( """ - | - |androidExtensions { - | experimental = true | - } - """.trimMargin() + |androidExtensions { + | experimental = true + |} + | + """.trimMargin() ) project.build("assembleDebug") { 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 1b7784784d7..a8f5d972260 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 @@ -9,7 +9,6 @@ package org.jetbrains.kotlin.gradle.plugin import com.android.build.api.attributes.BuildTypeAttr import com.android.build.gradle.* import com.android.build.gradle.api.* -import com.android.build.gradle.tasks.MergeResources import org.gradle.api.InvalidUserCodeException import org.gradle.api.NamedDomainObjectCollection import org.gradle.api.Project @@ -18,7 +17,6 @@ import org.gradle.api.artifacts.component.ProjectComponentIdentifier import org.gradle.api.attributes.Attribute import org.gradle.api.attributes.Category import org.gradle.api.file.ConfigurableFileTree -import org.gradle.api.file.FileCollection import org.gradle.api.file.SourceDirectorySet import org.gradle.api.logging.Logging import org.gradle.api.plugins.InvalidPluginException @@ -375,43 +373,6 @@ internal fun forEachVariant(project: Project, action: (BaseVariant) -> Unit) { } } -internal fun BaseVariant.getResDirectories(): FileCollection { - val getAllResourcesMethod = - this::class.java.methods.firstOrNull { it.name == "getAllRawAndroidResources" } - if (getAllResourcesMethod != null) { - val allResources = getAllResourcesMethod.invoke(this) as FileCollection - return allResources - } - - val project = mergeResources.project - return project.files(Callable { mergeResources?.computeResourceSetList0() ?: emptyList() }) -} - -//TODO A public API is expected for this purpose. Once it is available, use the public API -private fun MergeResources.computeResourceSetList0(): List? { - val computeResourceSetListMethod = MergeResources::class.java.declaredMethods - .firstOrNull { it.name == "computeResourceSetList" && it.parameterCount == 0 } ?: return null - - val oldIsAccessible = computeResourceSetListMethod.isAccessible - try { - computeResourceSetListMethod.isAccessible = true - - val resourceSets = computeResourceSetListMethod.invoke(this) as? Iterable<*> - - return resourceSets - ?.mapNotNull { resourceSet -> - val getSourceFiles = resourceSet?.javaClass?.methods?.find { it.name == "getSourceFiles" && it.parameterCount == 0 } - val files = getSourceFiles?.invoke(resourceSet) - @Suppress("UNCHECKED_CAST") - files as? Iterable - } - ?.flatten() - - } finally { - computeResourceSetListMethod.isAccessible = oldIsAccessible - } -} - /** Filter for the AGP test variant classpath artifacts. */ class AndroidTestedVariantArtifactsFilter( private val artifactCollection: ArtifactCollection, diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/android/internal/AndroidSubplugin.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/android/internal/AndroidSubplugin.kt index 109987d92e2..32e747c281b 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/android/internal/AndroidSubplugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/android/internal/AndroidSubplugin.kt @@ -13,12 +13,10 @@ import com.android.build.gradle.api.TestVariant import com.android.build.gradle.internal.variant.TestVariantData import org.gradle.api.Plugin import org.gradle.api.Project -import org.gradle.api.file.FileCollection +import org.gradle.api.file.ConfigurableFileTree import org.gradle.api.provider.Provider -import org.gradle.api.tasks.PathSensitivity import org.gradle.api.tasks.TaskProvider import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry -import org.gradle.util.GradleVersion import org.jetbrains.kotlin.gradle.model.builder.KotlinAndroidExtensionModelBuilder import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmAndroidCompilation @@ -130,31 +128,30 @@ class AndroidSubplugin : KotlinCompilerPluginSupportPlugin { ) ) kotlinCompilation.compileKotlinTaskProvider.configure { - it.androidLayoutResourceFiles.from(getLayoutDirectories(project, sourceSet.res.srcDirs)) + it.androidLayoutResourceFiles.from( + sourceSet.res.sourceDirectoryTrees.layoutDirectories + ) } } addVariant(mainSourceSet) - val flavorSourceSets = androidExtension.productFlavors - .mapNotNull { androidExtension.sourceSets.findByName(it.name) } - - for (sourceSet in flavorSourceSets) { - addVariant(sourceSet) + androidExtension.productFlavors.configureEach { flavor -> + androidExtension.sourceSets.findByName(flavor.name)?.let { + addVariant(it) + } } return project.provider { wrapPluginOptions(pluginOptions, "configuration") } } - private fun getLayoutDirectories(project: Project, resDirectories: Iterable): FileCollection { - fun isLayoutDirectory(file: File) = file.name == "layout" || file.name.startsWith("layout-") - - return project.files(Callable { - resDirectories.flatMap { resDir -> - (resDir.listFiles(::isLayoutDirectory)).orEmpty().asList() + private val List.layoutDirectories + get() = map { tree -> + tree.matching { + it.include("**/layout/**") + it.include("**/layout-*/**") } - }) - } + } private fun applyExperimental( kotlinCompile: TaskProvider, @@ -178,55 +175,39 @@ class AndroidSubplugin : KotlinCompilerPluginSupportPlugin { val mainSourceSet = androidExtension.sourceSets.getByName("main") pluginOptions += SubpluginOption("package", getApplicationPackage(androidExtension, project, mainSourceSet)) - fun addVariant(name: String, resDirectories: FileCollection) { + fun addVariant(name: String, resDirectories: List) { val optionValue = lazy { buildString { append(name) append(';') - resDirectories.joinTo(this, separator = ";") { it.canonicalPath } + resDirectories.map { it.dir }.joinTo(this, separator = ";") { it.canonicalPath } } } pluginOptions += CompositeSubpluginOption( "variant", optionValue, listOf( SubpluginOption("variantName", name), // use INTERNAL option kind since the resources are tracked as sources (see below) - FilesSubpluginOption("resDirs", resDirectories) + FilesSubpluginOption( + "resDirs", + resDirectories.map { it.dir } + ) ) ) kotlinCompile.configure { - it.inputs.files(getLayoutDirectories(project, resDirectories)) - .withPathSensitivity(PathSensitivity.RELATIVE) - .withPropertyName("androidExtensionLayoutsFrom$name") - .skipWhenEmpty(true) - .run { - if (GradleVersion.current() >= GradleVersion.version("6.8")) { - ignoreEmptyDirectories() - } else { - this!! - } - } + it.androidLayoutResourceFiles.from(resDirectories.layoutDirectories) } } fun addSourceSetAsVariant(name: String) { val sourceSet = androidExtension.sourceSets.findByName(name) ?: return - val srcDirs = sourceSet.res.srcDirs.toList() + val srcDirs = sourceSet.res.sourceDirectoryTrees if (srcDirs.isNotEmpty()) { - addVariant(sourceSet.name, project.files(srcDirs)) + addVariant(sourceSet.name, srcDirs) } } - val resDirectoriesForAllVariants = mutableListOf() - - forEachVariant(project) { variant -> - if (getTestedVariantData(variant) != null) return@forEachVariant - resDirectoriesForAllVariants += variant.getResDirectories() - } - - val commonResDirectories = getCommonResDirectories(project, resDirectoriesForAllVariants) - - addVariant("main", commonResDirectories) + addSourceSetAsVariant("main") getVariantComponentNames(variantData)?.let { (variantName, flavorName, buildTypeName) -> addSourceSetAsVariant(buildTypeName) @@ -252,19 +233,6 @@ class AndroidSubplugin : KotlinCompilerPluginSupportPlugin { private data class VariantComponentNames(val variantName: String, val flavorName: String, val buildTypeName: String) - private fun getCommonResDirectories(project: Project, resDirectories: List): FileCollection { - val lazyFiles = lazy { - if (resDirectories.isEmpty()) { - emptySet() - } else { - resDirectories.first().toMutableSet().apply { - resDirectories.drop(1).forEach { retainAll(it) } - } - } - } - return project.files(Callable { lazyFiles.value }) - } - private fun getApplicationPackage(androidExtension: BaseExtension, project: Project, mainSourceSet: AndroidSourceSet): String { val manifestFile = mainSourceSet.manifest.srcFile val applicationPackage = getApplicationPackage(androidExtension, manifestFile)