fix bug with nested dynamic params with dynamic function invocations

This commit is contained in:
nathanmarz 2017-05-08 18:48:46 -04:00
parent 426873da98
commit 0608ca6396
3 changed files with 17 additions and 6 deletions

View file

@ -74,7 +74,7 @@
curr-params# [~@curr-params]] curr-params# [~@curr-params]]
(if (every? (complement i/dynamic-param?) curr-params#) (if (every? (complement i/dynamic-param?) curr-params#)
(apply builder# curr-params#) (apply builder# curr-params#)
(com.rpl.specter.impl/->DynamicFunction builder# curr-params#))))) (com.rpl.specter.impl/->DynamicFunction builder# curr-params# nil)))))
(defmacro late-bound-nav [bindings & impls] (defmacro late-bound-nav [bindings & impls]
(late-bound-operation bindings `nav impls)) (late-bound-operation bindings `nav impls))

View file

@ -435,7 +435,7 @@
[path]) [path])
(defrecord DynamicFunction (defrecord DynamicFunction
[op params]) [op params code])
(defn dynamic-param? [o] (defn dynamic-param? [o]
(contains? #{DynamicPath DynamicVal DynamicFunction} (type o))) (contains? #{DynamicPath DynamicVal DynamicFunction} (type o)))
@ -670,7 +670,7 @@
(fn [& args] (fn [& args]
(if (all-static? args) (if (all-static? args)
(apply afn args) (apply afn args)
(->DynamicFunction afn args) (->DynamicFunction afn args nil)
))) )))
(defn preserve-map [afn o] (defn preserve-map [afn o]
@ -706,7 +706,7 @@
(if (or (-> op meta :dynamicnav) (if (or (-> op meta :dynamicnav)
(all-static? (conj params op))) (all-static? (conj params op)))
(magic-precompilation* (apply op params)) (magic-precompilation* (apply op params))
(->DynamicFunction op params))) (->DynamicFunction op params (:code o))))
:else :else
;; this handles dynamicval as well ;; this handles dynamicval as well
@ -729,7 +729,8 @@
(instance? DynamicFunction o) (instance? DynamicFunction o)
(->DynamicFunction (->DynamicFunction
(static-combine (:op o) false) (static-combine (:op o) false)
(doall (map #(static-combine % false) (:params o)))) (doall (map #(static-combine % false) (:params o)))
(:code o))
(instance? DynamicPath o) (instance? DynamicPath o)
(->DynamicPath (static-combine (:path o))) (->DynamicPath (static-combine (:path o)))
@ -805,6 +806,10 @@
(declare resolve-nav-code) (declare resolve-nav-code)
(defn dynamic->code [o]
;; works because both DynamicVal and DynamicFunction have :code field
(walk-until dynamic-param? :code o))
(defn resolve-arg-code [o possible-params] (defn resolve-arg-code [o possible-params]
(cond (instance? DynamicFunction o) (cond (instance? DynamicFunction o)
(let [op (resolve-arg-code (:op o) possible-params) (let [op (resolve-arg-code (:op o) possible-params)
@ -826,7 +831,7 @@
(static-val-code o) (static-val-code o)
;; done this way so it's compatible with cljs as well (since this dynamic val will be ;; done this way so it's compatible with cljs as well (since this dynamic val will be
;; a possible param) ;; a possible param)
(resolve-arg-code (->DynamicVal (walk-until dynamic-param? :code o)) possible-params) (resolve-arg-code (->DynamicVal (dynamic->code o)) possible-params)
))) )))
(defn resolve-nav-code [o possible-params] (defn resolve-nav-code [o possible-params]

View file

@ -1541,6 +1541,12 @@
(is (= #{:b} (setval (s/set-elem :a) s/NONE #{:a :b}))) (is (= #{:b} (setval (s/set-elem :a) s/NONE #{:a :b})))
) )
;; this function necessary to trigger the bug from happening
(defn inc2 [v] (inc v))
(deftest dynamic-function-arg
(is (= {[2] 4} (let [a 1] (transform (s/keypath [(inc2 a)]) inc {[2] 3}))))
)
#?(:clj #?(:clj
(do (do
(defprotocolpath FooPP) (defprotocolpath FooPP)