Make clojure.spec.alpha load and run
Four general gaps, shaken out by loading clojure.spec.alpha: - Special forms were shadowable by a same-named macro. analyze-list macroexpanded before checking special forms, so a ns that redefs def/and/or (spec excludes them via :refer-clojure :exclude) made a bare def resolve to the macro instead of the special form, breaking every defn after. Now a head in the special-form set is never macroexpanded, matching the reference macroexpand1 isSpecial check. - reify dropped all but the last arity of a multi-arity protocol method (spec reifies (specize* [s]) and (specize* [s _])). The macro keyed methods by name and overwrote; now it groups arities into one multi-arity fn. - reify instances did not implement IObj: with-meta threw and (instance? clojure.lang.IObj r) was false. Every Clojure reify carries metadata. with-meta now copies the reify to a fresh identity (shared method table) and keys its meta; instance? IObj/IMeta is true for any reify. This was the registry bug — spec's with-name returned nil for specs, so get-spec missed. - (set! (. Class field) val) was rejected. spec toggles clojure.lang.RT/checkSpecAsserts this way; the analyzer now lowers it to a jolt.host/set-static-field! call over a mutable-statics table, and a plain Class/field read consults that table. Also: .name/.getName on a Namespace and .ns/.sym on a Var (spec's ns-qualify / ->sym). analyzer + reify are seed sources (re-minted). spec.alpha now does valid?/conform/cat/keys/explain-str/check-asserts. tick.alpha.interval-test still needs time-literals data readers (separate).
This commit is contained in:
parent
f417516148
commit
7a343351d6
11 changed files with 598 additions and 532 deletions
|
|
@ -22,7 +22,7 @@
|
|||
(jolt-assoc (if user user (jolt-hash-map))
|
||||
jolt-kw-var-ns (var-cell-ns x)
|
||||
jolt-kw-var-name (var-cell-name x))))
|
||||
((or (pvec? x) (pmap? x) (pset? x) (cseq? x) (empty-list-t? x) (jolt-lazyseq? x) (jrec? x) (procedure? x))
|
||||
((or (pvec? x) (pmap? x) (pset? x) (cseq? x) (empty-list-t? x) (jolt-lazyseq? x) (jrec? x) (jreify? x) (procedure? x))
|
||||
(hashtable-ref meta-table x jolt-nil))
|
||||
(else jolt-nil)))
|
||||
|
||||
|
|
@ -34,6 +34,10 @@
|
|||
((pmap? x) (make-pmap (pmap-root x) (pmap-cnt x)))
|
||||
((pset? x) (make-pset (pset-m x)))
|
||||
((jrec? x) (make-jrec (jrec-tag x) (jrec-pairs x)))
|
||||
;; a reify shares its (read-only) method table + protos but gets a fresh
|
||||
;; identity, so attaching meta leaves the original's meta untouched. Every
|
||||
;; Clojure reify implements IObj.
|
||||
((jreify? x) (make-jreify (jreify-methods x) (jreify-protos x)))
|
||||
;; () is a shared singleton — a fresh instance keeps meta off every other ().
|
||||
((empty-list-t? x) (fresh-empty-list))
|
||||
(else x))) ; cseq / procedure
|
||||
|
|
@ -41,7 +45,7 @@
|
|||
(define (jolt-with-meta x m)
|
||||
(cond
|
||||
((symbol-t? x) (make-symbol-t (symbol-t-ns x) (symbol-t-name x) m))
|
||||
((or (pvec? x) (pmap? x) (pset? x) (cseq? x) (empty-list-t? x) (jolt-lazyseq? x) (jrec? x) (procedure? x))
|
||||
((or (pvec? x) (pmap? x) (pset? x) (cseq? x) (empty-list-t? x) (jolt-lazyseq? x) (jrec? x) (jreify? x) (procedure? x))
|
||||
(let ((c (meta-copy x)))
|
||||
(if (jolt-nil? m) (hashtable-delete! meta-table c) (hashtable-set! meta-table c m))
|
||||
c))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue