ronantakizawa/codereview-bench huggingface dataset:
Repository: InsertKoinIO/koin
File: projects/compose/koin-compose/src/commonMain/kotlin/org/koin/compose/ComposeContextWrapper.kt (Kotlin)

Code before:
package org.koin.compose

import org.koin.core.annotation.KoinInternalApi

/**
 * Compose Context Wrapper for Koin & Scope
 *
 * Internal wrapper used by LocalKoinApplication and LocalKoinScope to handle:
 * - Lazy initialization of Koin context and scopes
 * - Recovery from closed scopes by resetting to default values
 * - Context restoration after errors or configuration changes
 *
 * This wrapper is necessary to handle the Compose lifecycle where scopes may be closed
 * but the composition local still exists, allowing for graceful fallback to default contexts.
 *
 * @param initValue Initial value for the wrapper
 * @param setValue Lambda to reset/reinitialize the value when needed
 *
 * @author Arnaud Giuliani
 */
@KoinInternalApi
class ComposeContextWrapper<T>(initValue : T? = null, val setValue : (() -> T)? = null){

    private var _value : T? = initValue

    /**
     * Resets the wrapped value by invoking setValue lambda.
     * Used when recovering from closed scopes or errors.
     */
    fun resetValue(): T? {
        _value = setValue?.invoke()
        return _value
    }

Review comment (suggestion):
Documentation references outdated API names 'LocalKoinApplication' and 'LocalKoinScope'. These should be updated to 'LocalKoinApplicationContext' and 'LocalKoinScopeContext' to reflect the new naming.
```suggestion
 * Internal wrapper used by LocalKoinApplicationContext and LocalKoinScopeContext to handle:
```

Code after:
package org.koin.compose

import org.koin.core.annotation.KoinInternalApi

/**
 * Compose Context Wrapper for Koin & Scope
 *
 * Internal wrapper used by LocalKoinApplicationContext and LocalKoinScopeContext to handle:
 * - Lazy initialization of Koin context and scopes
 * - Recovery from closed scopes by resetting to default values
 * - Context restoration after errors or configuration changes
 *
 * This wrapper is necessary to handle the Compose lifecycle where scopes may be closed
 * but the composition local still exists, allowing for graceful fallback to default contexts.
 *
 * @param initValue Initial value for the wrapper
 * @param setValue Lambda to reset/reinitialize the value when needed
 *
 * @author Arnaud Giuliani
 */
@KoinInternalApi
class ComposeContextWrapper<T>(initValue : T? = null, val setValue : (() -> T)? = null){

    private var _value : T? = initValue

    /**
     * Resets the wrapped value by invoking setValue lambda.
     * Used when recovering from closed scopes or errors.
     */
    fun resetValue(): T? {
        _value = setValue?.invoke()
        return _value
    }
Repository: InsertKoinIO/koin
File: projects/core/koin-core/src/commonTest/kotlin/org/koin/core/ScopeTest.kt (Kotlin)

Code before:
    fun scope_regression_test(){
        startKoin {
            modules(
                module {
                    single<Unit> {}
                    scope(named("one")) {}
                    scope(named("two")) {
                        scoped<String> {
                            get<Unit>().toString() // gets Unit from the root scope
                        }
                    }
                },
            )
        }.run {
            val one = koin.createScope("one", named("one"))
            val two = koin.createScope("two", named("two")).apply {
                unlink(getScope("_root_"))
                linkTo(one)
            }
            // in 4.1.0-Beta11 -> prints "kotlin.Unit"
            // in 4.1.0-RC1 -> throws NoDefinitionFoundException
            assertEquals(Unit.toString(),two.get<String>())
        }
    }
}


Review comment (bug):
The try-catch block catches all exceptions but always calls `stopKoin()` in the catch block, which means the test will silently pass even if it fails. The test should either:
1. Not catch the exception (remove try-catch) and rely on proper test cleanup
2. Re-throw the exception after cleanup: `catch (e: Exception) { stopKoin(); throw e }`
3. Use a finally block: `finally { stopKoin() }`

As written, this test cannot fail, making it ineffective at catching regressions.
```suggestion
        } finally {
```

Code after:
    @Test
    fun scope_regression_test(){
        try {
            startKoin {
                modules(
                    module {
                        single<Unit> {}
                        scope(named("one")) {}
                        scope(named("two")) {
                            scoped<String> {
                                get<Unit>().toString() // gets Unit from the root scope
                            }
                        }
                    },
                )
            }.run {
                val one = koin.createScope("one", named("one"))
                val two = koin.createScope("two", named("two")).apply {
                    unlink(getScope("_root_"))
                    linkTo(one)
                }
                // in 4.1.0-Beta11 -> prints "kotlin.Unit"
                // in 4.1.0-RC1 -> throws NoDefinitionFoundException
                assertEquals(Unit.toString(),two.get<String>())
            }
        } catch (e: Exception) {
            stopKoin()
        }
    }

    @Test
    fun scope_regression_test2(){
        val koin = startKoin {
            modules(
                module {
                    single<String> { "ABC" }
                    scope(named("scope1")) {}
                    scope(named("scope2")) {}
                }
            )
        }.koin

        val scope1 = koin.createScope("scope1", named("scope1"))

        val scope2 = koin.createScope("scope2", named("scope2")).apply {
            unlink(koin.getScope("_root_"))
            linkTo(scope1)
        }

        // Koin 4.1.0 returns "ABC"
        // Koin 4.1.1 throws NoDefinitionFoundException
Repository: InsertKoinIO/koin
File: projects/compose/koin-compose-navigation3/build.gradle.kts (Kotlin)

Code before:
    }

    iosX64()
    iosArm64()
    iosSimulatorArm64()
    macosX64()
    macosArm64()

    sourceSets {
        androidMain.dependencies {
            api(project(":android:koin-android"))
        }
        commonMain.dependencies {
            api(project(":compose:koin-compose"))
            implementation(libs.androidx.navigation3.runtime)
        }
    }
}

val androidCompileSDK: String by project
val androidMinSDK : String by project

android {
    namespace = "org.koin.compose.navigation3"
    compileSdk = androidCompileSDK.toInt()
    defaultConfig {
        minSdk = androidMinSDK.toInt()
    }
}

tasks.withType<org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinNpmInstallTask>().configureEach {
    args.add("--ignore-engines")
}

apply(from = file("../../gradle/publish.gradle.kts"))


Review comment (suggestion):
The minSdk value is hardcoded as `23`, while other similar build files in the compose directory use `androidMinSDK.toInt()` to read from gradle.properties. This inconsistency could lead to maintenance issues. Consider using `val androidMinSDK : String by project` and `minSdk = androidMinSDK.toInt()` to match the pattern used in other compose modules.

Code after:
    }

    iosX64()
    iosArm64()
    iosSimulatorArm64()
    macosX64()
    macosArm64()

    sourceSets {
        androidMain.dependencies {
            api(project(":android:koin-android"))
        }
        commonMain.dependencies {
            api(project(":compose:koin-compose"))
            implementation(libs.androidx.navigation3.runtime)
        }
    }
}

val androidCompileSDK: String by project

android {
    namespace = "org.koin.compose.navigation3"
    compileSdk = androidCompileSDK.toInt()
    defaultConfig {
        minSdk = 23
    }
}

tasks.withType<org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinNpmInstallTask>().configureEach {
    args.add("--ignore-engines")
}

apply(from = file("../../gradle/publish.gradle.kts"))
Repository: InsertKoinIO/koin
File: projects/android/koin-android/src/test/java/org/koin/test/android/scope/ViewModelScopeArchetypeTest.kt (Kotlin)

Code before:
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertNull
import kotlin.test.assertSame

class ScopedVM(){
    val id : String = UUID.randomUUID().toString()
}
class FakeVM(val s : ScopedVM) : ViewModel()
class FakeVMActivity : ComponentActivity() {

    val fakeVM : FakeVM by viewModel()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }

    fun useViewModel(){
        println("fakeVM :$fakeVM")
    }
}

@RunWith(RobolectricTestRunner::class)
class ViewModelScopeArchetypeTest {

    @OptIn(KoinExperimentalAPI::class)
    @Before
    fun setup() {
        startKoin {
            printLogger(Level.DEBUG)

            options(
                viewModelScopeFactory()
            )
        }
    }

    @After
    fun stop() {
        stopKoin()
    }

    @Test
    fun `viewModelScope resolves`() {
        val koin = KoinPlatform.getKoin()
        val module = module {
            viewModel { FakeVM(get()) }
            viewModelScope {
                scoped { ScopedVM() }
            }
        }

Review comment (suggestion):
Missing `@OptIn(KoinViewModelScopeApi::class)` annotation. The `viewModelScope` function is annotated with `@KoinViewModelScopeApi`, which requires opt-in. The class-level `@OptIn(KoinExperimentalAPI::class)` doesn't cover this requirement.

Code after:
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertNull
import kotlin.test.assertSame

class ScopedVM(){
    val id : String = UUID.randomUUID().toString()
}
class FakeVM(val s : ScopedVM) : ViewModel()
class FakeVMActivity : ComponentActivity() {

    val fakeVM : FakeVM by viewModel()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }

    fun useViewModel(){
        println("fakeVM :$fakeVM")
    }
}

@RunWith(RobolectricTestRunner::class)
@OptIn(KoinExperimentalAPI::class)
class ViewModelScopeArchetypeTest {

    @Before
    fun setup() {
        startKoin {
            printLogger(Level.DEBUG)

            options(
                viewModelScopeFactory()
            )
        }
    }

    @After
    fun stop() {
        stopKoin()
    }

    @Test
    fun `viewModelScope resolves`() {
        val koin = KoinPlatform.getKoin()
        val module = module {
            viewModelScope {
                viewModel { FakeVM(get()) }
                scoped { ScopedVM() }
            }
Repository: JetBrains/compose-multiplatform
File: experimental/examples/chat-mpp/shared/src/iosMain/kotlin/main.ios.kt (Kotlin)

Code before:
import androidx.compose.ui.window.Application
import platform.UIKit.UIViewController

fun MainViewController(): UIViewController =
    Application("Chat") {
        ChatApp(displayTextField = false)
    }

fun sendMessage(text: String) {
    store.send(Action.SendMessage(Message(myUser, timestampMs(), text)))
}

fun gradient3Colors() = ChatColors.GRADIENT_3

fun surfaceColor() = ChatColors.SURFACE


Review comment (suggestion):
May be we should add other than Application method for  wrapping Compose to UIViewController.
And it is not MainViewController  now  but just ChatWindow

Code after:
import androidx.compose.ui.window.Application
import platform.UIKit.UIViewController

fun ChapViewController(): UIViewController =
    Application("Chat") {
        ChatApp(displayTextField = false)
    }

fun sendMessage(text: String) {
    store.send(Action.SendMessage(Message(myUser, timestampMs(), text)))
}

fun gradient3Colors() = ChatColors.GRADIENT_3

fun surfaceColor() = ChatColors.SURFACE
Repository: JetBrains/compose-multiplatform
File: experimental/examples/chat-mpp/iosApp/iosApp/ComposeViewControllerToSwiftUI.swift (Swift)

Code before:
    func sizeThatFits(_ proposal: ProposedViewSize, uiViewController: UIViewControllerType, context: Context) -> CGSize? {
        return uiViewController.view.frame.size
    }
}

public func sendMessage(_ text: String) {
    Main_iosKt.sendMessage(text: text)
}

public func gradient3Colors() -> [Color] {
    return Main_iosKt.gradient3Colors().map { hex in
        Color(getCGColor(hex.intValue)).opacity(1.0)
    }
}

public func surfaceColor() -> Color {
    Color(getCGColor(Int(Main_iosKt.surfaceColor())))
}

private func getCGColor(_ argb: Int) -> CGColor {
    func clr(_ component: Int) -> CGFloat {
        CGFloat(component & 0xff) / 255.0
    }

    return CGColor(red: clr(argb >> 16), green: clr(argb >> 8), blue: clr(argb), alpha: clr(argb >> 24))
}


Review comment (suggestion):
Can you move these functions out into a separate file? They don't seem like they're actually related to the "ComposeViewControllerToSwiftUI" adapter :)

Code after:
import UIKit
import SwiftUI
import shared

struct ComposeViewControllerToSwiftUI: UIViewControllerRepresentable {
    func makeUIViewController(context: Context) -> UIViewController {
        return Main_iosKt.ChapViewController()
    }

    func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
    }
}
Repository: JetBrains/compose-multiplatform
File: experimental/components/VideoPlayer/library/src/commonMain/kotlin/org/jetbrains/compose/videoplayer/VideoPlayer.kt (Kotlin)

Code before:
fun VideoPlayer(
    url: String,
    state: VideoPlayerState,
    modifier: Modifier = Modifier,
    onFinish: (() -> Unit)? = null
) = VideoPlayerImpl(
    url = url,
    isResumed = state.isResumed,
    volume = state.volume,
    speed = state.speed,
    seek = state.seek,
    isFullscreen = state.isFullscreen,
    modifier = modifier,
    onFinish = onFinish
)

internal expect fun VideoPlayerImpl(
    url: String,
    isResumed: Boolean,
    volume: Float,
    speed: Float,
    seek: Float,
    isFullscreen: Boolean,
    modifier: Modifier,
    onFinish: (() -> Unit)?
): State<Progress>

@Composable
fun rememberVideoPlayerState(
    seek: Float = 0f,
    speed: Float = 1f,
    volume: Float = 1f,
    isResumed: Boolean = true,
    isFullscreen: Boolean = false
): VideoPlayerState = rememberSaveable(saver = VideoPlayerState.Saver()) {
    VideoPlayerState(
        seek,
        speed,
        volume,
        isResumed,
        isFullscreen
    )
}

class VideoPlayerState(
    seek: Float = 0f,
    speed: Float = 1f,
    volume: Float = 1f,
    isResumed: Boolean = true,
    isFullscreen: Boolean = false
) {

Review comment (suggestion):
It's a bit unusual when a Composable function that draws/displays some content returns some value (state in this case)  at the same time.

I would pass progressState as a parameter and mutate it in the VideoPlayerImpl. 

Or maybe it's even better to add the progress details to VideoPlayerState. 


Code after:
fun VideoPlayer(
    url: String,
    state: VideoPlayerState,
    modifier: Modifier = Modifier,
    onFinish: (() -> Unit)? = null
) = VideoPlayerImpl(
    url = url,
    isResumed = state.isResumed,
    volume = state.volume,
    speed = state.speed,
    seek = state.seek,
    isFullscreen = state.isFullscreen,
    progressState = state._progress,
    modifier = modifier,
    onFinish = onFinish
)

internal expect fun VideoPlayerImpl(
    url: String,
    isResumed: Boolean,
    volume: Float,
    speed: Float,
    seek: Float,
    isFullscreen: Boolean,
    progressState: MutableState<Progress>,
    modifier: Modifier,
    onFinish: (() -> Unit)?
)

@Composable
fun rememberVideoPlayerState(
    seek: Float = 0f,
    speed: Float = 1f,
    volume: Float = 1f,
    isResumed: Boolean = true,
    isFullscreen: Boolean = false
): VideoPlayerState = rememberSaveable(saver = VideoPlayerState.Saver()) {
    VideoPlayerState(
        seek,
        speed,
        volume,
        isResumed,
        isFullscreen,
        Progress(0f, 0)
    )
}

class VideoPlayerState(
    seek: Float = 0f,
    speed: Float = 1f,
    volume: Float = 1f,
Repository: JetBrains/compose-multiplatform
File: examples/chat/iosApp/iosApp/iosApp.swift (Swift)

Code before:
import SwiftUI

let gradient = LinearGradient(
        colors: [Color(red: 0.933, green: 0.937, blue: 0.953),Color(red: 0.902, green: 0.941, blue: 0.949)
                 ],
        startPoint: .topLeading, endPoint: .bottomTrailing
)

@main
struct iOSApp: App {
	var body: some Scene {
		WindowGroup {
			TabView {
                ComposeInsideSwiftUIScreen()
                    .tabItem { Label("Group Chat", systemImage: "rectangle.3.group.bubble.left") }

                YetAnotherSwiftUIScreen()
                    .tabItem { Label("Settings", systemImage: "gear") }
                
            }
            .accentColor(Color(red: 0.671, green: 0.365, blue: 0.792))//.preferredColorScheme(.dark)
		}
	}
}


Review comment (suggestion):
```suggestion
        colors: [
            Color(red: 0.933, green: 0.937, blue: 0.953),
            Color(red: 0.902, green: 0.941, blue: 0.949)
        ],
```

Code after:
import SwiftUI

let gradient = LinearGradient(
        colors: [
            Color(red: 0.933, green: 0.937, blue: 0.953),
            Color(red: 0.902, green: 0.941, blue: 0.949)
        ],
        startPoint: .topLeading, endPoint: .bottomTrailing
)

@main
struct iOSApp: App {
	var body: some Scene {
		WindowGroup {
			TabView {
                ComposeInsideSwiftUIScreen()
                    .tabItem { Label("Group Chat", systemImage: "rectangle.3.group.bubble.left") }

                YetAnotherSwiftUIScreen()
                    .tabItem { Label("Settings", systemImage: "gear") }
                
            }
            .accentColor(Color(red: 0.671, green: 0.365, blue: 0.792)).preferredColorScheme(.light)
		}
	}
}
Repository: JetBrains/compose-multiplatform
File: benchmarks/ios/visual-effects-ny/shared/src/commonMain/kotlin/HappyNY.kt (Kotlin)

Code before:
}

var measureTime: Long = 0

@Composable
fun NYContent() {
    measureTime = measureTime()
    var time by remember { mutableStateOf(nanoTime()) }
    var startTime = remember { nanoTime() }
    var prevTime by remember { mutableStateOf(nanoTime()) }
    val snowFlakes = remember { mutableStateListOf<SnowFlake>() }
    val stars = remember { mutableStateListOf<Star>() }
    var flickering2 by remember { mutableStateOf(true) }
    remember { prepareStarsAndSnowFlakes(stars, snowFlakes) }

    Surface(
        modifier = Modifier.fillMaxSize().padding(5.dp).shadow(3.dp, RoundedCornerShape(20.dp)),
        color = Color.Black,
        shape = RoundedCornerShape(20.dp)
    ) {

        LaunchedEffect(Unit) {
            while (true) {
                prevTime = time
                time += 10000000
                delay(10)

//                withFrameNanos {
//                    prevTime = time
//                    time = it
//                }
            }
        }

        if (flickering2) {
            if (time - startTime > 15500000000) { //note, that startTime has been updated above
                flickering2 = false
            }
        }

        rocket.move(time, prevTime)

        Box(Modifier.fillMaxSize()) {

            snow(time, prevTime, snowFlakes, startTime)

            starrySky(stars)

            rocket.draw()

        }

Review comment (suggestion):
Not sure how this affects the results, but it is better to use `withFrameNanos` instead of this.

`withFrameNanos` is consistenly called one time each frame. `delay` on the other hand is unpredictable. The actual delay can be 7-13 milliseconds (on Windows 13-20ms instead of 10).

Code after:
}

var measureTime: Long = 0

@Composable
fun NYContent() {
    measureTime = measureTime()
    var time by remember { mutableStateOf(nanoTime()) }
    var startTime = remember { nanoTime() }
    var prevTime by remember { mutableStateOf(nanoTime()) }
    val snowFlakes = remember { mutableStateListOf<SnowFlake>() }
    val stars = remember { mutableStateListOf<Star>() }
    var flickering2 by remember { mutableStateOf(true) }
    remember { prepareStarsAndSnowFlakes(stars, snowFlakes) }

    Surface(
        modifier = Modifier.fillMaxSize().padding(5.dp).shadow(3.dp, RoundedCornerShape(20.dp)),
        color = Color.Black,
        shape = RoundedCornerShape(20.dp)
    ) {

        LaunchedEffect(Unit) {
            while (true) {
                withFrameNanos {
                    prevTime = time
                    time = it
                }
            }
        }

        if (flickering2) {
            if (time - startTime > 15500000000) { //note, that startTime has been updated above
                flickering2 = false
            }
        }

        rocket.move(time, prevTime)

        Box(Modifier.fillMaxSize()) {

            snow(time, prevTime, snowFlakes, startTime)

            starrySky(stars)

            rocket.draw()

        }
    }
}
Repository: JetBrains/compose-multiplatform
File: gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/integration/KotlinCompatibilityTest.kt (Kotlin)

Code before:

class KotlinCompatibilityTest : GradlePluginTestBase() {
    @Test
    fun testKotlinMpp_1_7_10() = testMpp("1.7.10")

    @Test
    fun testKotlinJsMpp_1_7_10() = testJsMpp("1.7.10")

    @Test
    fun testKotlinMpp_1_7_20() = testMpp("1.7.20")

    @Test
    fun testKotlinJsMpp_1_7_20() = testJsMpp("1.7.20")

    @Suppress("RedundantUnitExpression")
    @Test
    fun testKotlinJs_shows_warning_for_androidx_compose_compiler() = testProject(
        TestProjects.customCompilerArgs, defaultTestEnvironment.copy(
            kotlinVersion = "1.8.22",
            composeCompilerPlugin = "\"androidx.compose.compiler:compiler:1.4.8\"",
            composeCompilerArgs = "\"suppressKotlinVersionCompatibilityCheck=1.8.22\""
        )
    ).let {
        it.gradle(":compileKotlinJs").checks {
            check.taskSuccessful(":compileKotlinJs")
            check.logContains("WARNING: You are using the 'androidx.compose.compiler' compiler plugin in your Kotlin multiplatform project.")
        }
        Unit
    }

    private fun testMpp(kotlinVersion: String) = with(
        testProject(
            TestProjects.mpp,
            testEnvironment = defaultTestEnvironment.copy(kotlinVersion = kotlinVersion)
        )
    ) {
        val logLine = "Kotlin MPP app is running!"
        gradle("run").checks {
            check.taskSuccessful(":run")
            check.logContains(logLine)
        }
    }

    private fun testJsMpp(kotlinVersion: String) = with(
        testProject(
            TestProjects.jsMpp,
            testEnvironment = defaultTestEnvironment.copy(kotlinVersion = kotlinVersion)
        )
    ) {
        gradle(":compileKotlinJs").checks {
            check.taskSuccessful(":compileKotlinJs")

Review comment (suggestion):
Maybe using a const from the main source set could be more convenient in case anyone wants to edit the message.

Code after:

class KotlinCompatibilityTest : GradlePluginTestBase() {
    @Test
    fun testKotlinMpp_1_7_10() = testMpp("1.7.10")

    @Test
    fun testKotlinJsMpp_1_7_10() = testJsMpp("1.7.10")

    @Test
    fun testKotlinMpp_1_7_20() = testMpp("1.7.20")

    @Test
    fun testKotlinJsMpp_1_7_20() = testJsMpp("1.7.20")

    private fun testMpp(kotlinVersion: String) = with(
        testProject(
            TestProjects.mpp,
            testEnvironment = defaultTestEnvironment.copy(kotlinVersion = kotlinVersion)
        )
    ) {
        val logLine = "Kotlin MPP app is running!"
        gradle("run").checks {
            check.taskSuccessful(":run")
            check.logContains(logLine)
        }
    }

    private fun testJsMpp(kotlinVersion: String) = with(
        testProject(
            TestProjects.jsMpp,
            testEnvironment = defaultTestEnvironment.copy(kotlinVersion = kotlinVersion)
        )
    ) {
        gradle(":compileKotlinJs").checks {
            check.taskSuccessful(":compileKotlinJs")
        }
    }
}