This commit is contained in:
Michiel Borkent 2021-03-13 17:04:35 +01:00
parent 6a911fc54f
commit c0e512e304
3 changed files with 51 additions and 42 deletions

2
sci

@ -1 +1 @@
Subproject commit 02409735ac3e085a407352ea3d0fbd29a3777816 Subproject commit 139df5af5ab8e80a4988db45f1c7110ff40f3e8f

View file

@ -10,43 +10,47 @@
(defn method-or [methods k default] (defn method-or [methods k default]
(or (get methods k) (or (get methods k)
default)) (constantly default)))
(defn proxy-fn [{:keys [class methods]}] (defn class-name [^Class clazz]
(case (.getName ^Class class) (.getName clazz))
"clojure.lang.APersistentMap"
(proxy [clojure.lang.APersistentMap clojure.lang.IMeta clojure.lang.IObj] []
(iterator [] ((method-or-bust methods 'iterator) this))
(containsKey [k] ((method-or-bust methods 'containsKey) this k))
(entryAt [k] ((method-or-bust methods 'entryAt) this k))
(valAt
([k] ((method-or-bust methods 'valAt) this k))
([k default] ((method-or-bust methods 'valAt) this k default)))
(cons [v]
(if-let [m (get methods 'cons)]
(m this v)
(proxy-super cons v)))
(count [] ((method-or-bust methods 'count) this))
(assoc [k v] ((method-or-bust methods 'assoc) this k v))
(without [k] ((method-or-bust methods 'without) this k))
(seq [] ((method-or-bust methods 'seq) this))
(equiv [other] (defn proxy-fn [{:keys [class interfaces methods]}]
(if-let [m (get methods 'equiv)] (let [interfaces (set (map class-name interfaces))]
(m this other) (case [(class-name class) interfaces ]
(proxy-super equiv other))) ["clojure.lang.APersistentMap" #{"clojure.lang.IMeta" "clojure.lang.IObj"}]
(empty [] ((method-or-bust methods 'empty) this)) (proxy [clojure.lang.APersistentMap clojure.lang.IMeta clojure.lang.IObj] []
(iterator [] ((method-or-bust methods 'iterator) this))
(containsKey [k] ((method-or-bust methods 'containsKey) this k))
(entryAt [k] ((method-or-bust methods 'entryAt) this k))
(valAt
([k] ((method-or-bust methods 'valAt) this k))
([k default] ((method-or-bust methods 'valAt) this k default)))
(cons [v]
(if-let [m (get methods 'cons)]
(m this v)
(proxy-super cons v)))
(count [] ((method-or-bust methods 'count) this))
(assoc [k v] ((method-or-bust methods 'assoc) this k v))
(without [k] ((method-or-bust methods 'without) this k))
(seq [] ((method-or-bust methods 'seq) this))
(meta [] ((method-or methods 'meta nil) this)) (equiv [other]
(withMeta [meta] ((method-or methods 'withMeta this) this meta)) (if-let [m (get methods 'equiv)]
(m this other)
(proxy-super equiv other)))
(empty [] ((method-or-bust methods 'empty) this))
(toString [] (meta [] ((method-or-bust methods 'meta) this))
(if-let [m (get methods 'toString)] (withMeta [meta] ((method-or-bust methods 'withMeta) this meta))
(m this)
(proxy-super toString)))) (toString []
"clojure.lang.AMapEntry" (if-let [m (get methods 'toString)]
(proxy [clojure.lang.AMapEntry] [] (m this)
(key [] ((method-or-bust methods 'key) this)) (proxy-super toString))))
(val [] ((method-or-bust methods 'val) this)) ["clojure.lang.AMapEntry" #{}]
(getKey [] ((method-or-bust methods 'getKey) this)) (proxy [clojure.lang.AMapEntry] []
(getValue [] ((method-or-bust methods 'getValue) this))))) (key [] ((method-or-bust methods 'key) this))
(val [] ((method-or-bust methods 'val) this))
(getKey [] ((method-or-bust methods 'getKey) this))
(getValue [] ((method-or-bust methods 'getValue) this))))))

View file

@ -21,14 +21,14 @@
(defn proxy-deref-map (defn proxy-deref-map
{:added "1.0"} {:added "1.0"}
[m] [m]
(proxy [clojure.lang.APersistentMap] (proxy [clojure.lang.APersistentMap clojure.lang.IMeta clojure.lang.IObj]
[] []
(iterator [] (iterator []
::TODO) ::TODO)
(containsKey [k] (contains? m k)) (containsKey [k] (contains? m k))
(entryAt [k] (when (contains? m k) (proxy [clojure.lang.AMapEntry] [] (entryAt [k] (when (contains? m k) (proxy [clojure.lang.AMapEntry] []
(key [] k) (key [] k)
(val [] (auto-deref(get m k)))))) (val [] (auto-deref (get m k))))))
(valAt ([k] (auto-deref (get m k))) (valAt ([k] (auto-deref (get m k)))
([k default] (auto-deref (get m k default)))) ([k default] (auto-deref (get m k default))))
(cons [v] (proxy-deref-map (conj m v))) (cons [v] (proxy-deref-map (conj m v)))
@ -37,7 +37,9 @@
(without [k] (proxy-deref-map (dissoc m k))) (without [k] (proxy-deref-map (dissoc m k)))
(seq [] (map (fn [[k v]](proxy [clojure.lang.AMapEntry] [] (seq [] (map (fn [[k v]](proxy [clojure.lang.AMapEntry] []
(key [] k) (key [] k)
(val [] (auto-deref (get m k))))) m)))) (val [] (auto-deref (get m k))))) m))
(withMeta [md] (proxy-deref-map (with-meta m md)))
(meta [] (meta m))))
(let [m (proxy-deref-map (let [m (proxy-deref-map
{:a (delay 1) {:a (delay 1)
:b (delay 2) :b (delay 2)
@ -54,10 +56,13 @@
:d) :d)
(-> (dissoc m :a) (-> (dissoc m :a)
(contains? :a)) (contains? :a))
(seq m)]))) (seq m)
(meta (with-meta m {:a 1}))
])))
(deftest APersistentMap-proxy-test (deftest APersistentMap-proxy-test
(is (= [1 2 3 true [:c 3] (is (= [1 2 3 true [:c 3]
5 3 5 false 5 3 5 false
'([:a 1] [:b 2] [:c 3])] '([:a 1] [:b 2] [:c 3])
{:a 1}]
(bb code)))) (bb code))))