Skip to content

Surface Kotlin object companions on Compose class bindings#1468

Draft
Copilot wants to merge 2 commits into
mainfrom
copilot/fix-kotlin-object-companion-surfacing
Draft

Surface Kotlin object companions on Compose class bindings#1468
Copilot wants to merge 2 commits into
mainfrom
copilot/fix-kotlin-object-companion-surfacing

Conversation

Copilot AI commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Kotlin object companions on a class weren't surfaced as a static Companion property on the binding, forcing consumers to bootstrap the singleton through raw JNI (FindClass + GetStaticFieldID("Companion") + GetStaticObjectField) to reach members like KeyboardOptions.Companion.Default.

Root cause

The binder keeps a class's companion peer named <Outer>.Companion. A nested type and a property can't share a name in C#, so the generator silently drops the static Companion field. Interface companions are unaffected — their peer is hoisted/renamed to <Outer>Companion, so they already surface (Alignment.Companion, ContentScale.Companion, … work today).

Changes

  • managedName rename to CompanionStatic on the colliding nested peer (the convention already used by the okio binding), letting the generator emit public static <Outer>.CompanionStatic Companion { get; }. Applied per type in Transforms/Metadata.xml:
    • foundation-android: KeyboardOptions
    • ui-text-android: TextStyle, TextDecoration, FontWeight, FontFamily, FontStyle
    • ui-graphics-android: Color
  • Regenerated PublicAPI.Unshipped.txt for those three packages (companion-only delta).
<attr path="/api/package[@name='androidx.compose.foundation.text']/class[@name='KeyboardOptions.Companion']"
      name="managedName">CompanionStatic</attr>
// Before: only reachable via raw JNI
// After:
var def = KeyboardOptions.Companion.Default;
var red = Color.Companion.Red;
var bold = FontWeight.Companion.Bold;

Scope notes

Targets class companions only — renaming an interface companion's peer would needlessly rename an already-public type. Several names from the issue need no change: Alignment/ContentScale already surface (interfaces), Modifier is a special interface companion, and MaterialTheme / most *Defaults are Kotlin objects with no companion. The same CompanionStatic rename generalizes to any future class with an object companion.

…ionStatic rename

Co-authored-by: jonathanpeppers <840039+jonathanpeppers@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix Kotlin object companion field visibility on outer class binding Surface Kotlin object companions on Compose class bindings Jun 10, 2026
Copilot AI requested a review from jonathanpeppers June 10, 2026 18:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Kotlin object companion field not surfaced on outer class binding (KeyboardOptions.Companion, TextStyle.Companion, ...)

2 participants