Generate the Swift shim, C header and Scala externs from one widget description #7

Open
opened 2026-09-28 21:57:05 -07:00 by rleibman · 0 comments
Owner

The single largest cost left in the project, and the thing the MVP is gated on — see docs/12-component-status.md §12.7, item 1.

Measured when the Apple renderer landed: 11.0 non-comment Swift lines per exported function, against S3's 5.8 estimate from a 21-function spike, and now doubled because there are two shims with nothing but a C header and a self-test keeping them in step. docs/09 projects the v1 catalogue at ~240 functions, i.e. roughly 5 200 lines of Swift maintained in duplicate. The catalogue is 9 of 32 widgets done; hand-writing the other 23 twice is not a reasonable way to spend the effort.

That is why docs/decisions.md upgraded §7.6's generate-from-one-description recommendation from desirable to necessary before the catalogue grows.

Scope

One widget description (Scala source or a small data file, in modules/ or a new tools/ module) from which three artefacts are generated:

  1. scalaui_apple.h — types and functions in separate headers, because @_cdecl collides with its own C declaration (S3).
  2. Shim+AppKit.swift and Shim+UIKit.swift.
  3. The Scala extern bindings / kind codes in renderer-apple.

The description must express per-platform widget choice, not only per-platform naming — checkbox vs. switch is the motivating case, and docs/09 calls this out specifically.

Constraints already established, which the generator must not violate

  • No struct-by-value returns from callbacks; CGRect stays flattened to four doubles.
  • No #if os() inside a shim function body — per-file separation, which S3 got right.
  • The handle table is ConcurrentHashMap + AtomicLong, never synchronized (S9).

How to verify — this part is testable on Linux. The existing hand-written shims are the golden files: run the generator over a description of the nine widgets that exist today and diff against Shim+AppKit.swift and Shim+UIKit.swift. Modulo formatting and comments it should reproduce them; every divergence is either a generator bug or an inconsistency in the hand-written shim worth knowing about. Only after that does it need a Mac, to confirm the generated output still compiles and the 23-check self-test still passes.

Note for whoever picks this up: the generator itself is ordinary Scala and its golden-file test needs no Apple hardware, so it can be built on the Linux box and handed over compiling. Say so if you would rather it were done that way.

**The single largest cost left in the project, and the thing the MVP is gated on** — see `docs/12-component-status.md` §12.7, item 1. Measured when the Apple renderer landed: **11.0 non-comment Swift lines per exported function**, against S3's 5.8 estimate from a 21-function spike, and now **doubled** because there are two shims with nothing but a C header and a self-test keeping them in step. `docs/09` projects the v1 catalogue at ~240 functions, i.e. roughly **5 200 lines of Swift maintained in duplicate**. The catalogue is 9 of 32 widgets done; hand-writing the other 23 twice is not a reasonable way to spend the effort. That is why `docs/decisions.md` upgraded §7.6's generate-from-one-description recommendation from *desirable* to *necessary before the catalogue grows*. **Scope** One widget description (Scala source or a small data file, in `modules/` or a new `tools/` module) from which three artefacts are generated: 1. `scalaui_apple.h` — types and functions in separate headers, because `@_cdecl` collides with its own C declaration (S3). 2. `Shim+AppKit.swift` and `Shim+UIKit.swift`. 3. The Scala `extern` bindings / kind codes in `renderer-apple`. **The description must express per-platform widget *choice*, not only per-platform naming** — checkbox vs. switch is the motivating case, and `docs/09` calls this out specifically. **Constraints already established, which the generator must not violate** - No struct-by-value returns from callbacks; `CGRect` stays flattened to four doubles. - No `#if os()` inside a shim function body — per-*file* separation, which S3 got right. - The handle table is `ConcurrentHashMap` + `AtomicLong`, never `synchronized` (S9). **How to verify — this part is testable on Linux.** The existing hand-written shims are the golden files: run the generator over a description of the nine widgets that exist today and diff against `Shim+AppKit.swift` and `Shim+UIKit.swift`. Modulo formatting and comments it should reproduce them; every divergence is either a generator bug or an inconsistency in the hand-written shim worth knowing about. Only after that does it need a Mac, to confirm the generated output still compiles and the 23-check self-test still passes. **Note for whoever picks this up:** the generator itself is ordinary Scala and its golden-file test needs no Apple hardware, so it can be built on the Linux box and handed over compiling. Say so if you would rather it were done that way.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
rleibman/scala-ui#7
No description provided.