Host gaps that blocked malli: map .iterator, two clojure.lang builders
malli loads and validates now. Three divergences surfaced building its registry and :map schema: dot-forms: (.iterator coll) on a map fell into the map-as-object branch and was mis-read as a missing :iterator key (nil), so malli's -vmap got nil and crashed on .hasNext. Route iterator through the collection-interop path — a jiterator over the seq (the entry iterator for a map). host-static: register clojure.lang.LazilyPersistentVector/createOwning (-vmap fills an object-array then hands it over) and PersistentArrayMap/createWithCheck (malli's eager entry parser relies on its duplicate-key throw; a missing class was caught and mis-reported as ::duplicate-keys on every map schema).
This commit is contained in:
parent
6ab65a30e3
commit
4114766c71
3 changed files with 30 additions and 0 deletions
|
|
@ -38,6 +38,11 @@
|
||||||
((or (string=? name "get") (string=? name "valAt"))
|
((or (string=? name "get") (string=? name "valAt"))
|
||||||
(list (apply jolt-get obj args)))
|
(list (apply jolt-get obj args)))
|
||||||
((string=? name "containsKey") (list (jolt-contains? obj (car args))))
|
((string=? name "containsKey") (list (jolt-contains? obj (car args))))
|
||||||
|
;; (.iterator coll): a java.util.Iterator over the seq — for a map this is the
|
||||||
|
;; entry iterator. Without this a map's .iterator falls into the map-as-object
|
||||||
|
;; branch and is mis-read as a missing :iterator key (nil). Some libraries
|
||||||
|
;; (e.g. malli's -vmap) iterate a map this way.
|
||||||
|
((string=? name "iterator") (list (make-jiterator (jolt-seq obj))))
|
||||||
(else #f)))
|
(else #f)))
|
||||||
|
|
||||||
;; Universal object-methods: on a
|
;; Universal object-methods: on a
|
||||||
|
|
|
||||||
|
|
@ -164,6 +164,28 @@
|
||||||
(register-class-statics! "LockingTransaction" (list (cons "isRunning" (lambda () #f))))
|
(register-class-statics! "LockingTransaction" (list (cons "isRunning" (lambda () #f))))
|
||||||
(register-class-statics! "clojure.lang.LockingTransaction" (list (cons "isRunning" (lambda () #f))))
|
(register-class-statics! "clojure.lang.LockingTransaction" (list (cons "isRunning" (lambda () #f))))
|
||||||
|
|
||||||
|
;; clojure.lang.LazilyPersistentVector/createOwning: build a vector from an array
|
||||||
|
;; (malli's -vmap fills an object-array then hands it over). jolt has no array
|
||||||
|
;; ownership transfer, so copy the array's elements into a persistent vector.
|
||||||
|
(define (lpv-create-owning arr) (apply jolt-vector (seq->list (jolt-seq arr))))
|
||||||
|
(register-class-statics! "LazilyPersistentVector" (list (cons "createOwning" lpv-create-owning)))
|
||||||
|
(register-class-statics! "clojure.lang.LazilyPersistentVector" (list (cons "createOwning" lpv-create-owning)))
|
||||||
|
|
||||||
|
;; clojure.lang.PersistentArrayMap/createWithCheck: build a map from a [k v k v…]
|
||||||
|
;; array, throwing on a duplicate key. malli's eager entry parser relies on the
|
||||||
|
;; throw to report ::duplicate-keys, so a missing class would mis-fire on every
|
||||||
|
;; map. Build the map and signal if a key collapsed (count*2 < array length).
|
||||||
|
(define (pam-create-with-check arr)
|
||||||
|
(let ((items (seq->list (jolt-seq arr))))
|
||||||
|
(let loop ((xs items) (m (jolt-hash-map)))
|
||||||
|
(if (null? xs) m
|
||||||
|
(if (null? (cdr xs)) (error #f "PersistentArrayMap: odd key/value count")
|
||||||
|
(let ((k (car xs)))
|
||||||
|
(if (jolt-contains? m k) (error #f "Duplicate key")
|
||||||
|
(loop (cddr xs) (jolt-assoc m k (cadr xs))))))))))
|
||||||
|
(register-class-statics! "PersistentArrayMap" (list (cons "createWithCheck" pam-create-with-check)))
|
||||||
|
(register-class-statics! "clojure.lang.PersistentArrayMap" (list (cons "createWithCheck" pam-create-with-check)))
|
||||||
|
|
||||||
(define (now-millis)
|
(define (now-millis)
|
||||||
(let ((t (current-time 'time-utc)))
|
(let ((t (current-time 'time-utc)))
|
||||||
(+ (* 1000 (time-second t)) (quotient (time-nanosecond t) 1000000))))
|
(+ (* 1000 (time-second t)) (quotient (time-nanosecond t) 1000000))))
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,9 @@
|
||||||
(let-values (((form j) (rdr-read-form src i end)))
|
(let-values (((form j) (rdr-read-form src i end)))
|
||||||
(when (> j i)
|
(when (> j i)
|
||||||
(unless (rdr-eof? form)
|
(unless (rdr-eof? form)
|
||||||
|
(when (getenv "JOLT_TRACE_LOAD")
|
||||||
|
(display " [load-form] " (current-error-port))
|
||||||
|
(display (jolt-pr-str form) (current-error-port)) (newline (current-error-port)))
|
||||||
(jolt-compile-eval-form form (chez-current-ns)))
|
(jolt-compile-eval-form form (chez-current-ns)))
|
||||||
(loop j)))))))
|
(loop j)))))))
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue