/
fnref.clj
37 lines (32 loc) · 1.35 KB
/
fnref.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
(ns midje.parsing.util.fnref
"A fnref is the first symbol-or-var in a list. These utilities
allow you to interpret it in multiple ways."
(:require [such.control-flow :refer [branch-on]]))
(defn classify-function-reference [reference]
(branch-on reference
symbol? :symbol
sequential? :var-form
:else (throw (Exception. "Programmer error"))))
(defmulti as-symbol classify-function-reference)
(defmethod as-symbol :symbol [reference]
reference)
(defmethod as-symbol :var-form [reference]
(second reference))
(defmulti as-var-form classify-function-reference)
(defmethod as-var-form :symbol [reference]
`(var ~reference))
(defmethod as-var-form :var-form [reference]
reference)
(defmulti as-form-to-fetch-var-value classify-function-reference)
(defmethod as-form-to-fetch-var-value :symbol [reference]
reference)
(defmethod as-form-to-fetch-var-value :var-form [reference]
`(deref ~reference))
;; Unlike other functions, this doesn't return homoiconic forms to
;; substitute into macroexpansions. Instead, it returns the actual
;; clojure.lang.Var object.
(defmulti resolved-to-actual-var-object classify-function-reference)
(defmethod resolved-to-actual-var-object :symbol [reference]
(resolve reference))
(defmethod resolved-to-actual-var-object :var-form [reference]
(resolved-to-actual-var-object (second reference)))