|
3 | 3 | #?(:clj [active.clojure.record :as record]
|
4 | 4 | :cljs [active.clojure.cljs.record :as record :include-macros true])
|
5 | 5 | [active.clojure.record-helper :as record-helper]
|
| 6 | + [active.clojure.record-runtime :as record-runtime] |
6 | 7 | #?(:clj [active.clojure.lens :as lens]
|
7 | 8 | :cljs [active.clojure.lens :as lens :include-macros true])))
|
8 | 9 |
|
|
40 | 41 | (str (:name ((resolve 'cljs.analyzer.api/resolve) env t)))
|
41 | 42 | (str (:ns (meta (resolve t))) "/" (:name (meta (resolve t)))))))
|
42 | 43 |
|
| 44 | +(record/define-record-type ^:no-doc SumTypeDescriptor |
| 45 | + (make-sum-type-descriptor name sub-types) |
| 46 | + sum-type-descriptor? |
| 47 | + [name sum-type-descriptor-name |
| 48 | + sub-types sum-type-descriptor-sub-types]) |
| 49 | + |
| 50 | +(defn ^:no-doc value-of-sum-type? [v sum-type] |
| 51 | + (boolean (some (fn [t] |
| 52 | + (cond |
| 53 | + (sum-type-descriptor? t) (value-of-sum-type? v t) |
| 54 | + (record-runtime/record-type-descriptor? t) (record-runtime/record-of-type? v t) |
| 55 | + :else |
| 56 | + (do (assert false t) false) ;; should not happen? |
| 57 | + )) |
| 58 | + (sum-type-descriptor-sub-types sum-type)))) |
43 | 59 |
|
44 | 60 |
|
45 | 61 | ;; a clause is one of the following:
|
|
131 | 147 |
|
132 | 148 |
|
133 | 149 | (let [sym-fn (fn [a] (str *ns* "/" a))
|
134 |
| - resolved-type-symbols (mapv #(resolve-qualified-str % &env) type-symbols) |
| 150 | + resolved-type-symbols (mapv (comp symbol #(resolve-qualified-str % &env)) type-symbols) |
135 | 151 | sum-type-meta {:predicate (sym-fn predicate)
|
136 | 152 | :t sum-type-identifier
|
137 | 153 |
|
|
143 | 159 | (dissoc :end-line)
|
144 | 160 | (dissoc :end-column)
|
145 | 161 | (dissoc :name) ; this leads to a crash in clj
|
146 |
| - (dissoc :column)) type-symbols)}] |
| 162 | + (dissoc :column)) type-symbols)} |
| 163 | + arg (gensym "arg")] |
147 | 164 |
|
148 | 165 | (throw-when-illegal-types! type-symbols &env)
|
149 | 166 |
|
150 | 167 |
|
151 | 168 | `(do
|
152 |
| - |
153 |
| - (let [rss# ~resolved-type-symbols] ;; we only do resolution once |
154 |
| - |
155 |
| - (defn ~predicate [arg#] |
156 |
| - (boolean (some true? |
157 |
| - (map (fn [pred#] (pred# arg#)) |
158 |
| - ~(mapv #(symbol (get-predicate (symbol %) &env)) resolved-type-symbols))))) |
159 |
| - |
160 |
| - (def ~(add-meta type-name sum-type-meta) ~sum-type-meta)))))) |
| 169 | + (defn ~predicate [~arg] |
| 170 | + ;; we could use [[value-of-sum-type?]], but this is an optimized compiled version: |
| 171 | + (or ~@(map (fn [p] (list p arg)) |
| 172 | + (mapv #(symbol (get-predicate % &env)) resolved-type-symbols)))) |
| 173 | + |
| 174 | + (def ~(add-meta type-name sum-type-meta) |
| 175 | + (make-sum-type-descriptor '~type-name (vector ~@resolved-type-symbols))))))) |
161 | 176 |
|
162 | 177 |
|
163 | 178 |
|
|
0 commit comments