ffi 3.0: inst.method(args) DSL dispatch on #objc_class receivers
Implementation half of the cadence step started in the previous commit.
`lowerForeignMethodCall` for `#objc_class` / `#objc_protocol` runtimes
no longer bails; it routes through a new `lowerObjcMethodCall` helper
that derives the Obj-C selector from the sx method name and lowers to
`objc_msg_send` against the cached SEL slot (same intern path as
explicit `#objc_call`).
Default selector mangling (matches clang's keyword-method convention):
- Niladic (arity 0 excluding self): name verbatim. `length()` → "length".
- Arity ≥ 1: split the sx method name on `_`; each piece becomes a
keyword with a trailing `:`. `addObject(o)` → "addObject:";
`combine_and(a, b)` → "combine:and:";
`initWithFrame_options(f, o)` → "initWithFrame:options:".
Arity validation: keyword count (pieces from the `_`-split) must equal
call-site arity excluding self. Mismatch diagnoses at the call site
with a hint pointing at the forthcoming `#selector("...")` override
(Phase 3.2) for selectors that don't fit the underscore-split rule.
Mangling helper `deriveObjcSelector` and dispatch helper
`lowerObjcMethodCall` sit alongside `lowerForeignMethodCall`. The
existing fall-through diagnostic for non-JNI/non-Obj-C runtimes
remains for Swift (Phase 4 territory).
Tests `examples/ffi-objc-dsl-{01-niladic,02-one-arg,03-multi-keyword,
04-mismatch}.sx` snapshots flip from the pre-3.0 bail diagnostic
(exit=1) to working output (exit=0 for cases 01-03) and the specific
keyword-count mismatch diagnostic for case 04. Each test follows the
established pattern from `ffi-objc-call-08-multi-keyword.sx`:
synthesize a class at runtime via `objc_allocateClassPair` /
`class_addMethod`, declare a matching `#objc_class`, invoke the DSL
form. 163/163 tests; chess unaffected (JNI dispatch path untouched).
This commit is contained in:
@@ -472,23 +472,21 @@ JNI return + parameter type validation lives in lowering with source-
|
||||
spanned diagnostics; Call<T>Method coverage spans bool / s8 / s16 /
|
||||
u16 / s32 / s64 / f32 / f64 / pointer; varargs promotion is wired.
|
||||
|
||||
**Correction: Phase 3 step 3.0 had NOT landed at the time the previous
|
||||
checkpoint entry claimed it did.** [lower.zig's
|
||||
`lowerForeignMethodCall`](../src/ir/lower.zig#L4353) bails for any non-
|
||||
JNI runtime with `method calls on '{runtime}' runtime not yet supported
|
||||
(Phase 3/4)`; no commit in `git log` introduced an Obj-C DSL dispatch
|
||||
path; the planned regression files
|
||||
(`examples/ffi-objc-dsl-{01-niladic,02-one-arg,03-multi-keyword,04-mismatch}.sx`)
|
||||
didn't exist. As of this commit the four tests DO exist and snapshot
|
||||
the current bail diagnostic — they're the xfail half of the Phase 3.0
|
||||
cadence; the next commit implements the dispatch and the snapshots
|
||||
flip to the working output.
|
||||
Phase 3 step 3.0 landed (for real this time): `inst.method(args)` on
|
||||
an `#objc_class` / `#objc_protocol` receiver derives the selector via
|
||||
default mangling (niladic → name verbatim; arity ≥ 1 → split on `_`,
|
||||
each piece becomes a keyword with a trailing `:`) and lowers to
|
||||
`objc_msg_send` against the cached SEL slot. Arity mismatches diagnose
|
||||
at the call site with a remediation hint pointing at `#selector(...)`
|
||||
override (3.2). New helpers `deriveObjcSelector` and
|
||||
`lowerObjcMethodCall` at [lower.zig](../src/ir/lower.zig). Tests:
|
||||
`examples/ffi-objc-dsl-{01-niladic,02-one-arg,03-multi-keyword,04-mismatch}.sx`
|
||||
— landed previously as xfail-with-diagnostic, snapshots now flipped to
|
||||
working output (and the mismatch case to the specific keyword-count
|
||||
error).
|
||||
|
||||
Open work, in roughly the order they make sense:
|
||||
|
||||
- **Phase 3 step 3.0** — `inst.method(args)` DSL dispatch on
|
||||
`#objc_class` receivers with default selector mangling. The xfail
|
||||
tests are in place; next commit makes them green.
|
||||
- **Phase 3 step 3.1** — static call `Cls::class_method(args)` lowers
|
||||
to `#objc_call` on the class object (loaded via `objc_getClass` once
|
||||
and interned per module). Same pattern as 3.0 for the niladic /
|
||||
|
||||
Reference in New Issue
Block a user