88
99(ns cljs.spec
1010 (:refer-clojure :exclude [+ * and or cat def keys resolve])
11- (:require [cljs.analyzer.api :refer [resolve]]
11+ (:require [cljs.analyzer :as ana]
12+ [cljs.analyzer.api :refer [resolve]]
1213 [clojure.walk :as walk]
1314 [cljs.spec.impl.gen :as gen]
1415 [clojure.string :as str]))
3536 (sequential? form) (walk/postwalk #(if (symbol? %) (res env %) %) (unfn form))
3637 :else form))
3738
39+ (defn- ns-qualify
40+ " Qualify symbol s by resolving it or using the current *ns*."
41+ [env s]
42+ (if (namespace s)
43+ (let [v (resolve env s)]
44+ (assert v (str " Unable to resolve: " s))
45+ (->sym v))
46+ (symbol (str ana/*cljs-ns*) (str s))))
47+
3848(defmacro def
39- " Given a namespace-qualified keyword or symbol k, and a spec, spec-name, predicate or regex-op
40- makes an entry in the registry mapping k to the spec"
49+ " Given a namespace-qualified keyword or resolveable symbol k, and a spec,
50+ spec-name, predicate or regex-op makes an entry in the registry mapping k to
51+ the spec"
4152 [k spec-form]
42- `(cljs.spec/def-impl ~k '~(res &env spec-form) ~spec-form))
53+ (let [k (if (symbol? k) (ns-qualify &env k) k)]
54+ `(cljs.spec/def-impl '~k '~(res &env spec-form) ~spec-form)))
4355
4456(defmacro spec
4557 " Takes a single predicate form, e.g. can be the name of a predicate,
248260 and returns a spec whose conform/explain take a fn and validates it
249261 using generative testing. The conformed value is always the fn itself.
250262
263+ See 'fdef' for a single operation that creates an fspec and
264+ registers it, as well as a full description of :args, :ret and :fn
265+
251266 Optionally takes :gen generator-fn, which must be a fn of no args
252267 that returns a test.check generator."
253268 [& {:keys [args ret fn gen]}]
264279 (assert (not (empty? preds)))
265280 `(cljs.spec/tuple-impl '~(mapv #(res &env %) preds) ~(vec preds)))
266281
267- (defn- ns-qualify
268- " Qualify symbol s by resolving it or using the current *ns*."
269- [env s]
270- (if-let [resolved (resolve env s)]
271- (->sym resolved)
272- (if (namespace s)
273- s
274- (symbol (str (.-name *ns*)) (str s)))))
275-
276282(def ^:private _speced_vars (atom #{}))
277283
278284(defn speced-vars*
@@ -308,8 +314,8 @@ specified, return speced vars from all namespaces."
308314 expected to contain predicates that relate those values
309315
310316 Qualifies fn-sym with resolve, or using *ns* if no resolution found.
311- Registers specs in the global registry, where they can be retrieved
312- by calling fn -spec.
317+ Registers an fspec in the global registry, where it can be retrieved
318+ by calling get -spec with the var or full-qualified symbol .
313319
314320 Once registered, function specs are included in doc, checked by
315321 instrument, tested by the runner clojure.spec.test/run-tests, and (if
@@ -329,10 +335,8 @@ specified, return speced vars from all namespaces."
329335 :sym symbol?)
330336 :ret symbol?)"
331337 [fn-sym & specs]
332- (let [env &env
333- qn (ns-qualify env fn-sym)]
334- (swap! _speced_vars conj qn)
335- `(cljs.spec/def '~qn (cljs.spec/fspec ~@specs))))
338+ (swap! _speced_vars conj (ns-qualify &env fn-sym))
339+ `(cljs.spec/def ~fn-sym (cljs.spec/fspec ~@specs)))
336340
337341(defmacro with-instrument-disabled
338342 " Disables instrument's checking of calls, within a scope."
0 commit comments