From 94a67744c72d56c511701defb535d8bd924a1034 Mon Sep 17 00:00:00 2001 From: Nathan Marz Date: Mon, 15 Aug 2016 05:34:55 -0400 Subject: [PATCH] switched RichNavigator over to using definterface for clj, still need to change how rich navigator next-fn works to support primitive long --- project.clj | 4 +- src/clj/com/rpl/specter.cljc | 12 +-- src/clj/com/rpl/specter/defnavhelpers.cljc | 8 +- src/clj/com/rpl/specter/impl.cljc | 90 ++++++++++++---------- src/clj/com/rpl/specter/macros.clj | 42 +++++----- src/clj/com/rpl/specter/navs.cljc | 17 ++-- src/clj/com/rpl/specter/util_macros.clj | 9 +++ 7 files changed, 101 insertions(+), 81 deletions(-) diff --git a/project.clj b/project.clj index fc09529..bc8cc08 100644 --- a/project.clj +++ b/project.clj @@ -1,8 +1,8 @@ (def VERSION (.trim (slurp "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 - ;"-agentpath:/Applications/YourKit_Java_Profiler_2015_build_15056.app/Contents/Resources/bin/mac/libyjpagent.jnilib"] + :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"] :source-paths ["src/clj"] :java-source-paths ["src/java"] diff --git a/src/clj/com/rpl/specter.cljc b/src/clj/com/rpl/specter.cljc index 0acb7fc..a4475b2 100644 --- a/src/clj/com/rpl/specter.cljc +++ b/src/clj/com/rpl/specter.cljc @@ -175,9 +175,9 @@ needed (i/num-needed-params params-path)] (richnav 0 (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] - (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 @@ -725,15 +725,15 @@ (richnav (+ comp1-needed (i/num-needed-params comp2)) (select* [this 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)] + (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)] (if (identical? NONE res2) res1 res2))) (transform* [this 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)))))) + (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)))))) ([path1 path2 & paths] (reduce multi-path (multi-path path1 path2) paths))) diff --git a/src/clj/com/rpl/specter/defnavhelpers.cljc b/src/clj/com/rpl/specter/defnavhelpers.cljc index 5b16560..24b9613 100644 --- a/src/clj/com/rpl/specter/defnavhelpers.cljc +++ b/src/clj/com/rpl/specter/defnavhelpers.cljc @@ -1,13 +1,13 @@ (ns com.rpl.specter.defnavhelpers (:require [com.rpl.specter.impl :as i])) -(defn param-delta [i] - (fn [^objects params params-idx] +(defn param-delta [^long i] + (fn [^objects params ^long params-idx] (aget params (+ params-idx i)))) -(defn bound-params [path start-delta] - (fn [^objects params params-idx] +(defn bound-params [path ^long start-delta] + (fn [^objects params ^long params-idx] (if (i/params-needed-path? path) (i/bind-params* path params (+ params-idx start-delta)) path))) diff --git a/src/clj/com/rpl/specter/impl.cljc b/src/clj/com/rpl/specter/impl.cljc index a5479dd..a7f6fef 100644 --- a/src/clj/com/rpl/specter/impl.cljc +++ b/src/clj/com/rpl/specter/impl.cljc @@ -1,11 +1,11 @@ (ns com.rpl.specter.impl #?(:cljs (:require-macros [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 [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] [clojure.string :as s] @@ -104,35 +104,35 @@ (deftype ExecutorFunctions [traverse-executor transform-executor]) -(deftype ParameterizedRichNav [rich-nav params params-idx]) +(deftype ParameterizedRichNav [rich-nav params ^long params-idx]) -(defprotocol RichNavigator - (rich-select* [this params params-idx vals structure next-fn]) - (rich-transform* [this params params-idx vals structure next-fn])) +(definterface+ RichNavigator + (rich_select [this params ^long params-idx vals structure next-fn]) + (rich_transform [this params ^long params-idx vals structure next-fn])) #?( :clj - (defmacro exec-rich-select* [this & args] + (defmacro exec-rich_select [this & args] (let [hinted (with-meta this {:tag 'com.rpl.specter.impl.RichNavigator})] - `(.rich-select* ~hinted ~@args))) + `(.rich_select ~hinted ~@args))) :cljs - (defn exec-rich-select* [this params params-idx vals structure next-fn] - (rich-select* ^not-native 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))) #?( :clj - (defmacro exec-rich-transform* [this & args] + (defmacro exec-rich_transform [this & args] (let [hinted (with-meta this {:tag 'com.rpl.specter.impl.RichNavigator})] - `(.rich-transform* ~hinted ~@args))) + `(.rich_transform ~hinted ~@args))) :cljs - (defn exec-rich-transform* [this params params-idx vals structure next-fn] - (rich-transform* ^not-native 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))) #?( @@ -162,7 +162,7 @@ (def RichPathExecutor (->ExecutorFunctions (fn [^ParameterizedRichNav richnavp result-fn structure] - (exec-rich-select* (.-rich-nav richnavp) + (exec-rich_select (.-rich-nav richnavp) (.-params richnavp) (.-params-idx richnavp) [] structure (fn [_ _ vals structure] @@ -171,7 +171,7 @@ structure (conj vals structure)))))) (fn [^ParameterizedRichNav richnavp transform-fn structure] - (exec-rich-transform* (.-rich-nav richnavp) + (exec-rich_transform (.-rich-nav richnavp) (.-params richnavp) (.-params-idx richnavp) [] structure (fn [_ _ vals structure] @@ -326,22 +326,30 @@ (coerce-path [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]] (let [combiner - (if (satisfies? RichNavigator n) + (if (rich-nav? n) (fn [curr next] (reify RichNavigator - (rich-select* [this params params-idx vals structure next-fn] - (exec-rich-select* curr params params-idx vals structure + (rich_select [this params params-idx vals structure next-fn] + (exec-rich_select curr params params-idx vals structure (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)))) - (rich-transform* [this params params-idx vals structure next-fn] - (exec-rich-transform* curr params params-idx vals structure + (rich_transform [this params params-idx vals structure next-fn] + (exec-rich_transform curr params params-idx vals structure (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)))))) (fn [curr next] @@ -357,13 +365,13 @@ (reduce combiner all))) (defn coerce-rich-navigator [nav] - (if (satisfies? RichNavigator nav) + (if (rich-nav? nav) nav (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)))) - (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))))))) @@ -387,13 +395,13 @@ path (no-params-rich-compiled-path (reify RichNavigator - (rich-select* [this params2 params-idx2 vals structure next-fn] - (exec-rich-select* rich-nav params params-idx vals structure + (rich_select [this params2 params-idx2 vals structure next-fn] + (exec-rich_select rich-nav params params-idx vals structure (fn [_ _ vals-next structure-next] (next-fn params2 params-idx2 vals-next structure-next)))) - (rich-transform* [this params2 params-idx2 vals structure next-fn] - (exec-rich-transform* rich-nav params params-idx vals structure + (rich_transform [this params2 params-idx2 vals structure next-fn] + (exec-rich_transform rich-nav params params-idx vals structure (fn [_ _ vals-next structure-next] (next-fn params2 params-idx2 vals-next structure-next)))))))))) @@ -402,7 +410,7 @@ (capture-params-internally (comp-paths* path))) (defn nav-type [n] - (if (satisfies? RichNavigator n) + (if (rich-nav? n) :rich :lean)) @@ -775,13 +783,13 @@ (def pred* (->ParamsNeededPath (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)] (if (afn structure) (next-fn params (inc params-idx) vals structure) 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)] (if (afn structure) (next-fn params (inc params-idx) vals structure) @@ -793,13 +801,13 @@ (def collected?* (->ParamsNeededPath (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)] (if (afn vals) (next-fn params (inc params-idx) vals structure) 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)] (if (afn vals) (next-fn params (inc params-idx) vals structure) @@ -811,11 +819,11 @@ (def rich-compiled-path-proxy (->ParamsNeededPath (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) pnav ^ParameterizedRichNav (.-nav apath) nav (.-rich-nav pnav)] - (exec-rich-select* + (exec-rich_select nav (.-params pnav) (.-params-idx pnav) @@ -824,11 +832,11 @@ (fn [_ _ 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) pnav ^ParameterizedRichNav (.-nav apath) nav (.-rich-nav pnav)] - (exec-rich-transform* + (exec-rich_transform nav (.-params pnav) (.-params-idx pnav) @@ -843,7 +851,7 @@ (def lean-compiled-path-proxy (->ParamsNeededPath (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) ^Navigator nav (.-nav apath)] (exec-select* @@ -852,7 +860,7 @@ (fn [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) ^Navigator nav (.-nav apath)] (exec-transform* diff --git a/src/clj/com/rpl/specter/macros.clj b/src/clj/com/rpl/specter/macros.clj index 4ae626d..1f101d1 100644 --- a/src/clj/com/rpl/specter/macros.clj +++ b/src/clj/com/rpl/specter/macros.clj @@ -1,9 +1,9 @@ (ns com.rpl.specter.macros - (:use [com.rpl.specter.protocols :only [Navigator]] - [com.rpl.specter.impl :only [RichNavigator]]) + (:use [com.rpl.specter.protocols :only [Navigator]]) (:require [com.rpl.specter.impl :as i] [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] @@ -34,10 +34,10 @@ `(let [num-params# ~num-params 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#)] ~@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#)] ~@t-body)))] @@ -75,7 +75,7 @@ params-idx-sym (fn [binding-declarations] `(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 next-params-idx# (+ ~params-idx-sym ~num-params-code) ~s-next-fn-sym (fn [structure#] @@ -85,7 +85,7 @@ structure#))] ~@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 next-params-idx# (+ ~params-idx-sym ~num-params-code) ~t-next-fn-sym (fn [structure#] @@ -119,12 +119,12 @@ 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] + (~'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] + (~'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))))))) @@ -150,9 +150,9 @@ (next-fn# ~params-sym (+ ~params-idx-sym num-params#) (conj vals# (do ~@body)) ~structure-sym)))] (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#)) - (~'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#)))))))) @@ -340,13 +340,13 @@ `(do (defprotocol ~prot-name (~m [structure#])) (let [nav# (reify RichNavigator - (~'rich-select* [this# ~@rargs] + (~'rich_select [this# ~@rargs] (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] - (i/exec-rich-transform* inav# ~@rargs))))] + (i/exec-rich_transform inav# ~@rargs))))] (def ~name (if (= ~num-params 0) @@ -368,11 +368,11 @@ ([name params] (let [platform (if (contains? &env :locals) :cljs :clj) select-exec (if (= platform :clj) - `i/exec-rich-select* - `i/rich-select*) + `i/exec-rich_select + `i/rich_select) transform-exec (if (= platform :clj) - `i/exec-rich-transform* - `i/rich-transform*) + `i/exec-rich_transform + `i/rich_transform) num-params (count params) declared (declared-name name) rargs [(gensym "params") (gensym "pidx") (gensym "vals") @@ -381,9 +381,9 @@ (declare ~declared) (def ~name (let [nav# (reify RichNavigator - (~'rich-select* [this# ~@rargs] + (~'rich_select [this# ~@rargs] (~select-exec ~declared ~@rargs)) - (~'rich-transform* [this# ~@rargs] + (~'rich_transform [this# ~@rargs] (~transform-exec ~declared ~@rargs)))] (if (= ~num-params 0) diff --git a/src/clj/com/rpl/specter/navs.cljc b/src/clj/com/rpl/specter/navs.cljc index 2ea2d0f..7168039 100644 --- a/src/clj/com/rpl/specter/navs.cljc +++ b/src/clj/com/rpl/specter/navs.cljc @@ -14,11 +14,14 @@ [doseqres]])) (: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] [clojure.walk :as walk] #?(: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 else-nav) idx (if test? params-idx (+ params-idx then-params))] - (i/exec-rich-select* + (i/exec-rich_select sel params idx @@ -309,7 +312,7 @@ then-nav else-nav) idx (if test? params-idx (+ params-idx then-params))] - (i/exec-rich-transform* + (i/exec-rich_transform tran params idx @@ -463,8 +466,8 @@ (def DISPENSE* (i/no-params-rich-compiled-path - (reify i/RichNavigator - (rich-select* [this params params-idx vals structure next-fn] + (reify RichNavigator + (rich_select [this params params-idx vals structure next-fn] (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))))) diff --git a/src/clj/com/rpl/specter/util_macros.clj b/src/clj/com/rpl/specter/util_macros.clj index 6850812..4362cbd 100644 --- a/src/clj/com/rpl/specter/util_macros.clj +++ b/src/clj/com/rpl/specter/util_macros.clj @@ -10,3 +10,12 @@ ~backup-res ~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)))))