diff --git a/project.clj b/project.clj index 9b5cfc3..25ecdff 100644 --- a/project.clj +++ b/project.clj @@ -9,8 +9,8 @@ :auto-clean false :dependencies [[org.clojure/tools.macro "0.1.2"]] :profiles {:provided {:dependencies - [[org.clojure/clojure "1.7.0"] - [org.clojure/clojurescript "1.7.122"]]} + [[org.clojure/clojure "1.6.0"] + [org.clojure/clojurescript "0.0-3211"]]} :dev {:dependencies [[org.clojure/test.check "0.7.0"]] :plugins diff --git a/src/clj/com/rpl/specter/impl.cljx b/src/clj/com/rpl/specter/impl.cljx index 7ea1f21..e40d1a4 100644 --- a/src/clj/com/rpl/specter/impl.cljx +++ b/src/clj/com/rpl/specter/impl.cljx @@ -16,8 +16,9 @@ (:import [com.rpl.specter Util]) ) + (defn spy [e] - (println e) + (println (pr-str e)) e) (defprotocol PathComposer @@ -676,13 +677,6 @@ (satisfies? p/Collector v) (instance? CompiledPath v))) -#+clj -(def ^:dynamic *used-locals*) - -#+clj -(defmacro handle-params [precompiled params-maker possible-params] - `(bind-params* ~precompiled (~params-maker ~@*used-locals*) 0)) - #+cljs (defn handle-params [precompiled params-maker possible-params] (let [params (fast-object-array (count params-maker))] @@ -830,7 +824,7 @@ (let [precompiled (comp-paths* path) params-code (mapv extract-original-code @params-atom) params-maker (if-not (empty? params-code) - (mk-params-maker params-code possible-params-code used-locals)) + (mk-params-maker params-code possible-params-code used-locals)) ] ;; TODO: error if precompiled is compiledpath and there are params or ;; precompiled is paramsneededpath and there are no params... diff --git a/src/clj/com/rpl/specter/macros.clj b/src/clj/com/rpl/specter/macros.clj index 3a0df81..c704aef 100644 --- a/src/clj/com/rpl/specter/macros.clj +++ b/src/clj/com/rpl/specter/macros.clj @@ -349,13 +349,22 @@ (do (mapcat (fn [e] - (if (i/fn-invocation? e) - (concat (-> e rest) (ic-possible-params e)))) + (cond (i/fn-invocation? e) + (concat (-> e rest) (ic-possible-params e)) + + (vector? e) + (ic-possible-params e) + )) path))) ;; still possible to mess this up with alter-var-root (defmacro path [& path] ; "inline cache" - (let [local-syms (-> &env keys set) + (let [;;this is a hack, but the composition of &env is considered stable for cljs + platform (if (contains? &env :locals) :cljs :clj) + local-syms (if (= platform :cljs) + (-> &env :locals keys set) ;cljs + (-> &env keys set) ;clj + ) used-locals (vec (i/walk-select local-syms vector path)) prepared-path (ic-prepare-path local-syms (walk/macroexpand-all (vec path))) possible-params (vec (ic-possible-params path)) @@ -369,36 +378,45 @@ ;; to invoke and/or parameterize the precompiled path without ;; a bunch of checks beforehand cache-id (str (java.util.UUID/randomUUID)) - ] - (binding [i/*used-locals* used-locals] - ;; in order to pass the used locals to the clj handle-params macro - (walk/macroexpand-all - `(let [info# (i/get-path-cache ~cache-id) - - ^com.rpl.specter.impl.CachedPathInfo info# - (if (some? info#) - info# - (let [info# (i/magic-precompilation - ~prepared-path - (quote ~used-locals) - (quote ~possible-params) - )] - (i/add-path-cache! ~cache-id info#) - info# - )) - precompiled# (.-precompiled info#) - params-maker# (.-params-maker info#)] - (if (some? precompiled#) - (if (nil? params-maker#) - precompiled# - (i/handle-params - precompiled# - params-maker# - ~(mapv (fn [p] `(fn [] ~p)) possible-params) + precompiled-sym (gensym "precompiled") + params-maker-sym (gensym "params-maker") + + handle-params-code + (if (= platform :clj) + `(i/bind-params* ~precompiled-sym (~params-maker-sym ~@used-locals) 0) + `(i/handle-params + ~precompiled-sym + ~params-maker-sym + ~(mapv (fn [p] `(fn [] ~p)) possible-params) + )) + ] + ;; in order to pass the used locals to the clj handle-params macro + `(let [info# (i/get-path-cache ~cache-id) + + ^com.rpl.specter.impl.CachedPathInfo info# + (if (some? info#) + info# + (let [info# (i/magic-precompilation + ~prepared-path + (quote ~used-locals) + ;;possible-params is wrong atm + ;;as is used-locals in cljs... + (quote ~possible-params) + )] + (i/add-path-cache! ~cache-id info#) + info# )) - (i/comp-paths* ~(vec path)) - )))) + + ~precompiled-sym (.-precompiled info#) + ~params-maker-sym (.-params-maker info#)] + (if (some? ~precompiled-sym) + (if (nil? ~params-maker-sym) + ~precompiled-sym + ~handle-params-code + ) + (i/comp-paths* ~(vec path)) + )) )) (defmacro select [apath structure]