Skip to content

Commit 4fb83ef

Browse files
mfikesswannodette
authored andcommitted
CLJS-2793: Instrumenting breaks function with varargs
1 parent 5cc0e6c commit 4fb83ef

File tree

3 files changed

+76
-16
lines changed

3 files changed

+76
-16
lines changed

src/main/cljs/cljs/spec/test/alpha.cljc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,3 +279,17 @@ spec itself will have an ::s/failure value in ex-data:
279279
(map
280280
(fn [sym]
281281
(do `(check-1 '~sym nil nil ~opts-sym)))))]))))
282+
283+
(defmacro ^:private maybe-setup-static-dispatch [f ret arity]
284+
(let [arity-accessor (symbol (str ".-cljs$core$IFn$_invoke$arity$" arity))
285+
argv (mapv #(symbol (str "arg" %)) (range arity))]
286+
`(when (some? (~arity-accessor ~f))
287+
(set! (~arity-accessor ~ret)
288+
(fn ~argv
289+
(apply ~ret ~argv))))))
290+
291+
(defmacro ^:private setup-static-dispatches [f ret max-arity]
292+
`(do
293+
~@(mapv (fn [arity]
294+
`(maybe-setup-static-dispatch ~f ~ret ~arity))
295+
(range (inc max-arity)))))

src/main/cljs/cljs/spec/test/alpha.cljs

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
; You must not remove this notice, or any other, from this software.
88

99
(ns cljs.spec.test.alpha
10-
(:require-macros [cljs.spec.test.alpha :as m :refer [with-instrument-disabled]])
10+
(:require-macros [cljs.spec.test.alpha :as m :refer [with-instrument-disabled setup-static-dispatches]])
1111
(:require
1212
[goog.object :as gobj]
1313
[goog.userAgent.product :as product]
@@ -104,21 +104,22 @@
104104
(throw (ex-info
105105
(str "Call to " v " did not conform to spec." )
106106
ed)))
107-
conformed)))]
108-
(doto (fn [& args]
109-
(if *instrument-enabled*
110-
(with-instrument-disabled
111-
(when (:args fn-spec) (conform! v :args (:args fn-spec) args args))
112-
(binding [*instrument-enabled* true]
113-
(apply f args)))
114-
(apply f args)))
115-
(gobj/extend (MetaFn. (fn [& args]
116-
(if *instrument-enabled*
117-
(with-instrument-disabled
118-
(when (:args fn-spec) (conform! v :args (:args fn-spec) args args))
119-
(binding [*instrument-enabled* true]
120-
(apply f args)))
121-
(apply f args))) nil)))))
107+
conformed)))
108+
ret (fn [& args]
109+
(if *instrument-enabled*
110+
(with-instrument-disabled
111+
(when (:args fn-spec) (conform! v :args (:args fn-spec) args args))
112+
(binding [*instrument-enabled* true]
113+
(apply f args)))
114+
(apply f args)))]
115+
(when-not (and (-> (meta v) :top-fn :variadic?)
116+
(zero? (-> (meta v) :top-fn :max-fixed-arity)))
117+
(setup-static-dispatches f ret 20)
118+
(when-some [variadic (.-cljs$core$IFn$_invoke$arity$variadic f)]
119+
(set! (.-cljs$core$IFn$_invoke$arity$variadic ret)
120+
(fn [& args]
121+
(apply variadic args)))))
122+
ret))
122123

123124
(defn- no-fspec
124125
[v spec]

src/test/cljs/cljs/spec_test.cljs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,51 @@
368368
:args (s/cat :k keyword?)
369369
:ret string?)
370370

371+
(defn foo-2793 [m & args]
372+
{:m m, :args args})
373+
374+
(defn bar-2793
375+
([x] {:x x})
376+
([x y] {:x x, :y y})
377+
([x y & m] {:x x, :y y, :m m}))
378+
379+
(defn baz-2793 [x & ys])
380+
381+
(defn quux-2793 [& numbers])
382+
383+
(s/fdef foo-2793)
384+
(s/fdef bar-2793)
385+
(s/fdef baz-2793 :args (s/cat :x number? :ys (s/* number?)))
386+
387+
(st/instrument `foo-2793)
388+
(st/instrument `bar-2793)
389+
(st/instrument `baz-2793)
390+
391+
(deftest cljs-2793-test
392+
(is (= {:m {:x 1 :y 2}
393+
:args nil}
394+
(foo-2793 {:x 1 :y 2})))
395+
(is (= {:m {:x 1 :y 2}
396+
:args [1]}
397+
(foo-2793 {:x 1 :y 2} 1)))
398+
(is (= {:m {:x 1 :y 2}
399+
:args [1 2]}
400+
(foo-2793 {:x 1 :y 2} 1 2)))
401+
(is (= {:x 1}
402+
(bar-2793 1)))
403+
(is (= {:x 1
404+
:y 2}
405+
(bar-2793 1 2)))
406+
(is (= {:x 1
407+
:y 2
408+
:m [3]}
409+
(bar-2793 1 2 3)))
410+
(is (= {:x 1
411+
:y 2
412+
:m [3 4]}
413+
(bar-2793 1 2 3 4)))
414+
(is (nil? (baz-2793 1))))
415+
371416
(comment
372417

373418
(run-tests)

0 commit comments

Comments
 (0)