build: update Metalava to 0.5.0 - #3935
Conversation
0.4.0-alpha03's Kotlin-metadata reading is out of date: it will silently drop the throws clause it synthesizes from @throws once the repo's Kotlin compiler moves past 2.0.x (see the follow-up Kotlin bump), so this needs to land first. 0.5.0's own api*.txt diff is large (~3000 lines across 6 files) but fully audited: every change is either Metalava now correctly excluding @InternalRevenueCatAPI/@JvmSynthetic members that were leaking into the tracked surface before (e.g. Offering.getPaywall()/getPaywallComponents(), which back internal-only properties), a method->property rendering fix that also corrects several value-class-typed members previously shown with their erased type (e.g. AdMediatorName mediatorName was rendered as String mediatorName), or new informational @InaccessibleFromKotlin/ @KotlinOnly annotations on members that were otherwise unchanged. No real, currently-supported public API was removed; verified with a name-level diff across all 6 files plus javap spot checks on the actual compiled bytecode.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 7f0414d. Configure here.
tonidero
left a comment
There was a problem hiding this comment.
I wonder if we should fix the InaccessibleFromKotlin APIs to either remove them or expose them to kotlin... But I guess that would be a breaking change 🥴 So yeah, let's keep as is. Amazing job!
Not really, those are stuff like |
Metalava 0.5.0 started picking up AGP's generated BuildConfig, which is not part of the published SDK contract. Two of its fields make the dump non-deterministic across machines and unrelated changes: ENABLE_EXTRA_REQUEST_LOGGING is read from local.properties (git-ignored) and BILLING_CLIENT_VERSION embeds the Billing Client version, so an unrelated dependency bump would force an api*.txt regeneration. Excludes the generated buildConfig source dirs from the two modules that enable buildConfig. Note the plugin subtracts excludedSourceSets as an exact FileCollection, not by prefix, so the variant-specific dirs have to be listed individually rather than their parent.

Part of the AGP 9 upgrade pre-work, split out standalone because it doesn't need the Kotlin bump to justify it and shouldn't be entangled with it.
throwsclause it synthesizes from@Throwsonce the repo's Kotlin compiler moves past 2.0.x (a follow-up PR bumps Kotlin), so this needs to land ahead of that.api*.txtdiff is large but fully audited: every change is either correctly excluding@InternalRevenueCatAPI/@JvmSyntheticmembers that were leaking into the tracked API surface before, amethod→propertyrendering fix that also corrects several value-class-typed members previously shown with their erased type, or new informational@InaccessibleFromKotlin/@KotlinOnlyannotations on members that were otherwise unchanged.@InaccessibleFromKotlin: the member is callable from Java but not from Kotlin source. Shows up on the JVM getter Kotlin auto-generates for its own properties, since Kotlin only ever calls those via property syntax, never the raw getter name.@KotlinOnly: the member is callable from Kotlin but not meaningfully from Java. Shows up on@JvmSyntheticmethods (already hidden from Java) and@Composablefunctionsjavapspot checks against the actual compiled bytecode.BuildConfig, which 0.5.0 started pulling into the dumps (thanks @cursor). It isn't part of the SDK contract, and it made the dump non-deterministic:ENABLE_EXTRA_REQUEST_LOGGINGcomes from the git-ignoredlocal.properties, andBILLING_CLIENT_VERSIONwould force anapi*.txtregeneration on any unrelated Billing Client bump. Verified by flipping that flag locally:api-check.shstays clean now, where before it would have produced a diff.Checklist
purchases-iosand hybridsAgent description
Motivation
Part of the AGP 9 upgrade, split into small independently-shippable PRs, and further split out on
its own from the planned Kotlin 2.2.10 bump: Metalava doesn't need Kotlin to move to be worth
upgrading, and keeping it separate makes each PR's diff explainable on its own.
The concrete problem:
me.tylerbwong.gradle.metalava0.4.0-alpha03 can't fully parse the metadataformat a Kotlin 2.2 compiler produces. Confirmed by testing the pairing directly: with Kotlin
still at 2.0.21 (this PR), 0.4.0-alpha03 has no issue and
getPackage()'sthrows java.util.NoSuchElementExceptionclause round-trips unchanged. Once Kotlin moves to 2.2.x (aseparate, later PR), the old Metalava starts emitting "Module was compiled with an incompatible
version of Kotlin... expected version is 2.0.0" and silently drops that clause from the tracked
signature file, even though the real compiled bytecode is unaffected (confirmed with
javap).Landing this first avoids that combination ever existing on
main.0.5.0's diff turned out to be much bigger than that one fix, so it needed its own audit before
being accepted:
@InternalRevenueCatAPI-annotated properties (e.g.Offering.getPaywall()/getPaywallComponents()) are now correctly excluded from the trackedsurface. The old Metalava was leaking them in despite the
hiddenAnnotationsconfig alreadytelling it to hide
@InternalRevenueCatAPI.@JvmSyntheticmembers (never callable from Java to begin with) are now also excluded, ratherthan tracked as if they were part of the Java-facing API surface.
method→propertyrendering changes also fix the underlying type shown forvalue-class-typed members, which the old Metalava rendered using their erased type (e.g.
AdMediatorName mediatorNamewas shown asString mediatorName).@InaccessibleFromKotlin/@KotlinOnlyannotations appear on members that are otherwiseunchanged; these document pre-existing Kotlin/Java accessibility asymmetry (e.g. a Kotlin
property's JVM-visible getter form can't be called from Kotlin source, only Java; a
@JvmSyntheticor@Composablemember can't meaningfully be called from Java).Verified none of this drops real, currently-supported API: extracted a name-level diff of every
method/constructor/property/field across all 6 changed files and confirmed every apparent removal
resolves to one of the categories above, with no unexplained disappearance.
Description
gradle/libs.versions.toml:metalava0.4.0-alpha03 → 0.5.0.purchases/api-defauts.txt,purchases/api-entitlement.txt,ui/revenuecatui/api.txt,feature/admob/api.txt,feature/galaxy/api.txt,ui/debugview/api.txt: regenerated viascripts/api-dump.sh, audited as described above.Tested:
scripts/api-check.shclean,:purchases/:ui:revenuecatuiunit tests green,detektAlland
lintclean, all with Kotlin still at 2.0.21 and Poko at 0.17.2 (unchanged).Note
Low Risk
Changes are limited to the Metalava plugin version and regenerated API signature files; runtime SDK code is untouched, with no intended removal of supported public API per the PR audit.
Overview
Bumps Metalava from
0.4.0-alpha03to0.5.0ingradle/libs.versions.tomland regenerates the trackedapi*.txtsignatures (corepurchases, AdMob, Galaxy, etc.). This is tooling-only for published API tracking; compiled SDK behavior is unchanged.The signature files change heavily because 0.5.0 models Kotlin/Java interop more accurately, not because supported public API was intentionally removed:
@KotlinOnlyon@JvmSyntheticcoroutines and AdMob helpers;@InaccessibleFromKotlinon JVM getters for Kotlin properties.@JvmSyntheticand@InternalRevenueCatAPImembers (e.g. internal listeners, checkpoint slot) drop out of the tracked surface;Offeringpaywall-related ctor parameters no longer appear as ordinary public API in the dump.AdFormat,AdMediatorName, andAdRevenuePrecisioninstead of erasedStringtypes;@Throwson suspend helpers is preserved in the signatures (important before a future Kotlin 2.2 bump).sealed exhaustiveclasses, fullerSubscriptionOptionsListAPI, new deprecated typealiases (AdMob reward verification; purchase callback aliases in core), and serialization@SerialNameon some virtual-currency properties.Purchases.adTrackerappears in the core API dump as the Kotlin-facing property for ad tracking (replacing previously tracked synthetic getter noise).Reviewed by Cursor Bugbot for commit ce4128d. Bugbot is set up for automated code reviews on this repo. Configure here.