add :notpath metadata for pathedfn args that should not be interpreted as paths during inline factoring/caching, fixed transformed to operate appropriately in inline factoring when transform-fn is anonymous or local, drop support for cljs below v1.7.10
This commit is contained in:
parent
8a0ba0b3b0
commit
52740d56ac
5 changed files with 77 additions and 8 deletions
|
|
@ -9,8 +9,8 @@
|
||||||
:auto-clean false
|
:auto-clean false
|
||||||
:dependencies [[riddley "0.1.12"]]
|
:dependencies [[riddley "0.1.12"]]
|
||||||
:profiles {:provided {:dependencies
|
:profiles {:provided {:dependencies
|
||||||
[[org.clojure/clojure "1.6.0"]
|
[[org.clojure/clojure "1.7.0"]
|
||||||
[org.clojure/clojurescript "0.0-3211"]]}
|
[org.clojure/clojurescript "1.7.10"]]}
|
||||||
:dev {:dependencies
|
:dev {:dependencies
|
||||||
[[org.clojure/test.check "0.7.0"]]
|
[[org.clojure/test.check "0.7.0"]]
|
||||||
:plugins
|
:plugins
|
||||||
|
|
|
||||||
|
|
@ -374,7 +374,7 @@
|
||||||
The input path may be parameterized, in which case the result of transformed
|
The input path may be parameterized, in which case the result of transformed
|
||||||
will be parameterized in the order of which the parameterized navigators
|
will be parameterized in the order of which the parameterized navigators
|
||||||
were declared."
|
were declared."
|
||||||
[path update-fn]
|
[path ^:notpath update-fn]
|
||||||
(fixed-pathed-nav [late path]
|
(fixed-pathed-nav [late path]
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(next-fn (compiled-transform late update-fn structure)))
|
(next-fn (compiled-transform late update-fn structure)))
|
||||||
|
|
|
||||||
|
|
@ -857,6 +857,26 @@
|
||||||
1
|
1
|
||||||
))
|
))
|
||||||
|
|
||||||
|
(defn- variadic-arglist? [al]
|
||||||
|
(contains? (set al) '&))
|
||||||
|
|
||||||
|
(defn- arglist-for-params-count [arglists c code]
|
||||||
|
(let [ret (->> arglists
|
||||||
|
(filter
|
||||||
|
(fn [al]
|
||||||
|
(or (= (count al) c)
|
||||||
|
(variadic-arglist? al))
|
||||||
|
))
|
||||||
|
first)
|
||||||
|
len (count ret)]
|
||||||
|
(when-not ret
|
||||||
|
(throw-illegal "Invalid # arguments at " code))
|
||||||
|
(if (variadic-arglist? ret)
|
||||||
|
(srange-transform ret (- len 2) len
|
||||||
|
(fn [_] (repeatedly (- c (- len 2)) gensym)))
|
||||||
|
ret
|
||||||
|
)))
|
||||||
|
|
||||||
(defn- magic-precompilation* [p params-atom failed-atom]
|
(defn- magic-precompilation* [p params-atom failed-atom]
|
||||||
(let [magic-fail! (fn [& reason]
|
(let [magic-fail! (fn [& reason]
|
||||||
(if (get-cell MUST-CACHE-PATHS)
|
(if (get-cell MUST-CACHE-PATHS)
|
||||||
|
|
@ -908,9 +928,37 @@
|
||||||
vv
|
vv
|
||||||
)
|
)
|
||||||
|
|
||||||
(and (fn? vv) (-> vv meta :pathedfn))
|
(and (fn? vv) (-> v meta :pathedfn))
|
||||||
(let [subpath (mapv #(magic-precompilation* % params-atom failed-atom)
|
;;TODO: update this to ignore args that aren't symbols or have :nopath
|
||||||
ps)]
|
;;metadata on them (in the arglist)
|
||||||
|
(let [arglists (-> v meta :arglists)
|
||||||
|
al (arglist-for-params-count arglists (count ps) (:code p))
|
||||||
|
subpath (vec
|
||||||
|
(map
|
||||||
|
(fn [pdecl p]
|
||||||
|
(if (and (symbol? pdecl)
|
||||||
|
(-> pdecl meta :notpath not))
|
||||||
|
(magic-precompilation* p params-atom failed-atom)
|
||||||
|
|
||||||
|
(cond (and (instance? VarUse p)
|
||||||
|
(-> p :var meta :dynamic not))
|
||||||
|
(:val p)
|
||||||
|
|
||||||
|
(and (not (instance? LocalSym p))
|
||||||
|
(not (instance? VarUse p))
|
||||||
|
(not (instance? SpecialFormUse p))
|
||||||
|
(not (instance? FnInvocation p))
|
||||||
|
(not (coll? p)))
|
||||||
|
p
|
||||||
|
|
||||||
|
:else
|
||||||
|
(magic-fail! "Could not factor static param "
|
||||||
|
"of pathedfn because it's not a static var "
|
||||||
|
" or non-collection value: "
|
||||||
|
(extract-original-code p))
|
||||||
|
)))
|
||||||
|
al
|
||||||
|
ps))]
|
||||||
(if @failed-atom
|
(if @failed-atom
|
||||||
nil
|
nil
|
||||||
(apply vv subpath)
|
(apply vv subpath)
|
||||||
|
|
|
||||||
|
|
@ -339,8 +339,9 @@
|
||||||
[(with-meta name attr) macro-args]))
|
[(with-meta name attr) macro-args]))
|
||||||
|
|
||||||
(defmacro defpathedfn [name & args]
|
(defmacro defpathedfn [name & args]
|
||||||
(let [[name args] (name-with-attributes name args)]
|
(let [[name args] (name-with-attributes name args)
|
||||||
`(def ~name (vary-meta (fn ~@args) assoc :pathedfn true))))
|
name (vary-meta name assoc :pathedfn true)]
|
||||||
|
`(defn ~name ~@args)))
|
||||||
|
|
||||||
(defmacro defnavconstructor [name & args]
|
(defmacro defnavconstructor [name & args]
|
||||||
(let [[name [[csym anav] & body-or-bodies]] (name-with-attributes name args)
|
(let [[name [[csym anav] & body-or-bodies]] (name-with-attributes name args)
|
||||||
|
|
|
||||||
|
|
@ -936,6 +936,14 @@
|
||||||
[{:a 1 :b 2} {:a 10 :b 6} {:c 7 :b 8} {:c 1 :d 9} {:c 3 :d -1}]
|
[{:a 1 :b 2} {:a 10 :b 6} {:c 7 :b 8} {:c 1 :d 9} {:c 3 :d -1}]
|
||||||
[[:a :b] [:b :a] [:c :d] [:b :c]]
|
[[:a :b] [:b :a] [:c :d] [:b :c]]
|
||||||
)
|
)
|
||||||
|
(ic-test
|
||||||
|
true
|
||||||
|
[]
|
||||||
|
[(s/transformed s/STAY inc)]
|
||||||
|
inc
|
||||||
|
10
|
||||||
|
[]
|
||||||
|
)
|
||||||
|
|
||||||
(s/must-cache-paths!)
|
(s/must-cache-paths!)
|
||||||
(is (thrown? #+clj Exception #+cljs js/Error
|
(is (thrown? #+clj Exception #+cljs js/Error
|
||||||
|
|
@ -947,6 +955,11 @@
|
||||||
(is (thrown? #+clj Exception #+cljs js/Error
|
(is (thrown? #+clj Exception #+cljs js/Error
|
||||||
(select [:a (identity even?)] {:a 2})
|
(select [:a (identity even?)] {:a 2})
|
||||||
))
|
))
|
||||||
|
;; this tests a bug that existed before ^:staticparam annotation
|
||||||
|
;; for pathedfns
|
||||||
|
(is (thrown? #+clj Exception #+cljs js/Error
|
||||||
|
(select [(s/putval 10) (s/transformed s/STAY #(inc %))] 10)
|
||||||
|
))
|
||||||
(let [p :a]
|
(let [p :a]
|
||||||
(is (thrown? #+clj Exception #+cljs js/Error
|
(is (thrown? #+clj Exception #+cljs js/Error
|
||||||
(select [p even?] {:a 2})
|
(select [p even?] {:a 2})
|
||||||
|
|
@ -991,3 +1004,10 @@
|
||||||
[1 "a" "b" 2 3 "c" 4 5 6 "d" "e" "f"]
|
[1 "a" "b" 2 3 "c" 4 5 6 "d" "e" "f"]
|
||||||
)))
|
)))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
;; there was a bug where the transform-fn was being factored by inline caching
|
||||||
|
;; this verifies that it doesn't do inline caching
|
||||||
|
(deftest transformed-inline-caching
|
||||||
|
(dotimes [i 10]
|
||||||
|
(is (= [(inc i)] (select (s/transformed s/STAY #(+ % i)) 1)))
|
||||||
|
))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue