Compare commits
2 commits
master
...
primitive-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
94a67744c7 | ||
|
|
8d7c786fe9 |
7 changed files with 177 additions and 105 deletions
|
|
@ -1,8 +1,8 @@
|
||||||
(def VERSION (.trim (slurp "VERSION")))
|
(def VERSION (.trim (slurp "VERSION")))
|
||||||
|
|
||||||
(defproject com.rpl/specter VERSION
|
(defproject com.rpl/specter VERSION
|
||||||
:jvm-opts ["-XX:-OmitStackTraceInFastThrow"] ; this prevents JVM from doing optimizations which can remove stack traces from NPE and other exceptions
|
:jvm-opts ["-XX:-OmitStackTraceInFastThrow" ; this prevents JVM from doing optimizations which can remove stack traces from NPE and other exceptions
|
||||||
;"-agentpath:/Applications/YourKit_Java_Profiler_2015_build_15056.app/Contents/Resources/bin/mac/libyjpagent.jnilib"]
|
"-agentpath:/Applications/YourKit_Java_Profiler_2015_build_15056.app/Contents/Resources/bin/mac/libyjpagent.jnilib"]
|
||||||
|
|
||||||
:source-paths ["src/clj"]
|
:source-paths ["src/clj"]
|
||||||
:java-source-paths ["src/java"]
|
:java-source-paths ["src/java"]
|
||||||
|
|
|
||||||
|
|
@ -175,9 +175,9 @@
|
||||||
needed (i/num-needed-params params-path)]
|
needed (i/num-needed-params params-path)]
|
||||||
(richnav 0
|
(richnav 0
|
||||||
(select* [this params params-idx vals structure next-fn]
|
(select* [this params params-idx vals structure next-fn]
|
||||||
(i/exec-rich-select* nav params (- params-idx needed) vals structure next-fn))
|
(i/exec-rich_select nav params (- params-idx needed) vals structure next-fn))
|
||||||
(transform* [this params params-idx vals structure next-fn]
|
(transform* [this params params-idx vals structure next-fn]
|
||||||
(i/exec-rich-transform* nav params (- params-idx needed) vals structure next-fn)))))
|
(i/exec-rich_transform nav params (- params-idx needed) vals structure next-fn)))))
|
||||||
|
|
||||||
|
|
||||||
;; Built-in pathing and context operations
|
;; Built-in pathing and context operations
|
||||||
|
|
@ -328,6 +328,7 @@
|
||||||
In a transform, that subset in the original set is changed to the
|
In a transform, that subset in the original set is changed to the
|
||||||
new value of the subset."}
|
new value of the subset."}
|
||||||
subset
|
subset
|
||||||
|
{:inline-next-fn true}
|
||||||
[aset]
|
[aset]
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(next-fn (set/intersection structure aset)))
|
(next-fn (set/intersection structure aset)))
|
||||||
|
|
@ -344,6 +345,7 @@
|
||||||
In a transform, that submap in the original map is changed to the new
|
In a transform, that submap in the original map is changed to the new
|
||||||
value of the submap."}
|
value of the submap."}
|
||||||
submap
|
submap
|
||||||
|
{:inline-next-fn true}
|
||||||
[m-keys]
|
[m-keys]
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(next-fn (select-keys structure m-keys)))
|
(next-fn (select-keys structure m-keys)))
|
||||||
|
|
@ -371,7 +373,7 @@
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(n/walk-select afn next-fn structure))
|
(n/walk-select afn next-fn structure))
|
||||||
(transform* [this structure next-fn]
|
(transform* [this structure next-fn]
|
||||||
(n/codewalk-until afn next-fn structure)))
|
(i/codewalk-until afn next-fn structure)))
|
||||||
|
|
||||||
(defpathedfn subselect
|
(defpathedfn subselect
|
||||||
"Navigates to a sequence that contains the results of (select ...),
|
"Navigates to a sequence that contains the results of (select ...),
|
||||||
|
|
@ -397,6 +399,7 @@
|
||||||
(defnav
|
(defnav
|
||||||
^{:doc "Navigates to the specified key, navigating to nil if it does not exist."}
|
^{:doc "Navigates to the specified key, navigating to nil if it does not exist."}
|
||||||
keypath
|
keypath
|
||||||
|
{:inline-next-fn true}
|
||||||
[key]
|
[key]
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(next-fn (get structure key)))
|
(next-fn (get structure key)))
|
||||||
|
|
@ -407,6 +410,7 @@
|
||||||
(defnav
|
(defnav
|
||||||
^{:doc "Navigates to the key only if it exists in the map."}
|
^{:doc "Navigates to the key only if it exists in the map."}
|
||||||
must
|
must
|
||||||
|
{:inline-next-fn true}
|
||||||
[k]
|
[k]
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(if (contains? structure k)
|
(if (contains? structure k)
|
||||||
|
|
@ -421,6 +425,7 @@
|
||||||
(defnav
|
(defnav
|
||||||
^{:doc "Navigates to result of running `afn` on the currently navigated value."}
|
^{:doc "Navigates to result of running `afn` on the currently navigated value."}
|
||||||
view
|
view
|
||||||
|
{:inline-next-fn true}
|
||||||
[afn]
|
[afn]
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(next-fn (afn structure)))
|
(next-fn (afn structure)))
|
||||||
|
|
@ -433,6 +438,7 @@
|
||||||
transforms, the transformed value then has `unparse-fn` run on
|
transforms, the transformed value then has `unparse-fn` run on
|
||||||
it to get the final value at this point."}
|
it to get the final value at this point."}
|
||||||
parser
|
parser
|
||||||
|
{:inline-next-fn true}
|
||||||
[parse-fn unparse-fn]
|
[parse-fn unparse-fn]
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(next-fn (parse-fn structure)))
|
(next-fn (parse-fn structure)))
|
||||||
|
|
@ -518,6 +524,7 @@
|
||||||
^{:doc "Keeps the element only if it matches the supplied predicate. This is the
|
^{:doc "Keeps the element only if it matches the supplied predicate. This is the
|
||||||
late-bound parameterized version of using a function directly in a path."}
|
late-bound parameterized version of using a function directly in a path."}
|
||||||
pred
|
pred
|
||||||
|
{:inline-next-fn true}
|
||||||
[afn]
|
[afn]
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(if (afn structure) (next-fn structure) NONE))
|
(if (afn structure) (next-fn structure) NONE))
|
||||||
|
|
@ -546,6 +553,7 @@
|
||||||
^{:doc "Navigates to the provided val if the structure is nil. Otherwise it stays
|
^{:doc "Navigates to the provided val if the structure is nil. Otherwise it stays
|
||||||
navigated at the structure."}
|
navigated at the structure."}
|
||||||
nil->val
|
nil->val
|
||||||
|
{:inline-next-fn true}
|
||||||
[v]
|
[v]
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(next-fn (if (nil? structure) v structure)))
|
(next-fn (if (nil? structure) v structure)))
|
||||||
|
|
@ -717,15 +725,15 @@
|
||||||
|
|
||||||
(richnav (+ comp1-needed (i/num-needed-params comp2))
|
(richnav (+ comp1-needed (i/num-needed-params comp2))
|
||||||
(select* [this params params-idx vals structure next-fn]
|
(select* [this params params-idx vals structure next-fn]
|
||||||
(let [res1 (i/exec-rich-select* nav1 params params-idx vals structure next-fn)
|
(let [res1 (i/exec-rich_select nav1 params params-idx vals structure next-fn)
|
||||||
res2 (i/exec-rich-select* nav2 params (+ params-idx comp1-needed) vals structure next-fn)]
|
res2 (i/exec-rich_select nav2 params (+ params-idx comp1-needed) vals structure next-fn)]
|
||||||
(if (identical? NONE res2)
|
(if (identical? NONE res2)
|
||||||
res1
|
res1
|
||||||
res2)))
|
res2)))
|
||||||
|
|
||||||
(transform* [this params params-idx vals structure next-fn]
|
(transform* [this params params-idx vals structure next-fn]
|
||||||
(let [s1 (i/exec-rich-transform* nav1 params params-idx vals structure next-fn)]
|
(let [s1 (i/exec-rich_transform nav1 params params-idx vals structure next-fn)]
|
||||||
(i/exec-rich-transform* nav2 params (+ params-idx comp1-needed) vals s1 next-fn))))))
|
(i/exec-rich_transform nav2 params (+ params-idx comp1-needed) vals s1 next-fn))))))
|
||||||
|
|
||||||
([path1 path2 & paths]
|
([path1 path2 & paths]
|
||||||
(reduce multi-path (multi-path path1 path2) paths)))
|
(reduce multi-path (multi-path path1 path2) paths)))
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
(ns com.rpl.specter.defnavhelpers
|
(ns com.rpl.specter.defnavhelpers
|
||||||
(:require [com.rpl.specter.impl :as i]))
|
(:require [com.rpl.specter.impl :as i]))
|
||||||
|
|
||||||
(defn param-delta [i]
|
(defn param-delta [^long i]
|
||||||
(fn [^objects params params-idx]
|
(fn [^objects params ^long params-idx]
|
||||||
(aget params (+ params-idx i))))
|
(aget params (+ params-idx i))))
|
||||||
|
|
||||||
|
|
||||||
(defn bound-params [path start-delta]
|
(defn bound-params [path ^long start-delta]
|
||||||
(fn [^objects params params-idx]
|
(fn [^objects params ^long params-idx]
|
||||||
(if (i/params-needed-path? path)
|
(if (i/params-needed-path? path)
|
||||||
(i/bind-params* path params (+ params-idx start-delta))
|
(i/bind-params* path params (+ params-idx start-delta))
|
||||||
path)))
|
path)))
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,15 @@
|
||||||
(ns com.rpl.specter.impl
|
(ns com.rpl.specter.impl
|
||||||
#?(:cljs (:require-macros
|
#?(:cljs (:require-macros
|
||||||
[com.rpl.specter.defhelpers :refer [define-ParamsNeededPath]]
|
[com.rpl.specter.defhelpers :refer [define-ParamsNeededPath]]
|
||||||
[com.rpl.specter.util-macros :refer [doseqres]]))
|
[com.rpl.specter.util-macros :refer [doseqres definterface+]]))
|
||||||
|
|
||||||
(:use [com.rpl.specter.protocols :only
|
(:use [com.rpl.specter.protocols :only
|
||||||
[select* transform* collect-val Navigator]]
|
[select* transform* collect-val Navigator]]
|
||||||
#?(:clj [com.rpl.specter.util-macros :only [doseqres]]))
|
#?(:clj [com.rpl.specter.util-macros :only [doseqres definterface+]]))
|
||||||
|
|
||||||
(:require [com.rpl.specter.protocols :as p]
|
(:require [com.rpl.specter.protocols :as p]
|
||||||
[clojure.string :as s]
|
[clojure.string :as s]
|
||||||
|
[clojure.walk :as walk]
|
||||||
#?(:clj [com.rpl.specter.defhelpers :as dh])
|
#?(:clj [com.rpl.specter.defhelpers :as dh])
|
||||||
#?(:clj [riddley.walk :as riddley]))
|
#?(:clj [riddley.walk :as riddley]))
|
||||||
|
|
||||||
|
|
@ -103,35 +104,35 @@
|
||||||
|
|
||||||
(deftype ExecutorFunctions [traverse-executor transform-executor])
|
(deftype ExecutorFunctions [traverse-executor transform-executor])
|
||||||
|
|
||||||
(deftype ParameterizedRichNav [rich-nav params params-idx])
|
(deftype ParameterizedRichNav [rich-nav params ^long params-idx])
|
||||||
|
|
||||||
(defprotocol RichNavigator
|
(definterface+ RichNavigator
|
||||||
(rich-select* [this params params-idx vals structure next-fn])
|
(rich_select [this params ^long params-idx vals structure next-fn])
|
||||||
(rich-transform* [this params params-idx vals structure next-fn]))
|
(rich_transform [this params ^long params-idx vals structure next-fn]))
|
||||||
|
|
||||||
|
|
||||||
#?(
|
#?(
|
||||||
:clj
|
:clj
|
||||||
(defmacro exec-rich-select* [this & args]
|
(defmacro exec-rich_select [this & args]
|
||||||
(let [hinted (with-meta this {:tag 'com.rpl.specter.impl.RichNavigator})]
|
(let [hinted (with-meta this {:tag 'com.rpl.specter.impl.RichNavigator})]
|
||||||
`(.rich-select* ~hinted ~@args)))
|
`(.rich_select ~hinted ~@args)))
|
||||||
|
|
||||||
|
|
||||||
:cljs
|
:cljs
|
||||||
(defn exec-rich-select* [this params params-idx vals structure next-fn]
|
(defn exec-rich_select [this params params-idx vals structure next-fn]
|
||||||
(rich-select* ^not-native this params params-idx vals structure next-fn)))
|
(rich_select ^not-native this params params-idx vals structure next-fn)))
|
||||||
|
|
||||||
|
|
||||||
#?(
|
#?(
|
||||||
:clj
|
:clj
|
||||||
(defmacro exec-rich-transform* [this & args]
|
(defmacro exec-rich_transform [this & args]
|
||||||
(let [hinted (with-meta this {:tag 'com.rpl.specter.impl.RichNavigator})]
|
(let [hinted (with-meta this {:tag 'com.rpl.specter.impl.RichNavigator})]
|
||||||
`(.rich-transform* ~hinted ~@args)))
|
`(.rich_transform ~hinted ~@args)))
|
||||||
|
|
||||||
|
|
||||||
:cljs
|
:cljs
|
||||||
(defn exec-rich-transform* [this params params-idx vals structure next-fn]
|
(defn exec-rich_transform [this params params-idx vals structure next-fn]
|
||||||
(rich-transform* ^not-native this params params-idx vals structure next-fn)))
|
(rich_transform ^not-native this params params-idx vals structure next-fn)))
|
||||||
|
|
||||||
|
|
||||||
#?(
|
#?(
|
||||||
|
|
@ -161,7 +162,7 @@
|
||||||
(def RichPathExecutor
|
(def RichPathExecutor
|
||||||
(->ExecutorFunctions
|
(->ExecutorFunctions
|
||||||
(fn [^ParameterizedRichNav richnavp result-fn structure]
|
(fn [^ParameterizedRichNav richnavp result-fn structure]
|
||||||
(exec-rich-select* (.-rich-nav richnavp)
|
(exec-rich_select (.-rich-nav richnavp)
|
||||||
(.-params richnavp) (.-params-idx richnavp)
|
(.-params richnavp) (.-params-idx richnavp)
|
||||||
[] structure
|
[] structure
|
||||||
(fn [_ _ vals structure]
|
(fn [_ _ vals structure]
|
||||||
|
|
@ -170,7 +171,7 @@
|
||||||
structure
|
structure
|
||||||
(conj vals structure))))))
|
(conj vals structure))))))
|
||||||
(fn [^ParameterizedRichNav richnavp transform-fn structure]
|
(fn [^ParameterizedRichNav richnavp transform-fn structure]
|
||||||
(exec-rich-transform* (.-rich-nav richnavp)
|
(exec-rich_transform (.-rich-nav richnavp)
|
||||||
(.-params richnavp) (.-params-idx richnavp)
|
(.-params richnavp) (.-params-idx richnavp)
|
||||||
[] structure
|
[] structure
|
||||||
(fn [_ _ vals structure]
|
(fn [_ _ vals structure]
|
||||||
|
|
@ -325,22 +326,30 @@
|
||||||
(coerce-path [this]
|
(coerce-path [this]
|
||||||
(coerce-object this)))
|
(coerce-object this)))
|
||||||
|
|
||||||
|
#?(:clj
|
||||||
|
(defn rich-nav? [o]
|
||||||
|
(instance? RichNavigator o))
|
||||||
|
|
||||||
|
:cljs
|
||||||
|
(defn rich-nav? [o]
|
||||||
|
(satisfies? RichNavigator o)))
|
||||||
|
|
||||||
|
|
||||||
(defn- combine-same-types [[n & _ :as all]]
|
(defn- combine-same-types [[n & _ :as all]]
|
||||||
(let [combiner
|
(let [combiner
|
||||||
(if (satisfies? RichNavigator n)
|
(if (rich-nav? n)
|
||||||
(fn [curr next]
|
(fn [curr next]
|
||||||
(reify RichNavigator
|
(reify RichNavigator
|
||||||
(rich-select* [this params params-idx vals structure next-fn]
|
(rich_select [this params params-idx vals structure next-fn]
|
||||||
(exec-rich-select* curr params params-idx vals structure
|
(exec-rich_select curr params params-idx vals structure
|
||||||
(fn [params-next params-idx-next vals-next structure-next]
|
(fn [params-next params-idx-next vals-next structure-next]
|
||||||
(exec-rich-select* next params-next params-idx-next
|
(exec-rich_select next params-next params-idx-next
|
||||||
vals-next structure-next next-fn))))
|
vals-next structure-next next-fn))))
|
||||||
|
|
||||||
(rich-transform* [this params params-idx vals structure next-fn]
|
(rich_transform [this params params-idx vals structure next-fn]
|
||||||
(exec-rich-transform* curr params params-idx vals structure
|
(exec-rich_transform curr params params-idx vals structure
|
||||||
(fn [params-next params-idx-next vals-next structure-next]
|
(fn [params-next params-idx-next vals-next structure-next]
|
||||||
(exec-rich-transform* next params-next params-idx-next
|
(exec-rich_transform next params-next params-idx-next
|
||||||
vals-next structure-next next-fn))))))
|
vals-next structure-next next-fn))))))
|
||||||
|
|
||||||
(fn [curr next]
|
(fn [curr next]
|
||||||
|
|
@ -356,13 +365,13 @@
|
||||||
(reduce combiner all)))
|
(reduce combiner all)))
|
||||||
|
|
||||||
(defn coerce-rich-navigator [nav]
|
(defn coerce-rich-navigator [nav]
|
||||||
(if (satisfies? RichNavigator nav)
|
(if (rich-nav? nav)
|
||||||
nav
|
nav
|
||||||
(reify RichNavigator
|
(reify RichNavigator
|
||||||
(rich-select* [this params params-idx vals structure next-fn]
|
(rich_select [this params params-idx vals structure next-fn]
|
||||||
(exec-select* nav structure (fn [structure] (next-fn params params-idx vals structure))))
|
(exec-select* nav structure (fn [structure] (next-fn params params-idx vals structure))))
|
||||||
|
|
||||||
(rich-transform* [this params params-idx vals structure next-fn]
|
(rich_transform [this params params-idx vals structure next-fn]
|
||||||
(exec-transform* nav structure (fn [structure] (next-fn params params-idx vals structure)))))))
|
(exec-transform* nav structure (fn [structure] (next-fn params params-idx vals structure)))))))
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -386,13 +395,13 @@
|
||||||
path
|
path
|
||||||
(no-params-rich-compiled-path
|
(no-params-rich-compiled-path
|
||||||
(reify RichNavigator
|
(reify RichNavigator
|
||||||
(rich-select* [this params2 params-idx2 vals structure next-fn]
|
(rich_select [this params2 params-idx2 vals structure next-fn]
|
||||||
(exec-rich-select* rich-nav params params-idx vals structure
|
(exec-rich_select rich-nav params params-idx vals structure
|
||||||
(fn [_ _ vals-next structure-next]
|
(fn [_ _ vals-next structure-next]
|
||||||
(next-fn params2 params-idx2 vals-next structure-next))))
|
(next-fn params2 params-idx2 vals-next structure-next))))
|
||||||
|
|
||||||
(rich-transform* [this params2 params-idx2 vals structure next-fn]
|
(rich_transform [this params2 params-idx2 vals structure next-fn]
|
||||||
(exec-rich-transform* rich-nav params params-idx vals structure
|
(exec-rich_transform rich-nav params params-idx vals structure
|
||||||
(fn [_ _ vals-next structure-next]
|
(fn [_ _ vals-next structure-next]
|
||||||
(next-fn params2 params-idx2 vals-next structure-next))))))))))
|
(next-fn params2 params-idx2 vals-next structure-next))))))))))
|
||||||
|
|
||||||
|
|
@ -401,7 +410,7 @@
|
||||||
(capture-params-internally (comp-paths* path)))
|
(capture-params-internally (comp-paths* path)))
|
||||||
|
|
||||||
(defn nav-type [n]
|
(defn nav-type [n]
|
||||||
(if (satisfies? RichNavigator n)
|
(if (rich-nav? n)
|
||||||
:rich
|
:rich
|
||||||
:lean))
|
:lean))
|
||||||
|
|
||||||
|
|
@ -652,6 +661,14 @@
|
||||||
#?(:cljs (instance? cljs.core.LazySeq f))
|
#?(:cljs (instance? cljs.core.LazySeq f))
|
||||||
(list? f)))
|
(list? f)))
|
||||||
|
|
||||||
|
(defn codewalk-until [pred on-match-fn structure]
|
||||||
|
(if (pred structure)
|
||||||
|
(on-match-fn structure)
|
||||||
|
(let [ret (walk/walk (partial codewalk-until pred on-match-fn) identity structure)]
|
||||||
|
(if (and (fn-invocation? structure) (fn-invocation? ret))
|
||||||
|
(with-meta ret (meta structure))
|
||||||
|
ret))))
|
||||||
|
|
||||||
(defrecord LayeredNav [underlying])
|
(defrecord LayeredNav [underlying])
|
||||||
|
|
||||||
(defn layered-nav? [o] (instance? LayeredNav o))
|
(defn layered-nav? [o] (instance? LayeredNav o))
|
||||||
|
|
@ -766,13 +783,13 @@
|
||||||
(def pred*
|
(def pred*
|
||||||
(->ParamsNeededPath
|
(->ParamsNeededPath
|
||||||
(reify RichNavigator
|
(reify RichNavigator
|
||||||
(rich-select* [this params params-idx vals structure next-fn]
|
(rich_select [this params params-idx vals structure next-fn]
|
||||||
(let [afn (aget ^objects params params-idx)]
|
(let [afn (aget ^objects params params-idx)]
|
||||||
(if (afn structure)
|
(if (afn structure)
|
||||||
(next-fn params (inc params-idx) vals structure)
|
(next-fn params (inc params-idx) vals structure)
|
||||||
NONE)))
|
NONE)))
|
||||||
|
|
||||||
(rich-transform* [this params params-idx vals structure next-fn]
|
(rich_transform [this params params-idx vals structure next-fn]
|
||||||
(let [afn (aget ^objects params params-idx)]
|
(let [afn (aget ^objects params params-idx)]
|
||||||
(if (afn structure)
|
(if (afn structure)
|
||||||
(next-fn params (inc params-idx) vals structure)
|
(next-fn params (inc params-idx) vals structure)
|
||||||
|
|
@ -784,13 +801,13 @@
|
||||||
(def collected?*
|
(def collected?*
|
||||||
(->ParamsNeededPath
|
(->ParamsNeededPath
|
||||||
(reify RichNavigator
|
(reify RichNavigator
|
||||||
(rich-select* [this params params-idx vals structure next-fn]
|
(rich_select [this params params-idx vals structure next-fn]
|
||||||
(let [afn (aget ^objects params params-idx)]
|
(let [afn (aget ^objects params params-idx)]
|
||||||
(if (afn vals)
|
(if (afn vals)
|
||||||
(next-fn params (inc params-idx) vals structure)
|
(next-fn params (inc params-idx) vals structure)
|
||||||
NONE)))
|
NONE)))
|
||||||
|
|
||||||
(rich-transform* [this params params-idx vals structure next-fn]
|
(rich_transform [this params params-idx vals structure next-fn]
|
||||||
(let [afn (aget ^objects params params-idx)]
|
(let [afn (aget ^objects params params-idx)]
|
||||||
(if (afn vals)
|
(if (afn vals)
|
||||||
(next-fn params (inc params-idx) vals structure)
|
(next-fn params (inc params-idx) vals structure)
|
||||||
|
|
@ -802,11 +819,11 @@
|
||||||
(def rich-compiled-path-proxy
|
(def rich-compiled-path-proxy
|
||||||
(->ParamsNeededPath
|
(->ParamsNeededPath
|
||||||
(reify RichNavigator
|
(reify RichNavigator
|
||||||
(rich-select* [this params params-idx vals structure next-fn]
|
(rich_select [this params params-idx vals structure next-fn]
|
||||||
(let [apath ^CompiledPath (aget ^objects params params-idx)
|
(let [apath ^CompiledPath (aget ^objects params params-idx)
|
||||||
pnav ^ParameterizedRichNav (.-nav apath)
|
pnav ^ParameterizedRichNav (.-nav apath)
|
||||||
nav (.-rich-nav pnav)]
|
nav (.-rich-nav pnav)]
|
||||||
(exec-rich-select*
|
(exec-rich_select
|
||||||
nav
|
nav
|
||||||
(.-params pnav)
|
(.-params pnav)
|
||||||
(.-params-idx pnav)
|
(.-params-idx pnav)
|
||||||
|
|
@ -815,11 +832,11 @@
|
||||||
(fn [_ _ vals-next structure-next]
|
(fn [_ _ vals-next structure-next]
|
||||||
(next-fn params params-idx vals-next structure-next)))))
|
(next-fn params params-idx vals-next structure-next)))))
|
||||||
|
|
||||||
(rich-transform* [this params params-idx vals structure next-fn]
|
(rich_transform [this params params-idx vals structure next-fn]
|
||||||
(let [apath ^CompiledPath (aget ^objects params params-idx)
|
(let [apath ^CompiledPath (aget ^objects params params-idx)
|
||||||
pnav ^ParameterizedRichNav (.-nav apath)
|
pnav ^ParameterizedRichNav (.-nav apath)
|
||||||
nav (.-rich-nav pnav)]
|
nav (.-rich-nav pnav)]
|
||||||
(exec-rich-transform*
|
(exec-rich_transform
|
||||||
nav
|
nav
|
||||||
(.-params pnav)
|
(.-params pnav)
|
||||||
(.-params-idx pnav)
|
(.-params-idx pnav)
|
||||||
|
|
@ -834,7 +851,7 @@
|
||||||
(def lean-compiled-path-proxy
|
(def lean-compiled-path-proxy
|
||||||
(->ParamsNeededPath
|
(->ParamsNeededPath
|
||||||
(reify RichNavigator
|
(reify RichNavigator
|
||||||
(rich-select* [this params params-idx vals structure next-fn]
|
(rich_select [this params params-idx vals structure next-fn]
|
||||||
(let [^CompiledPath apath (aget ^objects params params-idx)
|
(let [^CompiledPath apath (aget ^objects params params-idx)
|
||||||
^Navigator nav (.-nav apath)]
|
^Navigator nav (.-nav apath)]
|
||||||
(exec-select*
|
(exec-select*
|
||||||
|
|
@ -843,7 +860,7 @@
|
||||||
(fn [structure-next]
|
(fn [structure-next]
|
||||||
(next-fn params params-idx vals structure-next)))))
|
(next-fn params params-idx vals structure-next)))))
|
||||||
|
|
||||||
(rich-transform* [this params params-idx vals structure next-fn]
|
(rich_transform [this params params-idx vals structure next-fn]
|
||||||
(let [^CompiledPath apath (aget ^objects params params-idx)
|
(let [^CompiledPath apath (aget ^objects params params-idx)
|
||||||
^Navigator nav (.-nav apath)]
|
^Navigator nav (.-nav apath)]
|
||||||
(exec-transform*
|
(exec-transform*
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
(ns com.rpl.specter.macros
|
(ns com.rpl.specter.macros
|
||||||
(:use [com.rpl.specter.protocols :only [Navigator]]
|
(:use [com.rpl.specter.protocols :only [Navigator]])
|
||||||
[com.rpl.specter.impl :only [RichNavigator]])
|
|
||||||
(:require [com.rpl.specter.impl :as i]
|
(:require [com.rpl.specter.impl :as i]
|
||||||
[clojure.walk :as cljwalk]
|
[clojure.walk :as cljwalk]
|
||||||
[com.rpl.specter.defnavhelpers :as dnh]))
|
[com.rpl.specter.defnavhelpers :as dnh])
|
||||||
|
(:import [com.rpl.specter.impl RichNavigator]))
|
||||||
|
|
||||||
|
|
||||||
(defn ^:no-doc gensyms [amt]
|
(defn ^:no-doc gensyms [amt]
|
||||||
|
|
@ -34,10 +34,10 @@
|
||||||
|
|
||||||
`(let [num-params# ~num-params
|
`(let [num-params# ~num-params
|
||||||
nav# (reify RichNavigator
|
nav# (reify RichNavigator
|
||||||
(~'rich-select* ~s-params
|
(~'rich_select ~s-params
|
||||||
(let [~s-next-fn-sym (i/mk-jump-next-fn ~s-next-fn-sym ~s-pidx-sym num-params#)]
|
(let [~s-next-fn-sym (i/mk-jump-next-fn ~s-next-fn-sym ~s-pidx-sym num-params#)]
|
||||||
~@s-body))
|
~@s-body))
|
||||||
(~'rich-transform* ~t-params
|
(~'rich_transform ~t-params
|
||||||
(let [~t-next-fn-sym (i/mk-jump-next-fn ~t-next-fn-sym ~t-pidx-sym num-params#)]
|
(let [~t-next-fn-sym (i/mk-jump-next-fn ~t-next-fn-sym ~t-pidx-sym num-params#)]
|
||||||
~@t-body)))]
|
~@t-body)))]
|
||||||
|
|
||||||
|
|
@ -62,20 +62,20 @@
|
||||||
`(let [~@binding-fn-declarations]
|
`(let [~@binding-fn-declarations]
|
||||||
~body)))
|
~body)))
|
||||||
|
|
||||||
(defmacro ^:no-doc rich-nav-with-bindings [num-params-code bindings & impls]
|
|
||||||
|
(defn- rich-nav-with-bindings-not-inlined [num-params-code bindings impls]
|
||||||
(let [{[[_ s-structure-sym s-next-fn-sym] & s-body] 'select*
|
(let [{[[_ s-structure-sym s-next-fn-sym] & s-body] 'select*
|
||||||
[[_ t-structure-sym t-next-fn-sym] & t-body] 'transform*}
|
[[_ t-structure-sym t-next-fn-sym] & t-body] 'transform*}
|
||||||
(determine-params-impls impls)
|
(determine-params-impls impls)
|
||||||
params-sym (gensym "params")
|
params-sym (gensym "params")
|
||||||
params-idx-sym (gensym "params-idx")]
|
params-idx-sym (gensym "params-idx")]
|
||||||
|
|
||||||
(operation-with-bindings
|
(operation-with-bindings
|
||||||
bindings
|
bindings
|
||||||
params-sym
|
params-sym
|
||||||
params-idx-sym
|
params-idx-sym
|
||||||
(fn [binding-declarations]
|
(fn [binding-declarations]
|
||||||
`(reify RichNavigator
|
`(reify RichNavigator
|
||||||
(~'rich-select* [this# ~params-sym ~params-idx-sym vals# ~s-structure-sym next-fn#]
|
(~'rich_select [this# ~params-sym ~params-idx-sym vals# ~s-structure-sym next-fn#]
|
||||||
(let [~@binding-declarations
|
(let [~@binding-declarations
|
||||||
next-params-idx# (+ ~params-idx-sym ~num-params-code)
|
next-params-idx# (+ ~params-idx-sym ~num-params-code)
|
||||||
~s-next-fn-sym (fn [structure#]
|
~s-next-fn-sym (fn [structure#]
|
||||||
|
|
@ -85,7 +85,7 @@
|
||||||
structure#))]
|
structure#))]
|
||||||
~@s-body))
|
~@s-body))
|
||||||
|
|
||||||
(~'rich-transform* [this# ~params-sym ~params-idx-sym vals# ~t-structure-sym next-fn#]
|
(~'rich_transform [this# ~params-sym ~params-idx-sym vals# ~t-structure-sym next-fn#]
|
||||||
(let [~@binding-declarations
|
(let [~@binding-declarations
|
||||||
next-params-idx# (+ ~params-idx-sym ~num-params-code)
|
next-params-idx# (+ ~params-idx-sym ~num-params-code)
|
||||||
~t-next-fn-sym (fn [structure#]
|
~t-next-fn-sym (fn [structure#]
|
||||||
|
|
@ -95,6 +95,44 @@
|
||||||
structure#))]
|
structure#))]
|
||||||
~@t-body)))))))
|
~@t-body)))))))
|
||||||
|
|
||||||
|
(defn inline-next-fn [body next-fn-sym extra-params]
|
||||||
|
(i/codewalk-until
|
||||||
|
#(and (i/fn-invocation? %) (= next-fn-sym (first %)))
|
||||||
|
(fn [code]
|
||||||
|
(let [code (map #(inline-next-fn % next-fn-sym extra-params) code)]
|
||||||
|
(concat [next-fn-sym] extra-params (rest code))))
|
||||||
|
body))
|
||||||
|
|
||||||
|
(defn- rich-nav-with-bindings-inlined [num-params-code bindings impls]
|
||||||
|
(let [{[[_ s-structure-sym s-next-fn-sym] & s-body] 'select*
|
||||||
|
[[_ t-structure-sym t-next-fn-sym] & t-body] 'transform*}
|
||||||
|
(determine-params-impls impls)
|
||||||
|
params-sym (gensym "params")
|
||||||
|
params-idx-sym (gensym "params-idx")
|
||||||
|
vals-sym (gensym "vals")
|
||||||
|
next-params-idx-sym (gensym "next-params-idx")
|
||||||
|
s-body (inline-next-fn s-body s-next-fn-sym [params-sym next-params-idx-sym vals-sym])
|
||||||
|
t-body (inline-next-fn t-body t-next-fn-sym [params-sym next-params-idx-sym vals-sym])]
|
||||||
|
(operation-with-bindings
|
||||||
|
bindings
|
||||||
|
params-sym
|
||||||
|
params-idx-sym
|
||||||
|
(fn [binding-declarations]
|
||||||
|
`(reify RichNavigator
|
||||||
|
(~'rich_select [this# ~params-sym ~params-idx-sym ~vals-sym ~s-structure-sym ~s-next-fn-sym]
|
||||||
|
(let [~@binding-declarations
|
||||||
|
~next-params-idx-sym (+ ~params-idx-sym ~num-params-code)]
|
||||||
|
~@s-body))
|
||||||
|
|
||||||
|
(~'rich_transform [this# ~params-sym ~params-idx-sym ~vals-sym ~t-structure-sym ~t-next-fn-sym]
|
||||||
|
(let [~@binding-declarations
|
||||||
|
~next-params-idx-sym (+ ~params-idx-sym ~num-params-code)]
|
||||||
|
~@t-body)))))))
|
||||||
|
|
||||||
|
(defmacro ^:no-doc rich-nav-with-bindings [opts num-params-code bindings & impls]
|
||||||
|
(if (:inline-next-fn opts)
|
||||||
|
(rich-nav-with-bindings-inlined num-params-code bindings impls)
|
||||||
|
(rich-nav-with-bindings-not-inlined num-params-code bindings impls)))
|
||||||
|
|
||||||
|
|
||||||
(defmacro ^:no-doc collector-with-bindings [num-params-code bindings impl]
|
(defmacro ^:no-doc collector-with-bindings [num-params-code bindings impl]
|
||||||
|
|
@ -112,9 +150,9 @@
|
||||||
(next-fn# ~params-sym (+ ~params-idx-sym num-params#) (conj vals# (do ~@body)) ~structure-sym)))]
|
(next-fn# ~params-sym (+ ~params-idx-sym num-params#) (conj vals# (do ~@body)) ~structure-sym)))]
|
||||||
|
|
||||||
(reify RichNavigator
|
(reify RichNavigator
|
||||||
(~'rich-select* [this# params# params-idx# vals# structure# next-fn#]
|
(~'rich_select [this# params# params-idx# vals# structure# next-fn#]
|
||||||
(cfn# params# params-idx# vals# structure# next-fn#))
|
(cfn# params# params-idx# vals# structure# next-fn#))
|
||||||
(~'rich-transform* [this# params# params-idx# vals# structure# next-fn#]
|
(~'rich_transform [this# params# params-idx# vals# structure# next-fn#]
|
||||||
(cfn# params# params-idx# vals# structure# next-fn#))))))))
|
(cfn# params# params-idx# vals# structure# next-fn#))))))))
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -130,21 +168,25 @@
|
||||||
with other navigators without knowing the parameters. When precompiled with other
|
with other navigators without knowing the parameters. When precompiled with other
|
||||||
navigators, the resulting path takes in parameters for all navigators in the path
|
navigators, the resulting path takes in parameters for all navigators in the path
|
||||||
that needed parameters (in the order in which they were declared)."
|
that needed parameters (in the order in which they were declared)."
|
||||||
[params & impls]
|
[& impl]
|
||||||
(if (empty? params)
|
(let [[opts params & impls] (if (map? (first impl))
|
||||||
`(i/lean-compiled-path (lean-nav* ~@impls))
|
impl
|
||||||
`(vary-meta
|
(cons {} impl))]
|
||||||
(fn ~params (i/lean-compiled-path (lean-nav* ~@impls)))
|
(if (empty? params)
|
||||||
assoc
|
`(i/lean-compiled-path (lean-nav* ~@impls))
|
||||||
:highernav
|
`(vary-meta
|
||||||
{:type :lean
|
(fn ~params (i/lean-compiled-path (lean-nav* ~@impls)))
|
||||||
:params-needed-path
|
assoc
|
||||||
(i/->ParamsNeededPath
|
:highernav
|
||||||
(rich-nav-with-bindings ~(count params)
|
{:type :lean
|
||||||
~(delta-param-bindings params)
|
:params-needed-path
|
||||||
~@impls)
|
(i/->ParamsNeededPath
|
||||||
|
(rich-nav-with-bindings ~opts
|
||||||
|
~(count params)
|
||||||
|
~(delta-param-bindings params)
|
||||||
|
~@impls)
|
||||||
|
|
||||||
~(count params))})))
|
~(count params))}))))
|
||||||
|
|
||||||
|
|
||||||
(defmacro collector
|
(defmacro collector
|
||||||
|
|
@ -214,7 +256,8 @@
|
||||||
(i/lean-compiled-path (lean-nav* ~@impls)))
|
(i/lean-compiled-path (lean-nav* ~@impls)))
|
||||||
|
|
||||||
(i/->ParamsNeededPath
|
(i/->ParamsNeededPath
|
||||||
(rich-nav-with-bindings ~total-params-sym
|
(rich-nav-with-bindings {}
|
||||||
|
~total-params-sym
|
||||||
~runtime-bindings
|
~runtime-bindings
|
||||||
~@impls)
|
~@impls)
|
||||||
|
|
||||||
|
|
@ -297,13 +340,13 @@
|
||||||
`(do
|
`(do
|
||||||
(defprotocol ~prot-name (~m [structure#]))
|
(defprotocol ~prot-name (~m [structure#]))
|
||||||
(let [nav# (reify RichNavigator
|
(let [nav# (reify RichNavigator
|
||||||
(~'rich-select* [this# ~@rargs]
|
(~'rich_select [this# ~@rargs]
|
||||||
(let [inav# ~retrieve]
|
(let [inav# ~retrieve]
|
||||||
(i/exec-rich-select* inav# ~@rargs)))
|
(i/exec-rich_select inav# ~@rargs)))
|
||||||
|
|
||||||
(~'rich-transform* [this# ~@rargs]
|
(~'rich_transform [this# ~@rargs]
|
||||||
(let [inav# ~retrieve]
|
(let [inav# ~retrieve]
|
||||||
(i/exec-rich-transform* inav# ~@rargs))))]
|
(i/exec-rich_transform inav# ~@rargs))))]
|
||||||
|
|
||||||
(def ~name
|
(def ~name
|
||||||
(if (= ~num-params 0)
|
(if (= ~num-params 0)
|
||||||
|
|
@ -325,11 +368,11 @@
|
||||||
([name params]
|
([name params]
|
||||||
(let [platform (if (contains? &env :locals) :cljs :clj)
|
(let [platform (if (contains? &env :locals) :cljs :clj)
|
||||||
select-exec (if (= platform :clj)
|
select-exec (if (= platform :clj)
|
||||||
`i/exec-rich-select*
|
`i/exec-rich_select
|
||||||
`i/rich-select*)
|
`i/rich_select)
|
||||||
transform-exec (if (= platform :clj)
|
transform-exec (if (= platform :clj)
|
||||||
`i/exec-rich-transform*
|
`i/exec-rich_transform
|
||||||
`i/rich-transform*)
|
`i/rich_transform)
|
||||||
num-params (count params)
|
num-params (count params)
|
||||||
declared (declared-name name)
|
declared (declared-name name)
|
||||||
rargs [(gensym "params") (gensym "pidx") (gensym "vals")
|
rargs [(gensym "params") (gensym "pidx") (gensym "vals")
|
||||||
|
|
@ -338,9 +381,9 @@
|
||||||
(declare ~declared)
|
(declare ~declared)
|
||||||
(def ~name
|
(def ~name
|
||||||
(let [nav# (reify RichNavigator
|
(let [nav# (reify RichNavigator
|
||||||
(~'rich-select* [this# ~@rargs]
|
(~'rich_select [this# ~@rargs]
|
||||||
(~select-exec ~declared ~@rargs))
|
(~select-exec ~declared ~@rargs))
|
||||||
(~'rich-transform* [this# ~@rargs]
|
(~'rich_transform [this# ~@rargs]
|
||||||
(~transform-exec ~declared ~@rargs)))]
|
(~transform-exec ~declared ~@rargs)))]
|
||||||
|
|
||||||
(if (= ~num-params 0)
|
(if (= ~num-params 0)
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,14 @@
|
||||||
[doseqres]]))
|
[doseqres]]))
|
||||||
|
|
||||||
(:use #?(:clj [com.rpl.specter macros])
|
(:use #?(:clj [com.rpl.specter macros])
|
||||||
#?(:clj [com.rpl.specter.util-macros :only [doseqres]]))
|
#?(:clj [com.rpl.specter.util-macros :only [doseqres]])
|
||||||
|
#?(:cljs [com.rpl.specter.impl :only [RichNavigator]]))
|
||||||
(:require [com.rpl.specter.impl :as i]
|
(:require [com.rpl.specter.impl :as i]
|
||||||
[clojure.walk :as walk]
|
[clojure.walk :as walk]
|
||||||
#?(:clj [clojure.core.reducers :as r])
|
#?(:clj [clojure.core.reducers :as r])
|
||||||
[com.rpl.specter.defnavhelpers])) ; so that for cljs it's loaded as macros expand to this
|
; so that for cljs it's loaded as macros expand to this
|
||||||
|
[com.rpl.specter.defnavhelpers])
|
||||||
|
#?(:clj (:import [com.rpl.specter.impl RichNavigator])))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -293,7 +296,7 @@
|
||||||
then-nav
|
then-nav
|
||||||
else-nav)
|
else-nav)
|
||||||
idx (if test? params-idx (+ params-idx then-params))]
|
idx (if test? params-idx (+ params-idx then-params))]
|
||||||
(i/exec-rich-select*
|
(i/exec-rich_select
|
||||||
sel
|
sel
|
||||||
params
|
params
|
||||||
idx
|
idx
|
||||||
|
|
@ -309,7 +312,7 @@
|
||||||
then-nav
|
then-nav
|
||||||
else-nav)
|
else-nav)
|
||||||
idx (if test? params-idx (+ params-idx then-params))]
|
idx (if test? params-idx (+ params-idx then-params))]
|
||||||
(i/exec-rich-transform*
|
(i/exec-rich_transform
|
||||||
tran
|
tran
|
||||||
params
|
params
|
||||||
idx
|
idx
|
||||||
|
|
@ -460,19 +463,11 @@
|
||||||
(walk/walk (partial walk-until pred on-match-fn) identity structure)))
|
(walk/walk (partial walk-until pred on-match-fn) identity structure)))
|
||||||
|
|
||||||
|
|
||||||
(defn codewalk-until [pred on-match-fn structure]
|
|
||||||
(if (pred structure)
|
|
||||||
(on-match-fn structure)
|
|
||||||
(let [ret (walk/walk (partial codewalk-until pred on-match-fn) identity structure)]
|
|
||||||
(if (and (i/fn-invocation? structure) (i/fn-invocation? ret))
|
|
||||||
(with-meta ret (meta structure))
|
|
||||||
ret))))
|
|
||||||
|
|
||||||
|
|
||||||
(def DISPENSE*
|
(def DISPENSE*
|
||||||
(i/no-params-rich-compiled-path
|
(i/no-params-rich-compiled-path
|
||||||
(reify i/RichNavigator
|
(reify RichNavigator
|
||||||
(rich-select* [this params params-idx vals structure next-fn]
|
(rich_select [this params params-idx vals structure next-fn]
|
||||||
(next-fn params params-idx [] structure))
|
(next-fn params params-idx [] structure))
|
||||||
(rich-transform* [this params params-idx vals structure next-fn]
|
(rich_transform [this params params-idx vals structure next-fn]
|
||||||
(next-fn params params-idx [] structure)))))
|
(next-fn params params-idx [] structure)))))
|
||||||
|
|
|
||||||
|
|
@ -10,3 +10,12 @@
|
||||||
|
|
||||||
~backup-res
|
~backup-res
|
||||||
~aseq))
|
~aseq))
|
||||||
|
|
||||||
|
|
||||||
|
(defmacro definterface+ [name & methods]
|
||||||
|
(let [platform (if (contains? &env :locals) :cljs :clj)]
|
||||||
|
(if (= platform :cljs)
|
||||||
|
`(defprotocol ~name ~@methods)
|
||||||
|
(let [methods (for [[n p & body] methods]
|
||||||
|
(concat [n (-> p next vec)] body))]
|
||||||
|
`(definterface ~name ~@methods)))))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue