|
242 | 242 | [spec v] |
243 | 243 | ) |
244 | 244 |
|
| 245 | +(defn- ->sym |
| 246 | + "Returns a symbol from a symbol or var" |
| 247 | + [x] |
| 248 | + (if (var? x) |
| 249 | + (.-sym x) |
| 250 | + x)) |
| 251 | + |
245 | 252 | (defn- fn-specs? |
246 | 253 | "Fn-specs must include at least :args or :ret specs." |
247 | 254 | [m] |
248 | 255 | (c/or (:args m) (:ret m))) |
249 | 256 |
|
| 257 | +(defn- fn-spec-sym |
| 258 | + [sym role] |
| 259 | + (symbol (str sym "$" (name role)))) |
| 260 | + |
250 | 261 | (defn fn-specs |
251 | 262 | "Returns :args/:ret/:fn map of specs for var or symbol v." |
252 | 263 | [v] |
|
303 | 314 | (ex-info (str "Fn at " v " is not spec'ed.") |
304 | 315 | {:var v :specs specs})) |
305 | 316 |
|
306 | | -;(def ^:private instrumented-vars |
307 | | -; "Map for instrumented vars to :raw/:wrapped fns" |
308 | | -; (atom {})) |
309 | | -; |
310 | | -;(defn- ->var |
311 | | -; [s-or-v] |
312 | | -; (if (var? s-or-v) |
313 | | -; s-or-v |
314 | | -; (let [v (c/and (symbol? s-or-v) (resolve s-or-v))] |
315 | | -; (if (var? v) |
316 | | -; v |
317 | | -; (throw (js/Error. (str (pr-str s-or-v) " does not name a var"))))))) |
318 | | - |
319 | | -;(defn instrument |
320 | | -; "Instruments the var at v, a var or symbol, to check specs |
321 | | -;registered with fdef. Wraps the fn at v to check :args/:ret/:fn |
322 | | -;specs, if they exist, throwing an ex-info with explain-data if a |
323 | | -;check fails. Idempotent." |
324 | | -; [v] |
325 | | -; (let [v (->var v) |
326 | | -; specs (fn-specs v)] |
327 | | -; (if (fn-specs? specs) |
328 | | -; (locking instrumented-vars |
329 | | -; (let [{:keys [raw wrapped]} (get @instrumented-vars v) |
330 | | -; current @v] |
331 | | -; (when-not (= wrapped current) |
332 | | -; (let [checked (spec-checking-fn v current)] |
333 | | -; (alter-var-root v (constantly checked)) |
334 | | -; (swap! instrumented-vars assoc v {:raw current :wrapped checked})))) |
335 | | -; v) |
336 | | -; (throw (no-fn-specs v specs))))) |
337 | | -; |
| 317 | +(def ^:private instrumented-vars |
| 318 | + "Map for instrumented vars to :raw/:wrapped fns" |
| 319 | + (atom {})) |
| 320 | + |
| 321 | +(defn instrument* |
| 322 | + [v] |
| 323 | + (let [specs (fn-specs v)] |
| 324 | + (if (fn-specs? specs) |
| 325 | + (locking instrumented-vars |
| 326 | + (let [{:keys [raw wrapped]} (get @instrumented-vars v) |
| 327 | + current @v] |
| 328 | + (when-not (= wrapped current) |
| 329 | + (let [checked (spec-checking-fn v current)] |
| 330 | + (swap! instrumented-vars assoc v {:raw current :wrapped checked}) |
| 331 | + checked)))) |
| 332 | + (throw (no-fn-specs v specs))))) |
| 333 | + |
338 | 334 | ;(defn unstrument |
339 | 335 | ; "Undoes instrument on the var at v, a var or symbol. Idempotent." |
340 | 336 | ; [v] |
|
0 commit comments