Stable extension point for definition-form? — no monkey-patching
Replace the fragile pattern of capturing and wrapping definition-form? with a mutable *definition-form-extensions* list in render.sx. Web modules append names to this list instead of redefining the function. Survives spec reloads without losing registrations. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -14,7 +14,7 @@
|
|||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
||||||
var NIL = Object.freeze({ _nil: true, toString: function() { return "nil"; } });
|
var NIL = Object.freeze({ _nil: true, toString: function() { return "nil"; } });
|
||||||
var SX_VERSION = "2026-03-24T09:53:22Z";
|
var SX_VERSION = "2026-03-24T10:04:16Z";
|
||||||
|
|
||||||
function isNil(x) { return x === NIL || x === null || x === undefined; }
|
function isNil(x) { return x === NIL || x === null || x === undefined; }
|
||||||
function isSxTruthy(x) { return x !== false && !isNil(x); }
|
function isSxTruthy(x) { return x !== false && !isNil(x); }
|
||||||
@@ -2236,8 +2236,12 @@ PRIMITIVES["VOID_ELEMENTS"] = VOID_ELEMENTS;
|
|||||||
var BOOLEAN_ATTRS = ["async", "autofocus", "autoplay", "checked", "controls", "default", "defer", "disabled", "formnovalidate", "hidden", "inert", "ismap", "loop", "multiple", "muted", "nomodule", "novalidate", "open", "playsinline", "readonly", "required", "reversed", "selected"];
|
var BOOLEAN_ATTRS = ["async", "autofocus", "autoplay", "checked", "controls", "default", "defer", "disabled", "formnovalidate", "hidden", "inert", "ismap", "loop", "multiple", "muted", "nomodule", "novalidate", "open", "playsinline", "readonly", "required", "reversed", "selected"];
|
||||||
PRIMITIVES["BOOLEAN_ATTRS"] = BOOLEAN_ATTRS;
|
PRIMITIVES["BOOLEAN_ATTRS"] = BOOLEAN_ATTRS;
|
||||||
|
|
||||||
|
// *definition-form-extensions*
|
||||||
|
var _definitionFormExtensions_ = [];
|
||||||
|
PRIMITIVES["*definition-form-extensions*"] = _definitionFormExtensions_;
|
||||||
|
|
||||||
// definition-form?
|
// definition-form?
|
||||||
var isDefinitionForm = function(name) { return sxOr((name == "define"), (name == "defcomp"), (name == "defisland"), (name == "defmacro"), (name == "defstyle"), (name == "deftype"), (name == "defeffect")); };
|
var isDefinitionForm = function(name) { return sxOr((name == "define"), (name == "defcomp"), (name == "defisland"), (name == "defmacro"), (name == "defstyle"), (name == "deftype"), (name == "defeffect"), contains(_definitionFormExtensions_, name)); };
|
||||||
PRIMITIVES["definition-form?"] = isDefinitionForm;
|
PRIMITIVES["definition-form?"] = isDefinitionForm;
|
||||||
|
|
||||||
// parse-element-args
|
// parse-element-args
|
||||||
|
|||||||
@@ -71,11 +71,16 @@
|
|||||||
;; Shared utilities
|
;; Shared utilities
|
||||||
;; --------------------------------------------------------------------------
|
;; --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
;; Extension point for definition forms — modules append names here.
|
||||||
|
;; Survives spec reloads (no function wrapping needed).
|
||||||
|
(define *definition-form-extensions* (list))
|
||||||
|
|
||||||
(define definition-form? :effects []
|
(define definition-form? :effects []
|
||||||
(fn ((name :as string))
|
(fn ((name :as string))
|
||||||
(or (= name "define") (= name "defcomp") (= name "defisland")
|
(or (= name "define") (= name "defcomp") (= name "defisland")
|
||||||
(= name "defmacro") (= name "defstyle")
|
(= name "defmacro") (= name "defstyle")
|
||||||
(= name "deftype") (= name "defeffect"))))
|
(= name "deftype") (= name "defeffect")
|
||||||
|
(contains? *definition-form-extensions* name))))
|
||||||
|
|
||||||
|
|
||||||
(define parse-element-args :effects [render]
|
(define parse-element-args :effects [render]
|
||||||
|
|||||||
@@ -213,27 +213,22 @@
|
|||||||
|
|
||||||
|
|
||||||
;; --------------------------------------------------------------------------
|
;; --------------------------------------------------------------------------
|
||||||
;; Patch form-classification functions
|
;; Register web forms with adapters
|
||||||
;;
|
;;
|
||||||
;; The adapters (html, sx, dom, async) use classifier functions to decide
|
;; Appends form names to the extension lists that definition-form?,
|
||||||
;; how to handle forms during rendering. Now that these web forms are
|
;; render-html-form?, special-form? etc. check. No function wrapping —
|
||||||
;; registered as custom special forms, we redefine the classifiers to
|
;; survives spec reloads.
|
||||||
;; include them. This runs after all adapters are loaded.
|
|
||||||
;; --------------------------------------------------------------------------
|
;; --------------------------------------------------------------------------
|
||||||
|
|
||||||
(define WEB_FORM_NAMES
|
(define WEB_FORM_NAMES
|
||||||
(list "defhandler" "defpage" "defquery" "defaction" "defrelation"))
|
(list "defhandler" "defpage" "defquery" "defaction" "defrelation"))
|
||||||
|
|
||||||
;; Redefine definition-form? to include web forms.
|
;; Extend definition-form? via the stable extension point in render.sx
|
||||||
;; All adapters call this to identify "eval for side effects" forms.
|
(for-each (fn (name)
|
||||||
(let ((core-definition-form? definition-form?))
|
(append! *definition-form-extensions* name))
|
||||||
(define definition-form?
|
WEB_FORM_NAMES)
|
||||||
(fn (name)
|
|
||||||
(or (core-definition-form? name)
|
|
||||||
(contains? WEB_FORM_NAMES name)))))
|
|
||||||
|
|
||||||
;; Extend adapter form-name lists so dispatchers recognise web forms.
|
;; Extend adapter form-name lists so dispatchers recognise web forms.
|
||||||
;; These lists are mutable — append! adds to them in place.
|
|
||||||
(for-each (fn (name)
|
(for-each (fn (name)
|
||||||
(append! RENDER_HTML_FORMS name)
|
(append! RENDER_HTML_FORMS name)
|
||||||
(append! SPECIAL_FORM_NAMES name))
|
(append! SPECIAL_FORM_NAMES name))
|
||||||
|
|||||||
Reference in New Issue
Block a user