ronantakizawa/codereview-bench huggingface dataset:
Repository: JetBrains/compose-multiplatform
File: html/test-utils/src/jsTest/kotlin/TestsForTestUtils.kt (Kotlin)

Code before:
                }
            } catch (t: TimeoutCancellationException) {
                cancelled = true
                throw t
            }
        }

        delay(100) // to check that `waitForChanges` is suspended after delay
        assertEquals(false, cancelled)

        delay(1000) // to check that `waitForChanges` is cancelled after timeout
        assertEquals(true, cancelled)

        job.join()
    }

    @Test
    fun waitForRecompositionComplete_cancels_with_timeout() = runTest {

        var cancelled = false

        val job = launch {
            try {
                withTimeout(1000) {
                    waitForRecompositionComplete()
                }
            } catch (t: TimeoutCancellationException) {
                cancelled = true
                throw t
            }
        }

        delay(100) // to check that `waitForRecompositionComplete` is suspended after delay
        assertEquals(false, cancelled)

        delay(1000) // to check that `waitForRecompositionComplete` is cancelled after timeout
        assertEquals(true, cancelled)

        job.join()
    }
}


Review comment (suggestion):
Please add imports:
```
import kotlinx.coroutines.TimeoutCancellationException
import kotlinx.coroutines.withTimeout
```

Code after:
                withTimeout(1000) {
                    waitForChanges(root)
                }
            } catch (t: TimeoutCancellationException) {
                cancelled = true
                throw t
            }
        }

        delay(100) // to check that `waitForChanges` is suspended after delay
        assertEquals(false, cancelled)

        delay(1000) // to check that `waitForChanges` is cancelled after timeout
        assertEquals(true, cancelled)

        job.join()
    }

    @Test
    fun waitForRecompositionComplete_cancels_with_timeout() = runTest {

        var cancelled = false

        val job = launch {
            try {
                withTimeout(1000) {
                    waitForRecompositionComplete()
                }
            } catch (t: TimeoutCancellationException) {
                cancelled = true
                throw t
            }
        }

        delay(100) // to check that `waitForRecompositionComplete` is suspended after delay
        assertEquals(false, cancelled)

        delay(1000) // to check that `waitForRecompositionComplete` is cancelled after timeout
        assertEquals(true, cancelled)

        job.join()
    }
}
Repository: JetBrains/compose-multiplatform
File: examples/interop/ios-uikit-in-compose/shared/src/iosMain/kotlin/UseUITextField.kt (Kotlin)

Code before:
import kotlinx.cinterop.ObjCAction
import platform.CoreGraphics.CGRectMake
import platform.Foundation.NSSelectorFromString
import platform.UIKit.UIControlEventEditingChanged
import platform.UIKit.UITextField

@OptIn(ExperimentalForeignApi::class)
@Composable
fun UseUITextField() {
    var message by remember { mutableStateOf("Hello, World!") }
    UIKitView(
        factory = {
            val textField = object : UITextField(CGRectMake(0.0, 0.0, 0.0, 0.0)) {
                @ObjCAction
                fun editingChanged() {
                    message = text ?: ""
                }
            }
            textField.addTarget(
                target = textField,
                action = NSSelectorFromString(textField::editingChanged.name),
                forControlEvents = UIControlEventEditingChanged
            )
            textField
        },
        modifier = Modifier.fillMaxWidth().height(30.dp),
        update = { textField ->
            textField.text = message
        }
    )
}


Review comment (suggestion):
```suggestion
        modifier = modifier.fillMaxWidth().height(30.dp),
```
We should add `modifier: Modifier = Modfier` to arguments as well

Code after:
import platform.UIKit.UIControlEventEditingChanged
import platform.UIKit.UITextField

@OptIn(ExperimentalForeignApi::class)
@Composable
fun UseUITextField(modifier: Modifier = Modifier) {
    var message by remember { mutableStateOf("Hello, World!") }
    UIKitView(
        factory = {
            val textField = object : UITextField(CGRectMake(0.0, 0.0, 0.0, 0.0)) {
                @ObjCAction
                fun editingChanged() {
                    message = text ?: ""
                }
            }
            textField.addTarget(
                target = textField,
                action = NSSelectorFromString(textField::editingChanged.name),
                forControlEvents = UIControlEventEditingChanged
            )
            textField
        },
        modifier = modifier.fillMaxWidth().height(30.dp),
        update = { textField ->
            textField.text = message
        }
    )
}
Repository: JetBrains/compose-multiplatform
File: examples/interop/ios-uikit-in-compose/shared/src/iosMain/kotlin/main.ios.kt (Kotlin)

Code before:
                .windowInsetsPadding(WindowInsets.systemBars),
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Text("How to use UIKitView inside Compose")

            BlueBorder {
                UIKitView(
                    factory = { MKMapView() },
                    modifier = Modifier.size(300.dp),
                    update = {},
                )
            }

            Spacer(Modifier.size(20.dp))

            BlueBorder {
                UseUITextField()
            }
        }
    }

/**
 * Border to easily understand the size of UIKitView
 */
@Composable
fun BlueBorder(content: @Composable () -> Unit) {
    Box(Modifier.padding(4.dp).border(2.dp, Color.Blue)) {
        content()
    }
}


Review comment (suggestion):
The Jetpack Compose recomendation is to use modifier for this case:
```
    ComposeUIViewController {
        Column(
            Modifier
                .fillMaxSize()
                .windowInsetsPadding(WindowInsets.systemBars),
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Text("How to use UIKitView inside Compose")

            UIKitView(
                factory = { MKMapView() },
                modifier = Modifier.padding(4.dp).border(2.dp, Color.Blue).size(300.dp),
                update = {},
            )

            Spacer(Modifier.size(20.dp))

            UseUITextField(Modifier.padding(4.dp).border(2.dp, Color.Blue))
        }
    }
```

Code after:
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.*
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.interop.UIKitView
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.ComposeUIViewController
import kotlinx.cinterop.ExperimentalForeignApi
import platform.MapKit.MKMapView
import platform.UIKit.UIViewController

@OptIn(ExperimentalForeignApi::class)
fun ComposeEntryPoint(): UIViewController =
    ComposeUIViewController {
        Column(
            Modifier
                .fillMaxSize()
                .windowInsetsPadding(WindowInsets.systemBars),
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Text("How to use UIKitView inside Compose")

            UIKitView(
                factory = { MKMapView() },
                modifier = Modifier.padding(4.dp).border(2.dp, Color.Blue).size(300.dp),
                update = {},
            )

            Spacer(Modifier.size(20.dp))

            UseUITextField(Modifier.padding(4.dp).border(2.dp, Color.Blue))
        }
    }
Repository: JetBrains/compose-multiplatform
File: components/ui-tooling-preview/library/build.gradle.kts (Kotlin)

Code before:
            testTask(Action {
                enabled = false
            })
        }
    }
    macosX64()
    macosArm64()
}

android {
    compileSdk = 34
    namespace = "org.jetbrains.compose.ui.tooling.preview"
    defaultConfig {
        minSdk = 21
        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_11
        targetCompatibility = JavaVersion.VERSION_11
    }
}

configureMavenPublication(
    groupId = "org.jetbrains.compose.components",
    artifactId = "ui-tooling-preview",
    name = "Compose tooling library API. This library provides the API required to declare " +
            "@Preview composables in user apps."
)


Review comment (suggestion):
```suggestion
    name = "Experimental Compose Multiplatform tooling library API. This library provides the API required to declare " +
```

Code after:
            testTask(Action {
                enabled = false
            })
        }
    }
    macosX64()
    macosArm64()
}

android {
    compileSdk = 34
    namespace = "org.jetbrains.compose.ui.tooling.preview"
    defaultConfig {
        minSdk = 21
        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_11
        targetCompatibility = JavaVersion.VERSION_11
    }
}

configureMavenPublication(
    groupId = "org.jetbrains.compose.components",
    artifactId = "components-ui-tooling-preview",
    name = "Experimental Compose Multiplatform tooling library API. This library provides the API required to declare " +
            "@Preview composables in user apps."
)
Repository: JetBrains/compose-multiplatform
File: components/ui-tooling-preview/library/build.gradle.kts (Kotlin)

Code before:
    js {
        browser {
            testTask(Action {
                enabled = false
            })
        }
    }
    macosX64()
    macosArm64()
}

android {
    compileSdk = 34
    namespace = "org.jetbrains.compose.ui.tooling.preview"
    defaultConfig {
        minSdk = 21
        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_11
        targetCompatibility = JavaVersion.VERSION_11
    }
}

configureMavenPublication(
    groupId = "org.jetbrains.compose.components",
    artifactId = "ui-tooling-preview",
    name = "Compose tooling library API. This library provides the API required to declare " +
            "@Preview composables in user apps."
)


Review comment (suggestion):
We, users, and IDE devs should be aware that this is subject to change in the future. Please, mention that in the PR message (with mentioning that it is an experiemental library).

Code after:
    js {
        browser {
            testTask(Action {
                enabled = false
            })
        }
    }
    macosX64()
    macosArm64()
}

android {
    compileSdk = 34
    namespace = "org.jetbrains.compose.ui.tooling.preview"
    defaultConfig {
        minSdk = 21
        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_11
        targetCompatibility = JavaVersion.VERSION_11
    }
}

configureMavenPublication(
    groupId = "org.jetbrains.compose.components",
    artifactId = "components-ui-tooling-preview",
    name = "Experimental Compose Multiplatform tooling library API. This library provides the API required to declare " +
            "@Preview composables in user apps."
)
Repository: JetBrains/compose-multiplatform
File: components/ui-tooling-preview/library/build.gradle.kts (Kotlin)

Code before:
        browser {
            testTask(Action {
                enabled = false
            })
        }
    }
    macosX64()
    macosArm64()
}

android {
    compileSdk = 34
    namespace = "org.jetbrains.compose.ui.tooling.preview"
    defaultConfig {
        minSdk = 21
        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_11
        targetCompatibility = JavaVersion.VERSION_11
    }
}

configureMavenPublication(
    groupId = "org.jetbrains.compose.components",
    artifactId = "ui-tooling-preview",
    name = "Compose tooling library API. This library provides the API required to declare " +
            "@Preview composables in user apps."
)


Review comment (suggestion):
```suggestion
    artifactId = "components-ui-tooling-preview",
```
We add "components-" prefix:
<img width="384" alt="image" src="https://github.com/JetBrains/compose-multiplatform/assets/5963351/4e8135dd-f163-4605-b9dc-470c0bc7c6fa">


Code after:
        browser {
            testTask(Action {
                enabled = false
            })
        }
    }
    macosX64()
    macosArm64()
}

android {
    compileSdk = 34
    namespace = "org.jetbrains.compose.ui.tooling.preview"
    defaultConfig {
        minSdk = 21
        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_11
        targetCompatibility = JavaVersion.VERSION_11
    }
}

configureMavenPublication(
    groupId = "org.jetbrains.compose.components",
    artifactId = "components-ui-tooling-preview",
    name = "Experimental Compose Multiplatform tooling library API. This library provides the API required to declare " +
            "@Preview composables in user apps."
)
Repository: JetBrains/compose-multiplatform
File: components/resources/library/build.gradle.kts (Kotlin)

Code before:
            }
        }
        val androidMain by getting {
            dependsOn(jvmAndAndroidMain)
        }
        val androidInstrumentedTest by getting {
            dependsOn(jvmAndAndroidTest)
            dependencies {
                implementation("androidx.test:core:1.5.0")
                implementation("androidx.compose.ui:ui-test-manifest:1.5.4")
                implementation("androidx.compose.ui:ui-test:1.5.4")
                implementation("androidx.compose.ui:ui-test-junit4:1.5.4")
            }
        }
        val androidUnitTest by getting {
            dependsOn(jvmAndAndroidTest)
        }
        val nativeMain by getting {
            dependsOn(skikoMain)
            dependsOn(blockingMain)
        }
        val nativeTest by getting {
            dependsOn(skikoTest)
            dependsOn(blockingTest)
        }
        val webMain by creating {
            dependsOn(skikoMain)
        }
        val jsMain by getting {
            dependsOn(webMain)
        }
        val wasmJsMain by getting {
            dependsOn(webMain)
        }
        val jsTest by getting {
            dependsOn(skikoTest)
        }
        val wasmJsTest by getting {
            dependsOn(skikoTest)
        }
    }
}

android {
    compileSdk = 34
    namespace = "org.jetbrains.compose.components.resources"
    defaultConfig {
        minSdk = 21
        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }
    compileOptions {

Review comment (suggestion):
We need to keep a mirroring of main and test source sets to avoid hidden problems.
need to add the webTest

Code after:
            }
        }
        val androidMain by getting {
            dependsOn(jvmAndAndroidMain)
        }
        val androidInstrumentedTest by getting {
            dependsOn(jvmAndAndroidTest)
            dependencies {
                implementation("androidx.test:core:1.5.0")
                implementation("androidx.compose.ui:ui-test-manifest:1.5.4")
                implementation("androidx.compose.ui:ui-test:1.5.4")
                implementation("androidx.compose.ui:ui-test-junit4:1.5.4")
            }
        }
        val androidUnitTest by getting {
            dependsOn(jvmAndAndroidTest)
        }
        val nativeMain by getting {
            dependsOn(skikoMain)
            dependsOn(blockingMain)
        }
        val nativeTest by getting {
            dependsOn(skikoTest)
            dependsOn(blockingTest)
        }
        val webMain by creating {
            dependsOn(skikoMain)
        }
        val jsMain by getting {
            dependsOn(webMain)
        }
        val wasmJsMain by getting {
            dependsOn(webMain)
        }
        val webTest by creating {
            dependsOn(skikoTest)
        }
        val jsTest by getting {
            dependsOn(webTest)
        }
        val wasmJsTest by getting {
            dependsOn(webTest)
        }
    }
}

android {
    compileSdk = 34
    namespace = "org.jetbrains.compose.components.resources"
    defaultConfig {
        minSdk = 21
Repository: JetBrains/compose-multiplatform
File: components/resources/library/src/commonTest/kotlin/org/jetbrains/compose/resources/TestUtils.kt (Kotlin)

Code before:
package org.jetbrains.compose.resources

import kotlinx.coroutines.CoroutineScope

expect fun runBlockingTest(block: suspend CoroutineScope.() -> Unit)

internal fun TestStringResource(key: String) = StringResource(
    "STRING:$key",
    key,
    setOf(ResourceItem(emptySet(), "strings.xml"))
)

Review comment (suggestion):
The test return type is different on platforms:
`-` void for k/jvm and k/native
`-` Promise<*> for k/js and k/wasm

Therefore we need to distinguish between them to ensure the compilation works. 

Code after:
package org.jetbrains.compose.resources

import kotlinx.coroutines.CoroutineScope

expect class TestReturnType

expect fun runBlockingTest(block: suspend CoroutineScope.() -> Unit): TestReturnType

internal fun TestStringResource(key: String) = StringResource(
    "STRING:$key",
    key,
    setOf(ResourceItem(emptySet(), "strings.xml"))
)
Repository: JetBrains/compose-multiplatform
File: tools/changelog.main.kts (Kotlin)

Code before:

val subsectionOrder = listOf(
    "Multiple Platforms",
    "iOS",
    "Desktop",
    "Web",
    "Resources",
    "Gradle Plugin",
    "Lifecycle",
    "Navigation",
    null
)

if (token == null) {
    println("To increase the rate limit, specify token (https://github.com/settings/tokens): kotlin changelog.main.kts <firstCommit> <lastCommit> TOKEN")
}

val entries = entriesForRepo("JetBrains/compose-multiplatform-core") +
        entriesForRepo("JetBrains/compose-multiplatform")

println("\n# CHANGELOG")

println(
    buildString {
        append("_Changes since ${commitToVersion(firstCommit)}_\n")
        append("\n")

        entries
            .sortedBy { it.sectionOrder() }
            .groupBy { it.sectionName() }
            .forEach { (section, sectionEntries) ->
                appendLine("## $section")

                sectionEntries
                    .sortedBy { it.subsectionOrder() }
                    .groupBy { it.subsectionName() }
                    .forEach { (subsection, subsectionEntries) ->
                        appendLine("### $subsection")
                        subsectionEntries.forEach {
                            appendLine(it.format())
                        }
                        appendLine()
                    }
            }
    }
)

/**
 * Transforms v1.6.0-beta01 to 1.6.0-beta01
 */
fun commitToVersion(commit: String) =

Review comment (suggestion):
```suggestion
println("\n# ${version} (${currentMonth})")
```

Code after:
    "Features",
    "Fixes",
)

val standardSubsections = listOf(
    "Multiple Platforms",
    "iOS",
    "Desktop",
    "Web",
    "Android",
    "Resources",
    "Gradle Plugin",
    "Lifecycle",
    "Navigation",
)

val changelogFile = __FILE__.resolve("../../CHANGELOG.md")

//endregion

val versionCommit = args.find { !it.contains("=") } ?: "HEAD"
val token = args.find { it.startsWith("token=") }?.removePrefix("token=")

println("Note. The script supports optional arguments: kotlin changelog.main.kts [versionCommit] [token=githubToken]")
if (token == null) {
    println("To increase the rate limit, specify token (https://github.com/settings/tokens)")
}
println()

val currentChangelog = changelogFile.readText()
val currentVersion = commitToVersion(versionCommit)
val previousChangelog =
    if (currentChangelog.startsWith("# $currentVersion ")) {
        val nextChangelogIndex = currentChangelog.indexOf("\n# ")
        currentChangelog.substring(nextChangelogIndex).removePrefix("\n")
    } else {
        currentChangelog
    }

val previousVersion = previousChangelog.substringAfter("# ").substringBefore(" (")

println("Generating changelog between $previousVersion and $currentVersion")

val newChangelog = getChangelog("v$previousVersion", versionCommit)

changelogFile.writeText(
    newChangelog + previousChangelog
)

println()
println("CHANGELOG.md changed")
Repository: JetBrains/compose-multiplatform
File: gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/ResourcesExtension.kt (Kotlin)

Code before:
package org.jetbrains.compose.resources

abstract class ResourcesExtension {
    /**
     * Whether the generated resources accessors class should be public or not.
     *
     * Default is false.
     */
    var publicResClass: Boolean = false

    /**
     * The unique identifier of the resources in the current project.
     * Uses as package for the generated Res class and for isolation resources in a final artefact.
     *
     * If it is empty then `{group name}.{module name}.generated.resources` will be used.
     *
     */
    var resourceProjectId: String = ""

    enum class ResourceClassGeneration { Auto, Always }

    //to support groovy DSL
    val auto = ResourceClassGeneration.Auto
    val always = ResourceClassGeneration.Always

    /**
     * The mode of resource class generation.
     *
     * - `auto`: The Res class will be generated if the current project has an explicit "implementation" or "api" dependency on the resource's library.
     * - `always`: Unconditionally generate the Res class. This may be useful when the resources library is available transitively.
     */
    var generateResClass: ResourceClassGeneration = auto
}

Review comment (suggestion):
```suggestion
    var resourceProjectId: String? = null
```
I would either make null as the default, or make it `Provider<String> = DefaultResourceProjectId`, which reads groupId + moduleId.

Checking an empty string can cause issues.

Code after:
package org.jetbrains.compose.resources

abstract class ResourcesExtension {
    /**
     * Whether the generated resources accessors class should be public or not.
     *
     * Default is false.
     */
    var publicResClass: Boolean = false

    /**
     * The unique identifier of the resources in the current project.
     * Uses as package for the generated Res class and for isolation resources in a final artefact.
     *
     * If it is empty then `{group name}.{module name}.generated.resources` will be used.
     *
     */
    var packageOfResClass: String = ""

    enum class ResourceClassGeneration { Auto, Always }

    //to support groovy DSL
    val auto = ResourceClassGeneration.Auto
    val always = ResourceClassGeneration.Always

    /**
     * The mode of resource class generation.
     *
     * - `auto`: The Res class will be generated if the current project has an explicit "implementation" or "api" dependency on the resource's library.
     * - `always`: Unconditionally generate the Res class. This may be useful when the resources library is available transitively.
     */
    var generateResClass: ResourceClassGeneration = auto
}