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

View file

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

View file

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

View file

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

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