diff --git a/gradle-plugins/.gitignore b/gradle-plugins/.gitignore index 941925514bd..239a2f727eb 100644 --- a/gradle-plugins/.gitignore +++ b/gradle-plugins/.gitignore @@ -37,3 +37,5 @@ jacoco.exec # Layout Inspector creates it. captures/ __pycache__ + +.kotlin/ diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/ComposeResourcesGeneration.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/ComposeResourcesGeneration.kt index 9b45b9be320..c1f483cae05 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/ComposeResourcesGeneration.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/ComposeResourcesGeneration.kt @@ -44,6 +44,7 @@ internal fun Project.configureComposeResourcesGeneration( } } val packageName = config.getResourcePackage(project) + val resClassName = config.map { it.resClassName } val makeAccessorsPublic = config.map { it.publicResClass } val packagingDir = config.getModuleResourcesDir(project) @@ -53,6 +54,7 @@ internal fun Project.configureComposeResourcesGeneration( sourceSet, shouldGenerateCode, packageName, + resClassName, makeAccessorsPublic, packagingDir, generateModulePath @@ -67,13 +69,20 @@ internal fun Project.configureComposeResourcesGeneration( preparedResources, shouldGenerateCode, packageName, + resClassName, makeAccessorsPublic, packagingDir, generateModulePath ) } - configureResourceCollectorsGeneration(kotlinExtension, shouldGenerateCode, packageName, makeAccessorsPublic) + configureResourceCollectorsGeneration( + kotlinExtension, + shouldGenerateCode, + packageName, + resClassName, + makeAccessorsPublic + ) //setup task execution during IDE import tasks.configureEach { importTask -> @@ -87,9 +96,10 @@ private fun Project.configureResClassGeneration( resClassSourceSet: KotlinSourceSet, shouldGenerateCode: Provider, packageName: Provider, + resClassName: Provider, makeAccessorsPublic: Provider, packagingDir: Provider, - generateModulePath: Boolean + generateModulePath: Boolean, ) { logger.info("Configure Res class generation for ${resClassSourceSet.name}") @@ -98,6 +108,7 @@ private fun Project.configureResClassGeneration( GenerateResClassTask::class.java ) { task -> task.packageName.set(packageName) + task.resClassName.set(resClassName) task.makeAccessorsPublic.set(makeAccessorsPublic) task.codeDir.set(layout.buildDirectory.dir("$RES_GEN_DIR/kotlin/commonResClass")) @@ -120,9 +131,10 @@ private fun Project.configureResourceAccessorsGeneration( resourcesDir: Provider, shouldGenerateCode: Provider, packageName: Provider, + resClassName: Provider, makeAccessorsPublic: Provider, packagingDir: Provider, - generateModulePath: Boolean + generateModulePath: Boolean, ) { logger.info("Configure resource accessors generation for ${sourceSet.name}") @@ -131,6 +143,7 @@ private fun Project.configureResourceAccessorsGeneration( GenerateResourceAccessorsTask::class.java ) { task -> task.packageName.set(packageName) + task.resClassName.set(resClassName) task.sourceSetName.set(sourceSet.name) task.makeAccessorsPublic.set(makeAccessorsPublic) task.resDir.set(resourcesDir) @@ -159,7 +172,8 @@ private fun Project.configureResourceCollectorsGeneration( kotlinExtension: KotlinProjectExtension, shouldGenerateCode: Provider, packageName: Provider, - makeAccessorsPublic: Provider + resClassName: Provider, + makeAccessorsPublic: Provider, ) { if (kotlinExtension is KotlinMultiplatformExtension) { kotlinExtension.sourceSets @@ -169,6 +183,7 @@ private fun Project.configureResourceCollectorsGeneration( commonMainSourceSet, shouldGenerateCode, packageName, + resClassName, makeAccessorsPublic ) } @@ -180,6 +195,7 @@ private fun Project.configureResourceCollectorsGeneration( androidMain, shouldGenerateCode, packageName, + resClassName, makeAccessorsPublic, true ) @@ -190,6 +206,7 @@ private fun Project.configureResourceCollectorsGeneration( compilation.defaultSourceSet, shouldGenerateCode, packageName, + resClassName, makeAccessorsPublic, true ) @@ -205,6 +222,7 @@ private fun Project.configureResourceCollectorsGeneration( compilation.defaultSourceSet, shouldGenerateCode, packageName, + resClassName, makeAccessorsPublic, false ) @@ -217,7 +235,8 @@ private fun Project.configureExpectResourceCollectorsGeneration( sourceSet: KotlinSourceSet, shouldGenerateCode: Provider, packageName: Provider, - makeAccessorsPublic: Provider + resClassName: Provider, + makeAccessorsPublic: Provider, ) { logger.info("Configure expect resource collectors generation for ${sourceSet.name}") @@ -227,6 +246,7 @@ private fun Project.configureExpectResourceCollectorsGeneration( GenerateExpectResourceCollectorsTask::class.java ) { task -> task.packageName.set(packageName) + task.resClassName.set(resClassName) task.makeAccessorsPublic.set(makeAccessorsPublic) task.codeDir.set(layout.buildDirectory.dir("$RES_GEN_DIR/kotlin/${sourceSet.name}ResourceCollectors")) task.onlyIf { shouldGenerateCode.get() } @@ -244,8 +264,9 @@ private fun Project.configureActualResourceCollectorsGeneration( sourceSet: KotlinSourceSet, shouldGenerateCode: Provider, packageName: Provider, + resClassName: Provider, makeAccessorsPublic: Provider, - useActualModifier: Boolean + useActualModifier: Boolean, ) { val taskName = "generateActualResourceCollectorsFor${sourceSet.name.uppercaseFirstChar()}" if (tasks.names.contains(taskName)) { @@ -269,6 +290,7 @@ private fun Project.configureActualResourceCollectorsGeneration( GenerateActualResourceCollectorsTask::class.java ) { task -> task.packageName.set(packageName) + task.resClassName.set(resClassName) task.makeAccessorsPublic.set(makeAccessorsPublic) task.useActualModifier.set(useActualModifier) task.resourceAccessorDirs.from(accessorDirs) @@ -282,4 +304,4 @@ private fun Project.configureActualResourceCollectorsGeneration( if (flag) listOf(task.codeDir) else emptyList() } ) -} \ No newline at end of file +} diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/GenerateResClassTask.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/GenerateResClassTask.kt index 676715343fc..100905b2bfc 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/GenerateResClassTask.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/GenerateResClassTask.kt @@ -9,13 +9,12 @@ import org.jetbrains.compose.internal.IdeaImportTask import java.io.File internal abstract class GenerateResClassTask : IdeaImportTask() { - companion object { - private const val RES_FILE_NAME = "Res" - } - @get:Input abstract val packageName: Property + @get:Input + abstract val resClassName: Property + @get:Input @get:Optional abstract val packagingDir: Property @@ -31,11 +30,12 @@ internal abstract class GenerateResClassTask : IdeaImportTask() { dir.deleteRecursively() dir.mkdirs() - logger.info("Generate $RES_FILE_NAME.kt") + val resClassName = resClassName.get() + logger.info("Generate $resClassName.kt") val pkgName = packageName.get() val moduleDirectory = packagingDir.getOrNull()?.let { it.invariantSeparatorsPath + "/" } ?: "" val isPublic = makeAccessorsPublic.get() - getResFileSpec(pkgName, RES_FILE_NAME, moduleDirectory, isPublic).writeTo(dir) + getResFileSpec(pkgName, resClassName, moduleDirectory, isPublic).writeTo(dir) } } diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/GenerateResourceAccessorsTask.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/GenerateResourceAccessorsTask.kt index 6d346c50696..cae05c45f8e 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/GenerateResourceAccessorsTask.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/GenerateResourceAccessorsTask.kt @@ -18,6 +18,9 @@ internal abstract class GenerateResourceAccessorsTask : IdeaImportTask() { @get:Input abstract val packageName: Property + @get:Input + abstract val resClassName: Property + @get:Input abstract val sourceSetName: Property @@ -68,9 +71,10 @@ internal abstract class GenerateResourceAccessorsTask : IdeaImportTask() { val pkgName = packageName.get() val moduleDirectory = packagingDir.getOrNull()?.let { it.invariantSeparatorsPath + "/" } ?: "" + val resClassName = resClassName.get() val isPublic = makeAccessorsPublic.get() getAccessorsSpecs( - resources, pkgName, sourceSet, moduleDirectory, isPublic + resources, pkgName, sourceSet, moduleDirectory, resClassName, isPublic ).forEach { it.writeTo(kotlinDir) } } diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/GenerateResourceCollectorsTask.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/GenerateResourceCollectorsTask.kt index 19b9a371a16..49c32fb2cdf 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/GenerateResourceCollectorsTask.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/GenerateResourceCollectorsTask.kt @@ -15,6 +15,9 @@ internal abstract class GenerateExpectResourceCollectorsTask : IdeaImportTask() @get:Input abstract val packageName: Property + @get:Input + abstract val resClassName: Property + @get:Input abstract val makeAccessorsPublic: Property @@ -31,8 +34,9 @@ internal abstract class GenerateExpectResourceCollectorsTask : IdeaImportTask() logger.info("Generate expect ResourceCollectors for $kotlinDir") val pkgName = packageName.get() + val resClassName = resClassName.get() val isPublic = makeAccessorsPublic.get() - val spec = getExpectResourceCollectorsFileSpec(pkgName, "ExpectResourceCollectors", isPublic) + val spec = getExpectResourceCollectorsFileSpec(pkgName, "ExpectResourceCollectors", resClassName, isPublic) spec.writeTo(kotlinDir) } } @@ -41,6 +45,9 @@ internal abstract class GenerateActualResourceCollectorsTask : IdeaImportTask() @get:Input abstract val packageName: Property + @get:Input + abstract val resClassName: Property + @get:Input abstract val makeAccessorsPublic: Property @@ -89,11 +96,13 @@ internal abstract class GenerateActualResourceCollectorsTask : IdeaImportTask() }.groupBy({ it.first }, { it.second }) val pkgName = packageName.get() + val resClassName = resClassName.get() val isPublic = makeAccessorsPublic.get() val useActual = useActualModifier.get() val spec = getActualResourceCollectorsFileSpec( pkgName, "ActualResourceCollectors", + resClassName, isPublic, useActual, funNames diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/GeneratedResClassSpec.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/GeneratedResClassSpec.kt index 559f0471b3d..0d6856dbaf8 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/GeneratedResClassSpec.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/GeneratedResClassSpec.kt @@ -16,7 +16,7 @@ import com.squareup.kotlinpoet.asClassName import com.squareup.kotlinpoet.withIndent import org.jetbrains.compose.internal.utils.uppercaseFirstChar import java.nio.file.Path -import java.util.* +import java.util.TreeMap import kotlin.io.path.invariantSeparatorsPathString internal enum class ResourceType(val typeName: String, val accessorName: String) { @@ -129,19 +129,19 @@ private fun CodeBlock.Builder.addQualifiers(resourceItem: ResourceItem): CodeBlo internal fun getResFileSpec( packageName: String, - fileName: String, + className: String, moduleDir: String, - isPublic: Boolean + isPublic: Boolean, ): FileSpec { val resModifier = if (isPublic) KModifier.PUBLIC else KModifier.INTERNAL - return FileSpec.builder(packageName, fileName).also { file -> + return FileSpec.builder(packageName, className).also { file -> file.addAnnotation( AnnotationSpec.builder(ClassName("kotlin", "OptIn")) .addMember("org.jetbrains.compose.resources.InternalResourceApi::class") .addMember("org.jetbrains.compose.resources.ExperimentalResourceApi::class") .build() ) - file.addType(TypeSpec.objectBuilder("Res").also { resObject -> + file.addType(TypeSpec.objectBuilder(className).also { resObject -> resObject.addModifiers(resModifier) //readFileBytes @@ -209,7 +209,8 @@ internal fun getAccessorsSpecs( packageName: String, sourceSetName: String, moduleDir: String, - isPublic: Boolean + resClassName: String, + isPublic: Boolean, ): List { val resModifier = if (isPublic) KModifier.PUBLIC else KModifier.INTERNAL val files = mutableListOf() @@ -226,6 +227,7 @@ internal fun getAccessorsSpecs( sourceSetName.uppercaseFirstChar() + type.accessorName.uppercaseFirstChar() + index, packageName, moduleDir, + resClassName, resModifier, idToResources.subMap(ids.first(), true, ids.last(), true) ) @@ -242,8 +244,9 @@ private fun getChunkFileSpec( chunkClassName: String, packageName: String, moduleDir: String, + resClassName: String, resModifier: KModifier, - idToResources: Map> + idToResources: Map>, ): FileSpec { return FileSpec.builder(packageName, fileName).also { chunkFile -> chunkFile.addAnnotation( @@ -282,7 +285,7 @@ private fun getChunkFileSpec( idToResources.forEach { (resName, items) -> val accessor = PropertySpec.builder(resName, type.getClassName(), resModifier) - .receiver(ClassName(packageName, "Res", type.accessorName)) + .receiver(ClassName(packageName, resClassName, type.accessorName)) .getter(FunSpec.getterBuilder().addStatement("return $chunkClassName.%N", resName).build()) .build() chunkFile.addProperty(accessor) @@ -321,7 +324,8 @@ private fun getChunkFileSpec( internal fun getExpectResourceCollectorsFileSpec( packageName: String, fileName: String, - isPublic: Boolean + resClassName: String, + isPublic: Boolean, ): FileSpec { val resModifier = if (isPublic) KModifier.PUBLIC else KModifier.INTERNAL return FileSpec.builder(packageName, fileName).also { file -> @@ -336,7 +340,7 @@ internal fun getExpectResourceCollectorsFileSpec( resModifier ) .addAnnotation(experimentalAnnotation) - .receiver(ClassName(packageName, "Res")) + .receiver(ClassName(packageName, resClassName)) .build() ) } @@ -346,9 +350,10 @@ internal fun getExpectResourceCollectorsFileSpec( internal fun getActualResourceCollectorsFileSpec( packageName: String, fileName: String, + resClassName: String, isPublic: Boolean, useActualModifier: Boolean, //e.g. java only project doesn't need actual modifiers - typeToCollectorFunctions: Map> + typeToCollectorFunctions: Map>, ): FileSpec = FileSpec.builder(packageName, fileName).also { file -> val resModifier = if (isPublic) KModifier.PUBLIC else KModifier.INTERNAL @@ -384,7 +389,7 @@ internal fun getActualResourceCollectorsFileSpec( mods ) .addAnnotation(experimentalAnnotation) - .receiver(ClassName(packageName, "Res")) + .receiver(ClassName(packageName, resClassName)) .delegate(initBlock) .build() file.addProperty(property) @@ -407,4 +412,4 @@ private fun sortResources( result[type] = typeResult } return result -} \ No newline at end of file +} diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/ResourcesDSL.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/ResourcesDSL.kt index 88406e11256..0743b5ff884 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/ResourcesDSL.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/ResourcesDSL.kt @@ -22,6 +22,13 @@ abstract class ResourcesExtension { */ var packageOfResClass: String = "" + /** + * The name of the generated resources accessors class. + * + * The default is "Res". + */ + var resClassName: String = "Res" + enum class ResourceClassGeneration { Auto, Always, Never } //to support groovy DSL