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:
Nathan Marz 2016-06-02 02:42:18 -04:00
parent 8a0ba0b3b0
commit 52740d56ac
5 changed files with 77 additions and 8 deletions

View file

@ -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

View file

@ -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)))

View file

@ -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)

View file

@ -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)

View file

@ -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)))
))