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
|
||||
:dependencies [[riddley "0.1.12"]]
|
||||
:profiles {:provided {:dependencies
|
||||
[[org.clojure/clojure "1.6.0"]
|
||||
[org.clojure/clojurescript "0.0-3211"]]}
|
||||
[[org.clojure/clojure "1.7.0"]
|
||||
[org.clojure/clojurescript "1.7.10"]]}
|
||||
:dev {:dependencies
|
||||
[[org.clojure/test.check "0.7.0"]]
|
||||
:plugins
|
||||
|
|
|
|||
|
|
@ -374,7 +374,7 @@
|
|||
The input path may be parameterized, in which case the result of transformed
|
||||
will be parameterized in the order of which the parameterized navigators
|
||||
were declared."
|
||||
[path update-fn]
|
||||
[path ^:notpath update-fn]
|
||||
(fixed-pathed-nav [late path]
|
||||
(select* [this structure next-fn]
|
||||
(next-fn (compiled-transform late update-fn structure)))
|
||||
|
|
|
|||
|
|
@ -857,6 +857,26 @@
|
|||
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]
|
||||
(let [magic-fail! (fn [& reason]
|
||||
(if (get-cell MUST-CACHE-PATHS)
|
||||
|
|
@ -908,9 +928,37 @@
|
|||
vv
|
||||
)
|
||||
|
||||
(and (fn? vv) (-> vv meta :pathedfn))
|
||||
(let [subpath (mapv #(magic-precompilation* % params-atom failed-atom)
|
||||
ps)]
|
||||
(and (fn? vv) (-> v meta :pathedfn))
|
||||
;;TODO: update this to ignore args that aren't symbols or have :nopath
|
||||
;;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
|
||||
nil
|
||||
(apply vv subpath)
|
||||
|
|
|
|||
|
|
@ -339,8 +339,9 @@
|
|||
[(with-meta name attr) macro-args]))
|
||||
|
||||
(defmacro defpathedfn [name & args]
|
||||
(let [[name args] (name-with-attributes name args)]
|
||||
`(def ~name (vary-meta (fn ~@args) assoc :pathedfn true))))
|
||||
(let [[name args] (name-with-attributes name args)
|
||||
name (vary-meta name assoc :pathedfn true)]
|
||||
`(defn ~name ~@args)))
|
||||
|
||||
(defmacro defnavconstructor [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 :b] [:b :a] [:c :d] [:b :c]]
|
||||
)
|
||||
(ic-test
|
||||
true
|
||||
[]
|
||||
[(s/transformed s/STAY inc)]
|
||||
inc
|
||||
10
|
||||
[]
|
||||
)
|
||||
|
||||
(s/must-cache-paths!)
|
||||
(is (thrown? #+clj Exception #+cljs js/Error
|
||||
|
|
@ -947,6 +955,11 @@
|
|||
(is (thrown? #+clj Exception #+cljs js/Error
|
||||
(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]
|
||||
(is (thrown? #+clj Exception #+cljs js/Error
|
||||
(select [p even?] {:a 2})
|
||||
|
|
@ -991,3 +1004,10 @@
|
|||
[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