Skip to content

Commit

Permalink
[gradle] Don't use actual modifiers for JVM only projects.
Browse files Browse the repository at this point in the history
  • Loading branch information
terrakok committed Jul 5, 2024
1 parent 08a84ae commit a8666a9
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -154,23 +154,36 @@ private fun Project.configureResourceCollectorsGeneration(
makeAccessorsPublic: Provider<Boolean>
) {
if (kotlinExtension is KotlinMultiplatformExtension) {
kotlinExtension.sourceSets
.matching { it.name == KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME }
.all { commonMainSourceSet ->
configureExpectResourceCollectorsGeneration(
commonMainSourceSet,
shouldGenerateCode,
packageName,
makeAccessorsPublic
)
}

kotlinExtension.targets.all { target ->
if (target is KotlinAndroidTarget) {
kotlinExtension.sourceSets.matching { it.name == "androidMain" }.all { androidMain ->
configureResourceCollectorsGeneration(
configureActualResourceCollectorsGeneration(
androidMain,
shouldGenerateCode,
packageName,
makeAccessorsPublic
makeAccessorsPublic,
true
)
}
} else if (target !is KotlinMetadataTarget) {
target.compilations.matching { it.name == KotlinCompilation.MAIN_COMPILATION_NAME }.all { compilation ->
configureResourceCollectorsGeneration(
configureActualResourceCollectorsGeneration(
compilation.defaultSourceSet,
shouldGenerateCode,
packageName,
makeAccessorsPublic
makeAccessorsPublic,
true
)
}
}
Expand All @@ -180,47 +193,73 @@ private fun Project.configureResourceCollectorsGeneration(
kotlinExtension.target.compilations
.findByName(KotlinCompilation.MAIN_COMPILATION_NAME)
?.let { compilation ->
configureResourceCollectorsGeneration(
configureActualResourceCollectorsGeneration(
compilation.defaultSourceSet,
shouldGenerateCode,
packageName,
makeAccessorsPublic
makeAccessorsPublic,
false
)
}
}

}

private fun Project.configureResourceCollectorsGeneration(
private fun Project.configureExpectResourceCollectorsGeneration(
sourceSet: KotlinSourceSet,
shouldGenerateCode: Provider<Boolean>,
packageName: Provider<String>,
makeAccessorsPublic: Provider<Boolean>
) {
val taskName = "generateResourceCollectorsFor${sourceSet.name.uppercaseFirstChar()}"
logger.info("Configure expect resource collectors generation for ${sourceSet.name}")


val genTask = tasks.register(
"generateExpectResourceCollectorsFor${sourceSet.name.uppercaseFirstChar()}",
GenerateExpectResourceCollectorsTask::class.java
) { task ->
task.packageName.set(packageName)
task.shouldGenerateCode.set(shouldGenerateCode)
task.makeAccessorsPublic.set(makeAccessorsPublic)
task.codeDir.set(layout.buildDirectory.dir("$RES_GEN_DIR/kotlin/${sourceSet.name}ResourceCollectors"))
}

//register generated source set
sourceSet.kotlin.srcDir(genTask.map { it.codeDir })
}

private fun Project.configureActualResourceCollectorsGeneration(
sourceSet: KotlinSourceSet,
shouldGenerateCode: Provider<Boolean>,
packageName: Provider<String>,
makeAccessorsPublic: Provider<Boolean>,
useActualModifier: Boolean
) {
val taskName = "generateActualResourceCollectorsFor${sourceSet.name.uppercaseFirstChar()}"
if (tasks.names.contains(taskName)) {
logger.info("Resource collectors generation for ${sourceSet.name} is already configured")
logger.info("Actual resource collectors generation for ${sourceSet.name} is already configured")
return
}
logger.info("Configure resource collectors generation for ${sourceSet.name}")
logger.info("Configure actual resource collectors generation for ${sourceSet.name}")

val accessorDirs = project.files({
val allSourceSets = sourceSet.withClosure { it.dependsOn }
allSourceSets.mapNotNull { item ->
val taskName = item.getResourceAccessorsGenerationTaskName()
if (tasks.names.contains(taskName)) {
tasks.named(taskName, GenerateResourceAccessorsTask::class.java).map { it.codeDir }
val accessorsTaskName = item.getResourceAccessorsGenerationTaskName()
if (tasks.names.contains(accessorsTaskName)) {
tasks.named(accessorsTaskName, GenerateResourceAccessorsTask::class.java).map { it.codeDir }
} else null
}
})

val genTask = tasks.register(
taskName,
GenerateResourceCollectorsTask::class.java
GenerateActualResourceCollectorsTask::class.java
) { task ->
task.packageName.set(packageName)
task.shouldGenerateCode.set(shouldGenerateCode)
task.makeAccessorsPublic.set(makeAccessorsPublic)
task.useActualModifier.set(useActualModifier)
task.resourceAccessorDirs.from(accessorDirs)
task.codeDir.set(layout.buildDirectory.dir("$RES_GEN_DIR/kotlin/${sourceSet.name}ResourceCollectors"))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@ import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.SkipWhenEmpty
import org.jetbrains.compose.internal.IdeaImportTask
import org.jetbrains.compose.internal.utils.uppercaseFirstChar

internal abstract class GenerateResourceCollectorsTask : IdeaImportTask() {
internal abstract class GenerateExpectResourceCollectorsTask : IdeaImportTask() {
@get:Input
abstract val packageName: Property<String>

Expand All @@ -22,6 +21,40 @@ internal abstract class GenerateResourceCollectorsTask : IdeaImportTask() {
@get:Input
abstract val makeAccessorsPublic: Property<Boolean>

@get:OutputDirectory
abstract val codeDir: DirectoryProperty

override fun safeAction() {
val kotlinDir = codeDir.get().asFile

logger.info("Clean directory $kotlinDir")
kotlinDir.deleteRecursively()
kotlinDir.mkdirs()

if (shouldGenerateCode.get()) {
logger.info("Generate expect ResourceCollectors for $kotlinDir")

val pkgName = packageName.get()
val isPublic = makeAccessorsPublic.get()
val spec = getExpectResourceCollectorsFileSpec(pkgName, "ExpectResourceCollectors", isPublic)
spec.writeTo(kotlinDir)
}
}
}

internal abstract class GenerateActualResourceCollectorsTask : IdeaImportTask() {
@get:Input
abstract val packageName: Property<String>

@get:Input
abstract val shouldGenerateCode: Property<Boolean>

@get:Input
abstract val makeAccessorsPublic: Property<Boolean>

@get:Input
abstract val useActualModifier: Property<Boolean>

@get:InputFiles
@get:PathSensitive(PathSensitivity.RELATIVE)
abstract val resourceAccessorDirs: ConfigurableFileCollection
Expand All @@ -42,7 +75,7 @@ internal abstract class GenerateResourceCollectorsTask : IdeaImportTask() {
}

if (shouldGenerateCode.get()) {
logger.info("Generate ResourceCollectors for $kotlinDir")
logger.info("Generate actual ResourceCollectors for $kotlinDir")
val funNames = inputFiles.mapNotNull { inputFile ->
if (inputFile.nameWithoutExtension.contains('.')) {
val (fileName, suffix) = inputFile.nameWithoutExtension.split('.')
Expand All @@ -67,7 +100,14 @@ internal abstract class GenerateResourceCollectorsTask : IdeaImportTask() {

val pkgName = packageName.get()
val isPublic = makeAccessorsPublic.get()
val spec = getResourceCollectorsFileSpec("ResourceCollectors", pkgName, isPublic, funNames)
val useActual = useActualModifier.get()
val spec = getActualResourceCollectorsFileSpec(
pkgName,
"ActualResourceCollectors",
isPublic,
useActual,
funNames
)
spec.writeTo(kotlinDir)
} else {
logger.info("Generation ResourceCollectors for $kotlinDir is disabled")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
package org.jetbrains.compose.resources

import com.squareup.kotlinpoet.*
import com.squareup.kotlinpoet.AnnotationSpec
import com.squareup.kotlinpoet.ClassName
import com.squareup.kotlinpoet.CodeBlock
import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.FunSpec
import com.squareup.kotlinpoet.KModifier
import com.squareup.kotlinpoet.MAP
import com.squareup.kotlinpoet.MUTABLE_MAP
import com.squareup.kotlinpoet.MemberName
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
import com.squareup.kotlinpoet.PropertySpec
import com.squareup.kotlinpoet.TypeSpec
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.*
Expand Down Expand Up @@ -179,22 +191,6 @@ internal fun getResFileSpec(
resObject.addType(TypeSpec.objectBuilder(type.accessorName).build())
}
}.build())

ResourceType.values().forEach { type ->
val typeClassName = type.getClassName()
file.addProperty(
PropertySpec
.builder(
"all${typeClassName.simpleName}s",
MAP.parameterizedBy(String::class.asClassName(), typeClassName),
KModifier.EXPECT,
resModifier
)
.addAnnotation(experimentalAnnotation)
.receiver(ClassName(packageName, "Res"))
.build()
)
}
}.build()
}

Expand Down Expand Up @@ -322,10 +318,36 @@ private fun getChunkFileSpec(
}.build()
}

internal fun getResourceCollectorsFileSpec(
internal fun getExpectResourceCollectorsFileSpec(
packageName: String,
fileName: String,
isPublic: Boolean
): FileSpec {
val resModifier = if (isPublic) KModifier.PUBLIC else KModifier.INTERNAL
return FileSpec.builder(packageName, fileName).also { file ->
ResourceType.values().forEach { type ->
val typeClassName = type.getClassName()
file.addProperty(
PropertySpec
.builder(
"all${typeClassName.simpleName}s",
MAP.parameterizedBy(String::class.asClassName(), typeClassName),
KModifier.EXPECT,
resModifier
)
.addAnnotation(experimentalAnnotation)
.receiver(ClassName(packageName, "Res"))
.build()
)
}
}.build()
}

internal fun getActualResourceCollectorsFileSpec(
packageName: String,
fileName: String,
isPublic: Boolean,
useActualModifier: Boolean, //e.g. java only project doesn't need actual modifiers
typeToCollectorFunctions: Map<ResourceType, List<String>>
): FileSpec = FileSpec.builder(packageName, fileName).also { file ->
val resModifier = if (isPublic) KModifier.PUBLIC else KModifier.INTERNAL
Expand All @@ -349,12 +371,17 @@ internal fun getResourceCollectorsFileSpec(
.addStatement("}")
.build()

val mods = if (useActualModifier) {
listOf(KModifier.ACTUAL, resModifier)
} else {
listOf(resModifier)
}

val property = PropertySpec
.builder(
"all${typeClassName.simpleName}s",
MAP.parameterizedBy(String::class.asClassName(), typeClassName),
KModifier.ACTUAL,
resModifier
mods
)
.addAnnotation(experimentalAnnotation)
.receiver(ClassName(packageName, "Res"))
Expand Down

0 comments on commit a8666a9

Please sign in to comment.