diff --git a/current/CHECKPOINT-EXTERN-EXPORT.md b/current/CHECKPOINT-EXTERN-EXPORT.md index 73a01db..3043f99 100644 --- a/current/CHECKPOINT-EXTERN-EXPORT.md +++ b/current/CHECKPOINT-EXTERN-EXPORT.md @@ -5,22 +5,34 @@ Companion to `current/PLAN-EXTERN-EXPORT.md` — one merged plan: **Part A** add every commit, one step at a time per the cadence rule. ## Last completed step -**Phase 7.1 — migrate incidental 12xx ffi examples `#foreign`→`extern`** (`refactor` -commit `731fb8d`). **PHASE 7 STARTED.** Migrated 12 plain-C examples that use -`#foreign` incidentally (FFI plumbing, output unchanged): -1200/1206/1209-1215/1220/1221/1222. Blanket keyword swap (all fn/global markers, no -class forms in 12xx). Empty snapshot diff; corpus validates directly (all marker'd). -Suite green (647/444). **KEEP-LIST POLICY ESTABLISHED (applies to all 7.x):** an -example is KEPT on `#foreign` (deferred to Phase 8 cutover) iff migrating it would -change a snapshot OR its identity is the `#foreign` keyword. Concretely kept: -- **Diagnostics asserting on `#foreign` source/message** — migrating flips the echoed - source line or message → non-empty diff: `1172` (foreign-symbol-conflict), `1174` - (foreign-postfix-conflict), `1620` (cimport-foreign-ref-unvalidated). -- **The equivalence test** `1228` (needs both `#foreign` + `extern` twins by design). -- **Identity-`#foreign` feature tests** (filename `ffi-foreign-*`, defer rename/dedup - to Phase 8): `1205`/`1207`/`1216`/`1218`/`1219`. -- **Comment-only provenance prose** (`1223`/`1229`/`1230`/`1231`) — `#foreign` only in - explanatory comments; left intact per Decision-6-recommended (keep provenance). +**Phase 7.4 — migrate straggler examples `#foreign`→`extern`** (`refactor` commit +`1a8991a`). **PHASE 7 MIGRATABLE WORK COMPLETE (7.1–7.4 done).** Migrated 16 fn/global +examples across categories (0415/0602/0603/1024/1025/1605/1607-1609/1611/1616/1619/ +1622/1628/1635/1636). Marker'd ones corpus-validated; the 3 unmarked uikit importers +(1607/1608/1616) verified byte-identical via `sx ir` probes. Empty snapshot diff; suite +green (647/444). + +**Phase 7 net result:** every example that uses `#foreign` *incidentally* (FFI plumbing, +output-preserving) is now on `extern`/`export`. The **24 files still holding `#foreign` +are exactly the intended keep-list**, all deferred to the Phase 8 cutover: +- **`foreign`-asserting diagnostics** (migrating changes a snapshot): 1172, 1174, 1219 + (stdout label), 1228 (equivalence test), 1620. +- **Identity `ffi-foreign-*` feature tests** (real decls; rename/dedup at cutover): + 1205-global, 1205-global-helper, 1207, 1218, 1219, 1306, 1318. +- **Comment-only / provenance prose** (decls=0; `#foreign` only in comments): 0716, 0729, + 1216, 1223, 1224, 1225, 1229, 1230, 1231, 1332, 1348, 1349, 1426, + issues/0030. +**Lesson (7.3):** the robust class-prefix transform is the GENERAL form +`s/#foreign\s+#(\w+)\((\"[^\"]*\")\)\s*\{/#$1($2) extern {/` — 1417 also used +`#jni_interface`/`#objc_protocol`/`#swift_class`/`#swift_struct`/`#swift_protocol`, and a +`#(objc|jni)_class`-only regex left `extern` in *prefix* position → parse error. All such +directives accept the postfix modifier (probed). Bare defined `#objc_class`/`#jni_class` +examples (no `#foreign`) were left untouched — not a purge target (define→export is an +optional consistency pass, deferrable). + +### Prior: Phase 7.1 — migrate incidental 12xx ffi examples (`refactor` commit `731fb8d`). +Migrated 12 plain-C examples (1200/1206/1209-1215/1220/1221/1222); established the +keep-list policy above. Phase 7.2 (`a68f7c2`): 18 13xx obj-c examples (prefix→postfix +classes). Phase 7.3 (`2888f6f`): 13 14xx jni examples incl. 1417 multi-runtime. ### Prior: Phase 6.5 — migrate `gpu/` `#foreign`→`extern`; `library/` now `#foreign`-free (`refactor` commit `32a7628`). **PHASE 6 COMPLETE.** Final batch: gpu/gles3.sx @@ -226,23 +238,34 @@ AOT), 1227 (export fn rename, AOT), 1348 (objc extern class), 1349 (objc export (jni extern class), 1174/1175 (interplay diagnostics). ## Next step -**PART B — Phase 7.2 (migrate `examples/13xx-ffi-objc-*` `#foreign`→`extern`/`export`).** -Phase 7.1 (12xx incidental) COMPLETE. Apply the KEEP-LIST POLICY above to every batch. +**PART B — Phase 8 (cutover: hard-reject the `#foreign` keyword).** Phases 5–7 COMPLETE: +the entire `library/` tree + all incidentally-`#foreign` examples are on `extern`/`export`; +only the 24-file keep-list (see Last completed step) still spells `#foreign`, by design. -- **Phase 7.2** (`refactor`, snapshot diff must be EMPTY): migrate `examples/13xx-ffi-objc-*`. - ⚠ 13xx has Obj-C **runtime classes** — use the postfix shape (`#objc_class("X") extern {` - import == old `#foreign #objc_class`; `… export {` defined == bare `#objc_class`). Check - each file's shapes first (`grep -c '#foreign #'`). Apply the keep-list: exclude any 13xx - whose snapshot asserts on `#foreign` text or whose identity is the keyword (scan - `examples/expected/13*.std{err,out}` for "foreign" first, like 7.1 did). Most 13xx ARE - marker'd (50 found in Phase 6.4) → corpus validates the empty diff directly. -- **Remaining Phase 7 batches:** 7.3 `examples/14xx-ffi-jni-*` (JNI runtime classes, - same postfix rules), 7.4 `issues/*.sx` repros + stragglers (16xx platform examples, - the scattered 04/06/07/10 ones). For 7.4 `issues/*.md` prose: defer per Decision 6 - (recommended = keep as provenance). +- **Phase 8.0** (`xfail`): add `examples/11xx-diagnostics-foreign-removed.sx` expecting a + clean "`#foreign` removed; use `extern`/`export`" diagnostic — RED while `#foreign` is + still accepted. +- **Phase 8.1** (`green`): parser hard-rejects `#foreign` (mirror the variadic `name: ..T` + cutover). **This is the breaking moment for the 24-file keep-list** — every kept file + must be dealt with IN this phase (or a 7.5 pre-step right before it): + - Identity feature tests (1205/1207/1218/1219/1306/1318) → migrate their decls to + `extern`/`export` (the `.ir`/output stays identical per the A→B gate; may also + `git mv` to drop the now-stale `ffi-foreign-*` name + reseed `expected/`). Dedup vs the + existing extern twins (1224/1225/1229/1230/1231) — delete if fully redundant. + - `foreign`-asserting diagnostics (1172/1174/1219/1228/1620) → these tested `#foreign` + behavior; convert to assert the NEW rejection diagnostic, or retarget to `extern` + equivalents, regenerating snapshots intentionally (this is the one place regen is + correct — it's a deliberate behavior change, not a silent diff). + - Comment-only / provenance prose (0716/0729/1216/1223-1231/1332/1348/1349/1426 + + issues/0030) → migrate the comment text to `extern` for live-tree files (Phase 9.3 + needs zero `foreign` in `examples/`); `issues/*.md` prose governed by Decision 6. + - `specs.md` drops `#foreign`, documents `extern`/`export` only. +- Then **Phase 9** (total `foreign` purge — internal identifiers + docs; needs Decision 5 + [done] + Decision 6). - **Decision 6 (STILL OPEN)** governs the `issues/*.md` + comment-prose carve-out — the - recommended default (keep provenance, gate only the live tree) is being applied; flag - to the user before Phase 9 if not yet ratified. + recommended default (keep provenance, gate only the live tree) has been applied through + Phase 7; **ratify it with the user before Phase 8.1/9** since it decides how much of the + keep-list + issues prose must change. - **6.2 verification note (carry forward):** the `platform/` runtime modules (uikit/android/android_jni) are NOT compiled by any marker'd host corpus test — verify future platform-adjacent migrations via direct `sx ir` on importers (1610/1606 compile @@ -369,6 +392,18 @@ Part A ratified (bare / postfix / `⇒ callconv(.c)` / lib-separate). Part B: deleted at cutover). Affects only diagnostic wording — IR/behavior identical either way. ## Log +- (7.4 stragglers) **PHASE 7 MIGRATABLE WORK COMPLETE.** Migrated 16 fn/global examples + (0415/0602/0603/1024/1025/1605/1607-1609/1611/1616/1619/1622/1628/1635/1636) `#foreign`→ + `extern`; 1607/1608/1616 (unmarked) verified by `sx ir` probes. 24-file keep-list remains + by design (deferred to Phase 8). Suite green (647/444). `refactor` `1a8991a`. +- (7.3 14xx) Migrated 13 jni examples (1410-1419/1423/1424/1425). 1417 (all-runtimes) hit + a parse-error trap: a `#(objc|jni)_class`-only regex left `extern` in PREFIX position on + `#jni_interface`/`#objc_protocol`/`#swift_*` lines → fixed with the GENERAL + `#foreign #(\w+)("X") {`→`#$1("X") extern {` rewrite (all such directives accept the + postfix modifier, probed). Kept 1426 (comment-only). Suite green. `refactor` `2888f6f`. +- (7.2 13xx) Migrated 18 obj-c examples (1308/1311-1321/1341-1347): prefix→postfix import + classes + fn markers. Kept identity 1306/1318, comment-only 1332/1348/1349. No 13xx + snapshot asserts on foreign. Suite green. `refactor` `a68f7c2`. - (7.1 12xx) **PHASE 7 STARTED.** Migrated 12 incidental plain-C examples (1200/1206/1209-1215/1220/1221/1222) `#foreign`→`extern`; output byte-identical, empty snapshot diff, corpus-validated. Established the keep-list policy (see Last