diff --git a/src/clj/com/rpl/specter.cljc b/src/clj/com/rpl/specter.cljc index 8c2e1be..d048246 100644 --- a/src/clj/com/rpl/specter.cljc +++ b/src/clj/com/rpl/specter.cljc @@ -74,7 +74,7 @@ curr-params# [~@curr-params]] (if (every? (complement i/dynamic-param?) 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] (late-bound-operation bindings `nav impls)) diff --git a/src/clj/com/rpl/specter/impl.cljc b/src/clj/com/rpl/specter/impl.cljc index ecd9538..1b4d4ee 100644 --- a/src/clj/com/rpl/specter/impl.cljc +++ b/src/clj/com/rpl/specter/impl.cljc @@ -435,7 +435,7 @@ [path]) (defrecord DynamicFunction - [op params]) + [op params code]) (defn dynamic-param? [o] (contains? #{DynamicPath DynamicVal DynamicFunction} (type o))) @@ -670,7 +670,7 @@ (fn [& args] (if (all-static? args) (apply afn args) - (->DynamicFunction afn args) + (->DynamicFunction afn args nil) ))) (defn preserve-map [afn o] @@ -706,7 +706,7 @@ (if (or (-> op meta :dynamicnav) (all-static? (conj params op))) (magic-precompilation* (apply op params)) - (->DynamicFunction op params))) + (->DynamicFunction op params (:code o)))) :else ;; this handles dynamicval as well @@ -729,7 +729,8 @@ (instance? DynamicFunction o) (->DynamicFunction (static-combine (:op o) false) - (doall (map #(static-combine % false) (:params o)))) + (doall (map #(static-combine % false) (:params o))) + (:code o)) (instance? DynamicPath o) (->DynamicPath (static-combine (:path o))) @@ -805,6 +806,10 @@ (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] (cond (instance? DynamicFunction o) (let [op (resolve-arg-code (:op o) possible-params) @@ -826,7 +831,7 @@ (static-val-code o) ;; done this way so it's compatible with cljs as well (since this dynamic val will be ;; 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] diff --git a/test/com/rpl/specter/core_test.cljc b/test/com/rpl/specter/core_test.cljc index 253ff2e..aabe105 100644 --- a/test/com/rpl/specter/core_test.cljc +++ b/test/com/rpl/specter/core_test.cljc @@ -1541,6 +1541,12 @@ (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 (do (defprotocolpath FooPP)