Add (param :as type) annotations to all fn/lambda params across SX spec

Extend the type annotation system from defcomp-only to fn/lambda params:
- Infrastructure: sf-lambda, py/js-collect-params-loop, and bootstrap_py.py
  now recognize (name :as type) in param lists, extracting just the name
- bootstrap_py.py: add _extract_param_name() helper, fix _emit_for_each_stmt
- 521 type annotations across 22 .sx spec files (eval, types, adapters,
  transpilers, engine, orchestration, deps, signals, router, prove, etc.)
- Zero behavioral change: annotations are metadata for static analysis only
- All bootstrappers (Python, JS, G1) pass, 81/81 spec tests pass

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-11 20:27:36 +00:00
parent c82941d93c
commit b99e69d1bb
23 changed files with 532 additions and 498 deletions

View File

@@ -19,7 +19,7 @@
;; --------------------------------------------------------------------------
(define render-to-dom
(fn (expr env ns)
(fn (expr (env :as dict) ns)
(set-render-active! true)
(case (type-of expr)
;; nil / boolean false / boolean true → empty fragment
@@ -67,7 +67,7 @@
;; --------------------------------------------------------------------------
(define render-dom-list
(fn (expr env ns)
(fn (expr (env :as dict) ns)
(let ((head (first expr)))
(cond
;; Symbol head — dispatch on name
@@ -166,7 +166,7 @@
;; --------------------------------------------------------------------------
(define render-dom-element
(fn (tag args env ns)
(fn ((tag :as string) (args :as list) (env :as dict) ns)
;; Detect namespace from tag
(let ((new-ns (cond (= tag "svg") SVG_NS
(= tag "math") MATH_NS
@@ -237,7 +237,7 @@
;; --------------------------------------------------------------------------
(define render-dom-component
(fn (comp args env ns)
(fn ((comp :as component) (args :as list) (env :as dict) ns)
;; Parse kwargs and children, bind into component env, render body.
(let ((kwargs (dict))
(children (list)))
@@ -284,7 +284,7 @@
;; --------------------------------------------------------------------------
(define render-dom-fragment
(fn (args env ns)
(fn ((args :as list) (env :as dict) ns)
(let ((frag (create-fragment)))
(for-each
(fn (x) (dom-append frag (render-to-dom x env ns)))
@@ -297,7 +297,7 @@
;; --------------------------------------------------------------------------
(define render-dom-raw
(fn (args env)
(fn ((args :as list) (env :as dict))
(let ((frag (create-fragment)))
(for-each
(fn (arg)
@@ -318,7 +318,7 @@
;; --------------------------------------------------------------------------
(define render-dom-unknown-component
(fn (name)
(fn ((name :as string))
(error (str "Unknown component: " name))))
@@ -335,11 +335,11 @@
"error-boundary"))
(define render-dom-form?
(fn (name)
(fn ((name :as string))
(contains? RENDER_DOM_FORMS name)))
(define dispatch-render-form
(fn (name expr env ns)
(fn ((name :as string) expr (env :as dict) ns)
(cond
;; if — reactive inside islands (re-renders when signal deps change)
(= name "if")
@@ -581,7 +581,7 @@
;; --------------------------------------------------------------------------
(define render-lambda-dom
(fn (f args env ns)
(fn ((f :as lambda) (args :as list) (env :as dict) ns)
;; Bind lambda params and render body as DOM
(let ((local (env-merge (lambda-closure f) env)))
(for-each-indexed
@@ -605,7 +605,7 @@
;; - Conditional fragments: (when (deref sig) ...) → reactive show/hide
(define render-dom-island
(fn (island args env ns)
(fn (island (args :as list) (env :as dict) ns)
;; Parse kwargs and children (same as component)
(let ((kwargs (dict))
(children (list)))
@@ -679,7 +679,7 @@
;; Supports :tag keyword to change wrapper element (default "div").
(define render-dom-lake
(fn (args env ns)
(fn ((args :as list) (env :as dict) ns)
(let ((lake-id nil)
(lake-tag "div")
(children (list)))
@@ -723,7 +723,7 @@
;; Stores the island env and transform on the element for morph retrieval.
(define render-dom-marsh
(fn (args env ns)
(fn ((args :as list) (env :as dict) ns)
(let ((marsh-id nil)
(marsh-tag "div")
(marsh-transform nil)
@@ -781,7 +781,7 @@
;; Marks the attribute name on the element via data-sx-reactive-attrs so
;; the morph algorithm knows not to overwrite it with server content.
(define reactive-attr
(fn (el attr-name compute-fn)
(fn (el (attr-name :as string) compute-fn)
;; Mark this attribute as reactively managed
(let ((existing (or (dom-get-attr el "data-sx-reactive-attrs") ""))
(updated (if (empty? existing) attr-name (str existing "," attr-name))))
@@ -802,7 +802,7 @@
;; reactive-fragment — conditionally render a fragment based on a signal
;; Used for (when (deref sig) ...) or (if (deref sig) ...) inside an island.
(define reactive-fragment
(fn (test-fn render-fn env ns)
(fn (test-fn render-fn (env :as dict) ns)
(let ((marker (create-comment "island-fragment"))
(current-nodes (list)))
(effect (fn ()
@@ -824,13 +824,13 @@
;; and reorderings touch the DOM. Without keys, falls back to clear+rerender.
(define render-list-item
(fn (map-fn item env ns)
(fn (map-fn item (env :as dict) ns)
(if (lambda? map-fn)
(render-lambda-dom map-fn (list item) env ns)
(render-to-dom (apply map-fn (list item)) env ns))))
(define extract-key
(fn (node index)
(fn (node (index :as number))
;; Extract key from rendered node: :key attr, data-key, or index fallback
(let ((k (dom-get-attr node "key")))
(if k
@@ -839,7 +839,7 @@
(if dk (str dk) (str "__idx_" index)))))))
(define reactive-list
(fn (map-fn items-sig env ns)
(fn (map-fn items-sig (env :as dict) ns)
(let ((container (create-fragment))
(marker (create-comment "island-list"))
(key-map (dict))
@@ -960,7 +960,7 @@
;; teardown.
(define render-dom-portal
(fn (args env ns)
(fn ((args :as list) (env :as dict) ns)
(let ((selector (trampoline (eval-expr (first args) env)))
(target (or (dom-query selector)
(dom-ensure-element selector))))
@@ -1000,7 +1000,7 @@
;; Calling (retry) re-renders the body, replacing the fallback.
(define render-dom-error-boundary
(fn (args env ns)
(fn ((args :as list) (env :as dict) ns)
(let ((fallback-expr (first args))
(body-exprs (rest args))
(container (dom-create-element "div" nil))