Skip to content

[Xamarin.AndroidX.Compose.Material3] Stop stripping @Composable functions on top of the existing 265 bound types #1417

@jonathanpeppers

Description

@jonathanpeppers

Unlike the other Compose NuGets, Xamarin.AndroidX.Compose.Material3Android already binds ~265 real types — it''s almost a real binding. The remaining gap is that every @Composable function (Text, Button, Card, Scaffold, ...) is stripped, so the public Material3 API is unreachable from C#.

The root cause is well-known: every @Composable overload has at least one inline-class parameter (Colorlong, Dp, TextStyle, ButtonColors, PaddingValues with inline Dp insets, ...). The Kotlin compiler hash-mangles the JVM method name (Button-XXXXX, BasicText-BpD7jsM, ...) and the binding generator currently drops or emits these with broken signatures. See NOTES.md surprises #1, #2 and open issues #2, #5, #9, #10 for the proven-by-experiment characterization, plus working raw-JNI fallbacks for Text/Button in compose-net.

Decision needed in this issue

Choose one of:

Option A (metadata only — short-term win): strip the Method-<hash> mangled siblings via per-overload <remove-node> so the rest of the Material3 API surfaces cleanly, and document the raw-JNI calling convention for the @Composable functions. Compose''s $default bitmask convention (set bit to "use the default") lets callers pass null for inline-class params with the function picking defaults — compose-net''s sample does exactly this for Button and Text.

Option B (generator change — long-term win): extend class-parse to demangle name-<hash> siblings as overloads of name and project inline-class params as their underlying primitive types (Colorlong, Dpfloat, etc.). This makes Button(...) / Text(...) directly callable from C# without raw JNI. Larger change; would benefit any Kotlin binding using inline classes, not just Compose.

I think Option A unblocks shipping; Option B is the right north star. Reasonable to land A now and track B separately.

Requested change (Option A)

  1. Drop the package-wide / @Composable-function strips from the Material3 recipe''s Transforms/Metadata.xml (whichever form they currently take — the existing 265 bound types prove it''s not a path="/api/package" strip; it''s more targeted).
  2. Add per-overload <remove-node> entries for the hashed Method-<hash> siblings using the pattern from ComposeNet.Bindings.Material3/Transforms/Metadata.xml.
  3. Document the raw-JNI calling pattern for the stripped overloads in the NuGet''s README (compose-net''s ComposeNet.Compose/ComposeBridges.cs has the working pattern).
  4. Regenerate api/PublicApi*.txt.

Sequencing

Depends on the Runtime issue (everyone does). Independent of the UI/Foundation issue but lands after for review-load reasons.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions