add direct nav hints
This commit is contained in:
parent
479cb7d023
commit
f8d74d5884
2 changed files with 31 additions and 17 deletions
|
|
@ -603,6 +603,14 @@
|
||||||
(defn dynamic-var? [v]
|
(defn dynamic-var? [v]
|
||||||
(-> v meta :dynamic))
|
(-> v meta :dynamic))
|
||||||
|
|
||||||
|
(defn maybe-direct-nav [obj direct-nav?]
|
||||||
|
(if direct-nav?
|
||||||
|
(vary-meta obj assoc :direct-nav true)
|
||||||
|
obj))
|
||||||
|
|
||||||
|
(defn direct-nav? [o]
|
||||||
|
(-> o meta :direct-nav))
|
||||||
|
|
||||||
;; don't do coerce-nav here... save that for resolve-magic-code
|
;; don't do coerce-nav here... save that for resolve-magic-code
|
||||||
(defn- magic-precompilation* [o]
|
(defn- magic-precompilation* [o]
|
||||||
(cond (sequential? o)
|
(cond (sequential? o)
|
||||||
|
|
@ -610,11 +618,18 @@
|
||||||
|
|
||||||
(instance? VarUse o)
|
(instance? VarUse o)
|
||||||
(if (dynamic-var? (:var o))
|
(if (dynamic-var? (:var o))
|
||||||
(->DynamicVal (:sym o))
|
(->DynamicVal (maybe-direct-nav
|
||||||
(:val o))
|
(:sym o)
|
||||||
|
(or (-> o :var direct-nav?)
|
||||||
|
(-> o :sym direct-nav?))))
|
||||||
|
|
||||||
|
(maybe-direct-nav
|
||||||
|
(:val o)
|
||||||
|
(or (-> o :var direct-nav?)
|
||||||
|
(-> o :sym direct-nav?)
|
||||||
|
(-> o :val direct-nav?))))
|
||||||
|
|
||||||
(instance? LocalSym o)
|
(instance? LocalSym o)
|
||||||
;; TODO: check metadata on locals to determine if it's definitely a direct-nav or not
|
|
||||||
(->DynamicVal (:sym o))
|
(->DynamicVal (:sym o))
|
||||||
|
|
||||||
(instance? SpecialFormUse o)
|
(instance? SpecialFormUse o)
|
||||||
|
|
@ -692,22 +707,17 @@
|
||||||
(resolve-magic-code path)))
|
(resolve-magic-code path)))
|
||||||
|
|
||||||
(instance? DynamicVal o)
|
(instance? DynamicVal o)
|
||||||
;;TODO: check ^:nav hint to see whether this is necessary
|
(if (-> o :code direct-nav?)
|
||||||
;;this is relevant for localsyms and dynamicvars
|
(:code o)
|
||||||
;;for localsyms can check metadata in the env as well as metadata on the symbol itself
|
`(coerce-nav ~(:code o)))
|
||||||
;;for dynamic vars check the var metadata
|
|
||||||
`(coerce-nav ~(:code o))
|
|
||||||
|
|
||||||
(instance? DynamicFunction o)
|
(instance? DynamicFunction o)
|
||||||
;;TODO: check ^:nav hint on op to see whether coerce-nav is necessary
|
|
||||||
;; checked when resolving varuse on the function to know if it returns a direct-nav or not
|
|
||||||
;; ":direct-nav-fn" metadata as opposed to :direct-nav metadata which is used for symbols/values
|
|
||||||
(let [op (resolve-dynamic-fn-arg (:op o))
|
(let [op (resolve-dynamic-fn-arg (:op o))
|
||||||
params (map resolve-dynamic-fn-arg (:params o))]
|
params (map resolve-dynamic-fn-arg (:params o))]
|
||||||
(if (all-static? (conj params op))
|
(if (all-static? (conj params op))
|
||||||
(coerce-nav (apply op params))
|
(coerce-nav (apply op params))
|
||||||
`(coerce-nav (~(resolve-dynamic-fn-arg-code op)
|
(let [code `(~(resolve-dynamic-fn-arg-code op) ~@(map resolve-dynamic-fn-arg-code params))]
|
||||||
~@(map resolve-dynamic-fn-arg-code params)))))
|
(if (direct-nav? op) code `(coerce-nav ~code)))))
|
||||||
|
|
||||||
:else
|
:else
|
||||||
(coerce-nav o)))
|
(coerce-nav o)))
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,11 @@
|
||||||
(defmacro richnav [params & impls]
|
(defmacro richnav [params & impls]
|
||||||
(if (empty? params)
|
(if (empty? params)
|
||||||
`(reify RichNavigator ~@impls)
|
`(reify RichNavigator ~@impls)
|
||||||
`(fn ~params
|
`(vary-meta
|
||||||
(reify RichNavigator
|
(fn ~params
|
||||||
~@impls))))
|
(reify RichNavigator
|
||||||
|
~@impls))
|
||||||
|
assoc :direct-nav true)))
|
||||||
|
|
||||||
|
|
||||||
(defmacro nav [params & impls]
|
(defmacro nav [params & impls]
|
||||||
|
|
@ -196,7 +198,9 @@
|
||||||
|
|
||||||
(symbol? path)
|
(symbol? path)
|
||||||
(if (contains? locals-set path)
|
(if (contains? locals-set path)
|
||||||
`(com.rpl.specter.impl/->LocalSym ~path (quote ~path))
|
(let [s (get locals-set path)
|
||||||
|
embed (i/maybe-direct-nav path (-> s meta :direct-nav))]
|
||||||
|
`(com.rpl.specter.impl/->LocalSym ~path (quote ~embed)))
|
||||||
;; var-get doesn't work in cljs, so capture the val in the macro instead
|
;; var-get doesn't work in cljs, so capture the val in the macro instead
|
||||||
`(com.rpl.specter.impl/->VarUse ~path (var ~path) (quote ~path)))
|
`(com.rpl.specter.impl/->VarUse ~path (var ~path) (quote ~path)))
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue