chore(deps): update dependency com.github.skydoves.compose.stability.analyzer to v0.13.0 - #208
chore(deps): update dependency com.github.skydoves.compose.stability.analyzer to v0.13.0#208renovate[bot] wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
🤖 Android CI Summary
Step Results:
- Debug Build: ⏭️ Skipped (0s)
- Code Style Check: ❌ Failure (0s)
- Compose Stability: ⏭️ Skipped (0s)
Total Time: 0s
See the Actions Log for details.
c9869c3 to
2ca3d1f
Compare
There was a problem hiding this comment.
🤖 Android CI Summary
Step Results:
- Debug Build: ⏭️ Skipped (0s)
- Code Style Check: ❌ Failure (0s)
- Compose Stability: ⏭️ Skipped (0s)
Total Time: 0s
See the Actions Log for details.
2ca3d1f to
c7faf8b
Compare
There was a problem hiding this comment.
🤖 Android CI Summary
Step Results:
- Debug Build: ❌ Failure (0s)
- Code Style Check: ✅ Success (2m 31s)
- Compose Stability: ⏭️ Skipped (0s)
Total Time: 2m 31s
See the Actions Log for details.
c7faf8b to
44ec34d
Compare
There was a problem hiding this comment.
🤖 Android CI Summary
Step Results:
- Debug Build: ❌ Failure (0s)
- Code Style Check: ✅ Success (2m 48s)
- Compose Stability: ⏭️ Skipped (0s)
Total Time: 2m 48s
See the Actions Log for details.
44ec34d to
0a24856
Compare
There was a problem hiding this comment.
🤖 Android CI Summary
Step Results:
- Debug Build: ❌ Failure (0s)
- Code Style Check: ✅ Success (2m 33s)
- Compose Stability: ⏭️ Skipped (0s)
Total Time: 2m 33s
See the Actions Log for details.
0a24856 to
257586c
Compare
There was a problem hiding this comment.
🤖 Android CI Summary
Step Results:
- Debug Build: ❌ Failure (0s)
- Code Style Check: ✅ Success (2m 43s)
- Compose Stability: ⏭️ Skipped (0s)
Total Time: 2m 43s
See the Actions Log for details.
…analyzer to v0.13.0
257586c to
8cb8c99
Compare
There was a problem hiding this comment.
🤖 Android CI Summary
Step Results:
- Debug Build: ❌ Failure (0s)
- Code Style Check: ✅ Success (2m 29s)
- Compose Stability: ⏭️ Skipped (0s)
Total Time: 2m 29s
See the Actions Log for details.
This PR contains the following updates:
0.6.4→0.13.0Release Notes
skydoves/compose-stability-analyzer (com.github.skydoves.compose.stability.analyzer)
v0.13.0Compare Source
Changed
Bumped Kotlin to 2.4.10 (from 2.4.0). Use the same Kotlin version as this library. The compiler plugin, runtime, Gradle plugin, Lint rules and IntelliJ plugin all build against 2.4.10, and every published target still compiles. No stability verdicts change: the Compose compiler's
analysis/Stability.ktis byte-identical between 2.4.0 and 2.4.10, and re-runningstabilityDumpon the sample app produced no diff, so committed.stabilitybaselines do not need refreshing for this bump alone.2.4.10's one Compose compiler fix, b/522127447 ("classes previously inferred
stablenow reportedruntime/Uncertain"), is inComposableFunctionBodyTransformer, not in stability inference. It restores the cast target type's stability when an argument is passed through aCAST/IMPLICIT_CAST, which affects the$changedmetadata Compose computes per call-site argument. This analyzer reports the stability of a parameter's declared type, so the fix is orthogonal to whatstabilityDumpand the IDE surface.allowIncrementalDisablingis now scoped per project. Previously a stability task anywhere in the build disabled Kotlin incremental compilation in every project applying the plugin. Each project now decides based on its own task paths../gradlew stabilityDump,stabilityCheckandcheckbehave identically; only a path-qualified invocation such as./gradlew :app:stabilityCheckdiffers, and there it is more correct — that task only reads:app's ownstability-info.json.The implicit
:stability-runtime/:stability-lintproject wiring is gone. The plugin used to callrootProject.findProject(...)and, when a module with either path existed, add thatProjectobject as a dependency notation. That only ever resolved inside this repository, silently hijacked any consumer build containing a module with those names, and is deprecated in Gradle 9 (an error in Gradle 10). The published Maven coordinates are now always used; lint checks continue to ship inside the runtime AAR'slint.jar.The compiler plugin's
projectDependenciesoption is deprecated and ignored. It stays registered so builds that pin the compiler artifact independently keep working, and will be removed in 1.0.Fixed
--isolated-projects/org.gradle.isolated-projects=true(incubating since Gradle 9.7) configure and compile cleanly. Two violations are gone:collectProjectDependencies()walkedrootProject.allprojectsand read every sibling project'sgroup,projectDirandpath— including a filesystem scan of each sibling's sources — on every Kotlin compile-task configuration.gradle.taskGraph.allTasks, which observes tasks created by other projects.UNSTABLE: cross-module detection used to match a parameter type's fully-qualified name against package prefixes guessed from sibling projects, and the first guess was the sibling's Gradlegroup. With the very commonallprojects { group = "com.example" }, that prefix also matched the module's owncom.example.*types, marking them unstable. Detection now relies solely on the IR declaration origin (IR_EXTERNAL_DECLARATION_STUB), which is the signal the Compose compiler itself uses and already covered every cross-module case. If you were affected, run./gradlew stabilityDumpto refresh your baseline — with the defaultfailOnStabilityChange = true,stabilityCheckwill otherwise fail on the resultingUNSTABLE → STABLEtransitions.UNSTABLE (has mutable properties or unstable members)even when they had none. They now readUNSTABLE (cross-module type without @Stable/@Immutable). Reasons are not compared bystabilityCheck, so this alone cannot fail a build.@StabilityInferredis honoured only on declarations from outside the module being compiled, where it is baked into the binary and is the intended cross-module channel. On a class in the module being compiled it exists only after the Compose compiler plugin's IR lowering has run, and whether that happens before or after this plugin is decided by the resolved order ofkotlinCompilerPluginClasspath. The same source could therefore reportSTABLEin one build andRUNTIMEin another. Our own property analysis is authoritative for source classes, and ignoring the annotation there also matches the IDE plugin, which only ever sees source.Note for contributors
The sample
:appmodule now resolves the runtime from its published coordinate like any consumer, instead of from the in-build:stability-runtimeproject. Two consequences:./gradlew :stability-runtime:publishToMavenLocalmust run before:apppicks up local runtime edits, and after a version bump:appcannot build until the new version is published to Maven Local.That change also shifted where the analyzer's IR pass sits relative to the Compose compiler plugin's IR lowering — plugin order follows the resolved
kotlinCompilerPluginClasspathorder, and the in-build project dependency used to push the analyzer behind Compose. Consumers were always on the other side of that boundary, so nothing changes for them, butapp/stability/*.stabilitywas regenerated and now records what a real consumer sees: composable-lambda parameters render in their pre-lowering form (@[Composable] ComposableFunction0<T>rather thanFunction2<Composer, Int, T>), andIcon.normalSealedClassreportsRUNTIMEinstead ofSTABLEbecause@StabilityInferredis not yet attached to same-module classes when the pass runs. The analysis no longer depends on that ordering — see the@StabilityInferredentry under Fixed — so the regenerated baseline is now stable regardless of how the plugin classpath resolves.v0.12.0Compare Source
Added
linuxX64,linuxArm64andmingwX64are now published, so applying the Gradle plugin to a KMP project with Linux or Windows native targets no longer fails to resolve the runtime.recompositionNanoTime(): the public monotonic clock behindRecompositionTracker.recordDuration, used by compiler-generated timing code. Compiler-generated code prefers it and falls back toSystem.nanoTime()when the runtime predates it.Fixed
@TraceRecompositionnow works on every published target (#197): tracing was silently a no-op on iOS, macOS, Linux, Windows, JS and Wasm. The compiler plugin skips instrumentation when it cannot resolverememberRecompositionTracker, and that entry point only existed for Android and JVM. It moved tocommonMain, so every target the runtime publishes gets parameter tracing, tags, thresholds and per-recomposition timing. Internal state write-site capture (the← onClick (Screen.kt:42)suffix) still needs the Compose Snapshot observer and stays Android/JVM-only.0.00msoutside Android and JVM (#197):currentNanoTime()returned a hardcoded0on JS, Wasm and all native targets. It now readskotlin.time.TimeSource.Monotonicthere, which maps toperformance.now()andgetTimeNanos().Changed
jvmCommon(JVM, Android),web(JS, Wasm) andnative(Apple, Linux, MinGW). A new target now inherits a working set of actuals instead of silently losing the entry points the compiler plugin resolves.skiaMainbecamenativeMain.ConcurrentHashMapon JVM/Android, a copy-on-write map behind an atomic compare-and-set on native, and a plain map on JS/Wasm where Kotlin runs single-threaded.rememberRecompositionTrackertarget theRememberRecompositionTrackerKtJVM facade. The previousRememberRecompositionTracker_jvmKtandRememberRecompositionTracker_androidKtfacades are retained as hidden delegates, so binaries instrumented by 0.11.x and earlier keep linking. No action needed when upgrading.v0.11.1Compare Source
Fixed
until-buildupper bound so the plugin installs on IntelliJ IDEA / Android Studio 2026.2 and later, and K2 Analysis API access now falls back to PSI on any linkage error so it stays resilient across IDE versions (#191).ignoreNonRegressiveChanges— a new composable whose parameters are all stable is no longer reported when it is non-restartable or opts out of skipping (@NonSkippableComposable, a non-Unitreturn,inline, etc.). Only composables that introduce an unstable parameter are reported (#192).v0.11.0Compare Source
Added
composeStabilityAnalyzer { stabilityConfigurationFiles }option, so configured types are treated as stable everywhere the compiler runs —stabilityDump/stabilityCheck, trace-all, and the IDE data. This fixes a data class that wraps a configured type being reported unstable bystabilityCheck(#176). The oldstabilityValidation { stabilityConfigurationFiles }option is deprecated in favor of the top-level one.Fixed
@NonRestartableComposable,@ReadOnlyComposable,@ExplicitGroupsComposable,inlinefunctions, and composables returning a non-Unitvalue are no longer reported as restartable/skippable, matching the Compose compiler.stabilityChecknow also detectsrestartable/skippableregressions.val x get() = ...) no longer makes its class unstable, in both the compiler and the IDE.varargparameter compiles to an array, so it is no longer reported as its (often stable) element type.stabilityDump/stabilityChecknow findstability-info.jsonunder the KMP Android compile task pathcompile<Variant>KotlinAndroid(#183).v0.10.0Compare Source
Added
var→val(aborts if write usages exist), annotate with@Immutable/@Stable, add the type to the stability configuration file, and wrap call-site arguments inremember(keys) { ... }for silent-waste parameters (guarded by conservative safety rules and a preview dialog). New Doctor tool-window tab, Code → Run Stability Doctor action, and a settings group.@TraceRecomposition, so the Live Heatmap, Reality Check, and Stability Doctor get module-wide runtime data without manual annotations.composeStabilityAnalyzer { traceAll { enabled.set(true) // default: false (opt-in) threshold.set(2) // default: 2 — skips the initial-composition burst variants.set(listOf("debug")) // default: ["debug"]; never applies to tests } }@TraceRecompositionannotations keep their own tag/threshold; previews, inline/readonly/non-restartable composables, and property getters are excluded automatically.(fq: com.example.UserProfile)and(auto)tokens (backward compatible with older parsers), so the IDE attributes runtime data precisely even when composables share a simple name across packages.RecompositionEventgains additivefqNameandisAutoTracedfields.Fixed
gradle-apiascompileOnlyand isolates all AGP types behind an Android-only registrar, so KMP/JVM projects without AGP work and AGP 8.x projects no longer get AGP 9 on their buildscript classpath.kotlinx.datetime.LocalTime?matches akotlinx.datetime.LocalTimeconfig entry.Changed
ComposeStabilityAnalyzer.setEnabled(false), trackers allocate nothing (early exits before any event construction); the tracker cache is thread-safe and keyed by fully qualified name to avoid cross-package collisions.v0.9.0Compare Source
Added
ParameterStability.UNKNOWN— a fourth stability value for types whose stability cannot be determined statically (interfaces and non-final classes). Mirrors the Compose 2.4.0 compiler'sStability.Unknown.Changed
ProjectExtensionDescriptormechanism (KT-83341); the deprecatedIrPluginContext.referenceClass/referenceFunctionswere replaced with thefinderForSourceAPI.UNKNOWNstability rule — interfaces and non-final (open/abstract) classes now reportUNKNOWNinstead ofRUNTIME/UNSTABLE, matching the Compose 2.4.0 compiler. This includes anykotlin.Any?parameter (sinceAnyisopen). Skippability is unchanged (these types were already non-skippable), but the rule will produce diffs in committed.stabilitybaselines — run./gradlew stabilityDumpto refresh them. ASTABLE → UNKNOWNtransition is reported as a regression bystabilityCheck.v0.8.0Compare Source
Added
equals-equal instance every frame (silent waste). Grades appear in editor inlays, hover tooltips (predicted vs. actual), and a new Reality tool-window tab with a wasted-recomposition tally.@TraceRecomposition(traceStates = true), a Compose Snapshot write observer records where each internal state was mutated, e.g.[state] counter: Int changed (0 → 1) ← onClick (Screen.kt:42).@Composable→ Blame this Recomposition to walk the reverse call graph and see where each argument's value originates, in a new Blame tool-window tab.ParameterChange.referenceChanged(runtime API) — distinguishes anequals-equal value delivered as a new instance (a strong-skipping===miss) from a genuine value change; this powers the Reality Check.Changed
stability-runtimenow declares acompileOnlydependency on the Compose runtime for its Android/JVM source sets (used only by the state-write observer); all other Kotlin Multiplatform targets remain Compose-free via no-opactuals.v0.7.5Compare Source
Added
allowIncrementalDisablingconfiguration switch (Issue #156, #158)stabilityValidation.allowIncrementalDisablingproperty (default:true) to control whether the plugin may disable Kotlin's incremental compilation when stability validation tasks are in the build graphfalseto opt out and keep incremental compilation enabled even when runningstabilityDump/stabilityCheckChanged
2026.04.01, Android Gradle Plugin8.13.2, Lint API32.1.12.2.0, kotlinx.serialization1.11.0, Spotless7.0.2, Nexus publish plugin0.36.0, androidx Activity1.13.0, runtime annotation1.11.0KotlinCompile-dependent task now writes to a dedicatedbuild/stability/<name>/directory to prevent cross-variant clobbering. Consumers (Stability Explorer,stabilityDump/stabilityCheck) read from both the new and legacy layouts for backward compatibility.Fixed
val→var). The plugin now disables incremental compilation whilestabilityDump/stabilityCheckare in the task graph so stability results stay accurate (can be opted out viaallowIncrementalDisabling).v0.7.4Compare Source
Added
@TraceRecompositionnow measures composable recomposition duration viaSystem.nanoTime()IR injection[Recomposition #​3] UserCard (2.30ms)RecompositionEvent.durationNanosfield added for custom logger consumptionexpect/actual currentNanoTime()(Android/JVM supported, other platforms gracefully skip)[param]and[state]prefixed lines and duration from log outputChanged
com.github.johnrengelman.shadowtocom.gradleup.shadow)v0.7.3Compare Source
Added
stabilityDump(Issue #130, PR #105)stabilityConfigurationFilesnow applies to bothstabilityDumpandstabilityChecktasksskippableflag is recalculated based on resolved parameter stabilityunstableOnlyoption for stability baseline (Issue #128)unstableOnlyoption: when enabled, only unstable composables are included in the baseline filestabilityCheckoutput for new composables shows each parameter's stability status@TraceRecomposition(Issue #89)traceStatesannotation parameter:@TraceRecomposition(traceStates = true)mutableStateOf,mutableIntStateOf,derivedStateOfand other Compose state changesIrLocalDelegatedPropertyIR analysis[state]prefix, parameter changes with[param]prefixFixed
ignoredPackagesnow consistently respected duringstabilityCheck(Issue #129)stabilityDumpbut still detected as "new composable" duringstabilityCheck@Optionalannotation added tostabilityConfigurationFilestask input (PR #105)adb.exedetection on Windows for the Heatmap feature%LOCALAPPDATA%\Android\Sdk)wherecommand instead ofwhichon Windows for PATH lookupChanged
StabilityComparison.kt(PR #105)StabilityConfigParser.kt(PR #105)v0.7.2Compare Source
[0.7.2] - 2026-04-02
Added
stabilityDump(Issue #130, PR #105)stabilityConfigurationFilesnow applies to bothstabilityDumpandstabilityChecktasksskippableflag is recalculated based on resolved parameter stabilityunstableOnlyoption for stability baseline (Issue #128)unstableOnlyoption: when enabled, only unstable composables are included in the baseline filestabilityCheckoutput for new composables shows each parameter's stability statusFixed
ignoredPackagesnow consistently respected duringstabilityCheck(Issue #129)stabilityDumpbut still detected as "new composable" duringstabilityCheck@Optionalannotation added tostabilityConfigurationFilestask input (PR #105)adb.exedetection on Windows for the Heatmap feature%LOCALAPPDATA%\Android\Sdk)wherecommand instead ofwhichon Windows for PATH lookupChanged
StabilityComparison.kt(PR #105)StabilityConfigParser.kt(PR #105)v0.7.1Compare Source
Fixed
NoSuchMethodErrorforIrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUBandDEFINEDconstantsComposableStabilityCheckerfromFirSimpleFunctionCheckertoFirCallableDeclarationCheckerto handleFirSimpleFunction→FirNamedFunctionrenameChanged
v0.7.0Compare Source
Added
@Composablefunction and select "Analyze Recomposition Cascade" to trace downstream composables affected by recomposition@TraceRecompositionevents from ADB logcat and aggregates per-composable datarunPluginVerifiertask for automated compatibility testingImproved
runCatchingpattern in cascade analyzerProgressIndicator.checkCanceled()v0.6.7Compare Source
Added
debugStabilityDump,releaseStabilityCheck) for Android projectsstabilityDump,stabilityCheck) still available for all variantsignoreNonRegressiveChangesoption: only flag stability regressions, ignore non-regressive changes (e.g., new stable parameters)allowMissingBaselineoption: allow stability checks to run even without an existing baseline filestabilityPatternToRegexto support*and**wildcard syntax in stability configuration filescom.datalayer.*,com.example.**Fixed
@StabilityInferredannotation now supported in Gradle plugin (Issue #102, PR #112)@StabilityInferred(parameters=0)are now correctly treated as stable duringstabilityDump/stabilityCheck@StabilityInferredwere incorrectly marked as UNSTABLE@NonRestartableComposableand@NonSkippableComposable(Issue #103, PR #111)@NonRestartableComposableor@NonSkippableComposableare now excluded from stability analysistypealias ComposableAction = @Composable () -> Unit) are now correctly recognized as stableImproved
nj2k.descendantsOfTypewith stablePsiTreeUtilAPI (PR #109)v0.6.6Compare Source
Fixed
stability-info.jsoninput file for up-to-date checks@Internalto@InputFilesannotation on input file property./gradlew stabilityDumpwould skip execution even when stability files were missingcleanor when stability output is deletedv0.6.5Compare Source
Added
quietCheck: Boolean = falseoption instabilityValidationconfigurationstabilityValidation { quietCheck.set(true) }Changed
Configuration
📅 Schedule: (UTC)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.