Skip to content

[Gradle] Distinguish non-Unit-return false positives from real instability in stability dump #205

Description

@egorikftp

Is your feature request related to a problem?

Every @Composable function that returns a non-Unit value is reported as skippable: false and restartable: false in the .stability dump, no matter how stable its parameters are. This is expected Compose compiler behavior — the compiler only generates skip/restart group logic for Unit-returning composables, since skipping means "do nothing and return", which isn't possible when a value must be produced. It is not a real stability regression.

The dump gives no way to distinguish this compiler-inherent case from an actual problem (unstable/unknown params). Minimal repro:

@Composable
private fun borderColor(enabled: Boolean): Color =
    if (enabled) Color.Red else Color.Gray

Generated dump (unstableOnly = true):

@Composable
private fun com.example.borderColor(enabled: kotlin.Boolean): androidx.compose.ui.graphics.Color
  skippable: false
  restartable: false
  params:
    - enabled: STABLE (primitive type)

enabled is STABLE and there are no other params, yet the function is still flagged — purely because it returns Color instead of Unit. In a large codebase this produces a steady stream of dump entries that reviewers have to manually re-verify are non-issues every time, and CI/baseline diffing can't tell them apart from genuine regressions.

Describe the solution you'd like:

Give consumers a way to separate "flagged only because of non-Unit return type, params otherwise stable" from real instability, for example:

  • Per-entry metadata, e.g. nonSkippableReason: NON_UNIT_RETURN_TYPE, when skippable/restartable are false solely because the return type isn't Unit and every param is STABLE.
  • Or a stabilityValidation { } option (alongside the existing unstableOnly) such as ignoreNonUnitReturnFalsePositives = true that excludes these entries from the dump entirely.

Describe alternatives you've considered:

We currently post-process the generated .stability file ourselves in the consuming Gradle module: parsing the skippable: / restartable: / params: lines with regex to strip out entries matching this pattern, and deleting the file once nothing else is left. It works, but it's brittle text-parsing against a format the plugin explicitly says not to hand-edit, and it will silently break if the dump format ever changes.

Environment

  • com.github.skydoves.compose.stability.analyzer plugin: 0.13.0
  • Kotlin / Compose compiler plugin: 2.4.10
  • Gradle: 9.5.0

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions