Repository: JetBrains/kotlin
File: libraries/tools/kotlin-compose-compiler/src/common/kotlin/org/jetbrains/kotlin/compose/compiler/gradle/internal/ComposeAgpMappingFile.kt (Kotlin)

Code before:
    }
}


@CacheableTask
internal abstract class MergeMappingFileTask @Inject constructor(objects: ObjectFactory) : DefaultTask() {

    @get:InputFile
    @get:PathSensitive(PathSensitivity.RELATIVE)
    abstract val originalFile: RegularFileProperty

    @get:InputFiles
    @get:PathSensitive(PathSensitivity.RELATIVE)
    val r8Outputs: FileCollection = objects.fileCollection()
        .from(originalFile.asFile.map { it.parentFile })
        .asFileTree
        .matching {
            it.include("**/*")
        }

    @get:InputFile
    @get:PathSensitive(PathSensitivity.RELATIVE)
    abstract val composeMapping: RegularFileProperty

    @get:OutputFile
    abstract val output: RegularFileProperty

    @get:OutputDirectory
    val outputDir: Provider<File> = output.asFile.map { it.parentFile }

    @TaskAction
    fun taskAction() {
        /*
         * Read the proguard file generated by R8, calculate the new SHA-256 hash for the header, and append Compose mapping.
         */
        val newHeader = buildHeader()

        val originalFile = originalFile.get().asFile

        val outputFile = output.get().asFile
        val outputDir = outputDir.get()
        outputDir.mkdirs()

        outputFile.bufferedWriter().use { writer ->
            writer.append(newHeader)

            var skippingHeader = true
            originalFile.forEachLine {
                if (skippingHeader && it.startsWith("#")) {
                    return@forEachLine
                }

Review comment (suggestion):
This looks SuS:
- property `output` is already annotated with `@OutputFile`, but this output is also part of this output directory
- could other tasks write to this directory? For example R8? If yes, Gradle will complain as it could not detect from where new additional outputs are present and invalidate the task state.

Maybe better to change annotation type to `@OutputFiles`.

Code after:
    }
}


@CacheableTask
internal abstract class MergeMappingFileTask @Inject constructor(objects: ObjectFactory) : DefaultTask() {

    @get:InputFile
    @get:PathSensitive(PathSensitivity.RELATIVE)
    abstract val originalFile: RegularFileProperty

    @get:InputFiles
    @get:PathSensitive(PathSensitivity.RELATIVE)
    val r8Outputs: FileCollection = objects.fileCollection()
        .from(originalFile.asFile.map { it.parentFile })
        .asFileTree

    @get:InputFile
    @get:PathSensitive(PathSensitivity.RELATIVE)
    abstract val composeMapping: RegularFileProperty

    @get:OutputFile
    abstract val output: RegularFileProperty

    @get:OutputFiles
    val outputDir: Provider<File> = output.asFile.map { it.parentFile }

    @TaskAction
    fun taskAction() {
        /*
         * Read the proguard file generated by R8, calculate the new SHA-256 hash for the header, and append Compose mapping.
         */
        val newHeader = buildHeader()

        val originalFile = originalFile.get().asFile

        val outputFile = output.get().asFile
        val outputDir = outputDir.get()
        outputDir.mkdirs()

        outputFile.bufferedWriter().use { writer ->
            writer.append(newHeader)

            var skippingHeader = true
            originalFile.forEachLine {
                if (skippingHeader && it.startsWith("#")) {
                    return@forEachLine
                }
                skippingHeader = false

                writer.appendLine(it)