Skip to content

After upgrading kotlin 2.3.21 -> 2.4.10, compose branch coverage drop down #2210

Description

@neworld

Steps to reproduce

  1. Checkout repo
  2. Run ./gradlew test jacocoTestReport
  3. Open build/reports/jacoco/test/html/org.example/index.source.html
Image 4. Change kotlin version to 2.3.21 5. Run `./gradlew test jacocoTestReport` and refresh browser Image

Expected behaviour

Give same amount of branch coverage

Actual behaviour

Increases number of branches, but coverage decreases

Extra info

Kotlin upgrade in our product cause significant coverage drop, which is enough to prevent upgrade to kotlin. Sometimes it was +120 branches per composable. I tried to make small as possible repro.

I wasn't sure at first whether this is the right place to report it, but similar problems were fixed here in #1616 and #1911. Let me know if it belongs elsewhere.

I have no idea if it even makes sense, but AI explained it like this:

AI Analysis

The difference is in the lambda memoization check inside the CC(remember) region (between sourceInformationMarkerStart/End). javap -c of ExampleKt.example, the check for the captured state parameter:

Kotlin 2.3.21 — an unconditional changedInstance() call, no extra branches, which roughly corresponds to:

val invalidated = $composer.changedInstance(state) or
        ($changed and 0b1110000 == 0b0100000)  // onDone

Kotlin 2.4.10 — the same capture now consults the caller-provided $changed bits before falling back to changedInstance(), adding three conditionals, which roughly corresponds to:

val invalidated = ($changed and 0b0001110 == 0b0000100 ||
        ($changed and 0b0001000 != 0 && $composer.changedInstance(state))) or
        ($changed and 0b1110000 == 0b0100000)  // onDone

The result is used as if (invalidated || rememberedValue === Empty) { create and cache the lambda } else { reuse cached }. Some of these branch outcomes depend on bits computed by the caller, so they cannot be reliably exercised by tests. It would be great if KotlinComposeFilter also filtered this pattern.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

  • Status
    Awaiting triage

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions