get macroexpansion for clojurescript working correctly so that collected? works inside inline paths
This commit is contained in:
parent
1f21fa5a9d
commit
8c128816f5
3 changed files with 53 additions and 38 deletions
|
|
@ -48,28 +48,29 @@
|
|||
(defn throw-illegal [& args]
|
||||
(throw (js/Error. (apply str args))))
|
||||
|
||||
;; these macroexpand functions are for path macro in bootstrap cljs environment
|
||||
#+cljs
|
||||
(defn macroexpand'
|
||||
[form]
|
||||
(let [orig-eval-fn ^:cljs.analyzer/no-resolve cljs.js/*eval-fn*]
|
||||
(try
|
||||
(set! ^:cljs.analyzer/no-resolve cljs.js/*eval-fn* ^:cljs.analyzer/no-resolve cljs.js/js-eval)
|
||||
(^:cljs.analyzer/no-resolve cljs.js/eval (^:cljs.analyzer/no-resolve cljs.js/empty-state)
|
||||
`(macroexpand (quote ~form))
|
||||
identity)
|
||||
(finally
|
||||
(set! ^:cljs.analyzer/no-resolve cljs.js/*eval-fn* orig-eval-fn)))))
|
||||
|
||||
#+cljs
|
||||
(defn do-macroexpand-all
|
||||
"Recursively performs all possible macroexpansions in form."
|
||||
{:added "1.1"}
|
||||
[form]
|
||||
(walk/prewalk (fn [x]
|
||||
(if (seq? x)
|
||||
(macroexpand' x)
|
||||
x)) form))
|
||||
;; these macroexpand functions are for path macro in bootstrap cljs environment
|
||||
; #+cljs
|
||||
; (defn macroexpand'
|
||||
; [form]
|
||||
; (let [orig-eval-fn ^:cljs.analyzer/no-resolve cljs.js/*eval-fn*]
|
||||
; (try
|
||||
; (set! ^:cljs.analyzer/no-resolve cljs.js/*eval-fn* ^:cljs.analyzer/no-resolve cljs.js/js-eval)
|
||||
; (^:cljs.analyzer/no-resolve cljs.js/eval (^:cljs.analyzer/no-resolve cljs.js/empty-state)
|
||||
; `(macroexpand (quote ~form))
|
||||
; identity)
|
||||
; (finally
|
||||
; (set! ^:cljs.analyzer/no-resolve cljs.js/*eval-fn* orig-eval-fn)))))
|
||||
|
||||
; #+cljs
|
||||
; (defn do-macroexpand-all
|
||||
; "Recursively performs all possible macroexpansions in form."
|
||||
; {:added "1.1"}
|
||||
; [form]
|
||||
; (walk/prewalk (fn [x]
|
||||
; (if (seq? x)
|
||||
; (macroexpand' x)
|
||||
; x)) form))
|
||||
|
||||
#+clj
|
||||
(defn intern* [ns name val] (intern ns name val))
|
||||
|
|
@ -78,10 +79,6 @@
|
|||
(defn intern* [ns name val]
|
||||
(throw-illegal "intern not supported in ClojureScript"))
|
||||
|
||||
#+clj
|
||||
(defn do-macroexpand-all [form]
|
||||
(riddley/macroexpand-all form))
|
||||
|
||||
;; so that macros.clj compiles appropriately when
|
||||
;; run in cljs (this code isn't called in that case)
|
||||
#+cljs
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
(ns com.rpl.specter.macros
|
||||
(:require [com.rpl.specter.impl :as i]
|
||||
[clojure.walk :as cljwalk])
|
||||
[clojure.walk :as cljwalk]
|
||||
[riddley.walk :as riddley])
|
||||
)
|
||||
|
||||
(defn ^:no-doc gensyms [amt]
|
||||
|
|
@ -444,6 +445,27 @@
|
|||
path
|
||||
)))
|
||||
|
||||
(defn cljs-macroexpand [env form]
|
||||
(require 'cljs.analyzer)
|
||||
(let [expand-fn (eval 'cljs.analyzer/macroexpand-1)
|
||||
mform (expand-fn env form)]
|
||||
(cond (identical? form mform) mform
|
||||
(and (seq? mform) (#{'js*} (first mform))) form
|
||||
:else (cljs-macroexpand env mform))))
|
||||
|
||||
(defn cljs-macroexpand-all* [env form]
|
||||
(if (and (seq? form)
|
||||
(#{'fn 'fn* 'cljs.core/fn} (first form)))
|
||||
form
|
||||
(let [expanded (if (seq? form) (cljs-macroexpand env form) form)]
|
||||
(cljwalk/walk #(cljs-macroexpand-all* env %) identity expanded)
|
||||
)))
|
||||
|
||||
(defn cljs-macroexpand-all [env form]
|
||||
(let [ret (cljs-macroexpand-all* env form)]
|
||||
ret
|
||||
))
|
||||
|
||||
;; still possible to mess this up with alter-var-root
|
||||
(defmacro path
|
||||
"Same as calling comp-paths, except it caches the composition of the static part
|
||||
|
|
@ -470,7 +492,10 @@
|
|||
;; note: very important to use riddley's macroexpand-all here, so that
|
||||
;; &env is preserved in any potential nested calls to select (like via
|
||||
;; a view function)
|
||||
expanded (i/do-macroexpand-all (vec path))
|
||||
expanded (if (= platform :clj)
|
||||
(riddley/macroexpand-all (vec path))
|
||||
(cljs-macroexpand-all &env (vec path)))
|
||||
|
||||
prepared-path (ic-prepare-path local-syms expanded)
|
||||
possible-params (vec (ic-possible-params expanded))
|
||||
|
||||
|
|
@ -624,11 +649,8 @@
|
|||
"Creates a filter function navigator that takes in all the collected values
|
||||
as input. For arguments, can use `(collected? [a b] ...)` syntax to look
|
||||
at each collected value as individual arguments, or `(collected? v ...)` syntax
|
||||
to capture all the collected values as a single vector.
|
||||
|
||||
For ClojureScript, since can't use macros inside path when that path will be
|
||||
inline factored/cached, to use collected? declare the logic in a global
|
||||
variable such as (def my-collected (collected? [v] (= v 1)))"
|
||||
to capture all the collected values as a single vector."
|
||||
[params & body]
|
||||
`(i/collected?* (fn [~params] ~@body))
|
||||
)
|
||||
(let [platform (if (contains? &env :locals) :cljs :clj)]
|
||||
`(i/collected?* (~'fn [~params] ~@body))
|
||||
))
|
||||
|
|
|
|||
|
|
@ -1224,10 +1224,6 @@
|
|||
m)
|
||||
)))
|
||||
|
||||
|
||||
;; clojure only because inability to use macroexpand inside path macro in
|
||||
;; clojurescript makes it impossible to use macros inside the path
|
||||
#+clj
|
||||
(deftest collected?-test
|
||||
(let [data {:active-id 1 :items [{:id 1 :name "a"} {:id 2 :name "b"}]}]
|
||||
(is (= {:id 1 :name "a"}
|
||||
|
|
|
|||
Loading…
Reference in a new issue