|
146 | 146 | fields (conj fields '__meta '__extmap)] |
147 | 147 | (when (some #{:volatile-mutable :unsynchronized-mutable} (mapcat (comp keys meta) hinted-fields)) |
148 | 148 | (throw (IllegalArgumentException. ":volatile-mutable or :unsynchronized-mutable not supported for record fields"))) |
| 149 | + (let [gs (gensym)] |
149 | 150 | (letfn |
150 | 151 | [(eqhash [[i m]] |
151 | 152 | [i |
152 | 153 | (conj m |
153 | | - `(hashCode [~'this] (-> ~tag hash ~@(map #(list `hash-combine %) (remove #{'__meta} fields)))) |
154 | | - `(equals [~'this ~'o] |
| 154 | + `(hashCode [this#] (-> ~tag hash ~@(map #(list `hash-combine %) (remove #{'__meta} fields)))) |
| 155 | + `(equals [this# ~gs] |
155 | 156 | (boolean |
156 | | - (or (identical? ~'this ~'o) |
157 | | - (when (identical? (class ~'this) (class ~'o)) |
158 | | - (let [~'o ~(with-meta 'o {:tag tagname})] |
159 | | - (and ~@(map (fn [fld] `(= ~fld (. ~'o ~fld))) base-fields) |
160 | | - (= ~'__extmap (. ~'o ~'__extmap)))))))))]) |
| 157 | + (or (identical? this# ~gs) |
| 158 | + (when (identical? (class this#) (class ~gs)) |
| 159 | + (let [~gs ~(with-meta gs {:tag tagname})] |
| 160 | + (and ~@(map (fn [fld] `(= ~fld (. ~gs ~fld))) base-fields) |
| 161 | + (= ~'__extmap (. ~gs ~'__extmap)))))))))]) |
161 | 162 | (iobj [[i m]] |
162 | 163 | [(conj i 'clojure.lang.IObj) |
163 | | - (conj m `(meta [~'this] ~'__meta) |
164 | | - `(withMeta [~'this ~'m] (new ~tagname ~@(replace {'__meta 'm} fields))))]) |
| 164 | + (conj m `(meta [this#] ~'__meta) |
| 165 | + `(withMeta [this# ~gs] (new ~tagname ~@(replace {'__meta gs} fields))))]) |
165 | 166 | (ilookup [[i m]] |
166 | 167 | [(conj i 'clojure.lang.ILookup 'clojure.lang.IKeywordLookup) |
167 | | - (conj m `(valAt [~'this ~'k] (.valAt ~'this ~'k nil)) |
168 | | - `(valAt [~'this ~'k ~'else] |
169 | | - (case ~'k ~@(mapcat (fn [fld] [(keyword fld) fld]) |
| 168 | + (conj m `(valAt [this# k#] (.valAt this# k# nil)) |
| 169 | + `(valAt [this# k# else#] |
| 170 | + (case k# ~@(mapcat (fn [fld] [(keyword fld) fld]) |
170 | 171 | base-fields) |
171 | | - (get ~'__extmap ~'k ~'else))) |
172 | | - `(getLookupThunk [~'this ~'k] |
173 | | - (let [~'gclass (class ~'this)] |
174 | | - (case ~'k |
| 172 | + (get ~'__extmap k# else#))) |
| 173 | + `(getLookupThunk [this# k#] |
| 174 | + (let [~'gclass (class this#)] |
| 175 | + (case k# |
175 | 176 | ~@(let [hinted-target (with-meta 'gtarget {:tag tagname})] |
176 | 177 | (mapcat |
177 | 178 | (fn [fld] |
|
186 | 187 | (imap [[i m]] |
187 | 188 | [(conj i 'clojure.lang.IPersistentMap) |
188 | 189 | (conj m |
189 | | - `(count [~'this] (+ ~(count base-fields) (count ~'__extmap))) |
190 | | - `(empty [~'this] (throw (UnsupportedOperationException. (str "Can't create empty: " ~(str classname))))) |
191 | | - `(cons [~'this ~'e] ((var imap-cons) ~'this ~'e)) |
192 | | - `(equiv [~'this ~'o] (.equals ~'this ~'o)) |
193 | | - `(containsKey [~'this ~'k] (not (identical? ~'this (.valAt ~'this ~'k ~'this)))) |
194 | | - `(entryAt [~'this ~'k] (let [~'v (.valAt ~'this ~'k ~'this)] |
195 | | - (when-not (identical? ~'this ~'v) |
196 | | - (clojure.lang.MapEntry. ~'k ~'v)))) |
197 | | - `(seq [~'this] (concat [~@(map #(list `new `clojure.lang.MapEntry (keyword %) %) base-fields)] |
| 190 | + `(count [this#] (+ ~(count base-fields) (count ~'__extmap))) |
| 191 | + `(empty [this#] (throw (UnsupportedOperationException. (str "Can't create empty: " ~(str classname))))) |
| 192 | + `(cons [this# e#] ((var imap-cons) this# e#)) |
| 193 | + `(equiv [this# o#] (.equals this# o#)) |
| 194 | + `(containsKey [this# k#] (not (identical? this# (.valAt this# k# this#)))) |
| 195 | + `(entryAt [this# k#] (let [v# (.valAt this# k# this#)] |
| 196 | + (when-not (identical? this# v#) |
| 197 | + (clojure.lang.MapEntry. k# v#)))) |
| 198 | + `(seq [this#] (concat [~@(map #(list `new `clojure.lang.MapEntry (keyword %) %) base-fields)] |
198 | 199 | ~'__extmap)) |
199 | | - `(assoc [~'this ~'gk__4242 ~'gv__4242] |
200 | | - (condp identical? ~'gk__4242 |
| 200 | + `(assoc [this# k# ~gs] |
| 201 | + (condp identical? k# |
201 | 202 | ~@(mapcat (fn [fld] |
202 | | - [(keyword fld) (list* `new tagname (replace {fld 'gv__4242} fields))]) |
| 203 | + [(keyword fld) (list* `new tagname (replace {fld gs} fields))]) |
203 | 204 | base-fields) |
204 | | - (new ~tagname ~@(remove #{'__extmap} fields) (assoc ~'__extmap ~'gk__4242 ~'gv__4242)))) |
205 | | - `(without [~'this ~'k] (if (contains? #{~@(map keyword base-fields)} ~'k) |
206 | | - (dissoc (with-meta (into {} ~'this) ~'__meta) ~'k) |
| 205 | + (new ~tagname ~@(remove #{'__extmap} fields) (assoc ~'__extmap k# ~gs)))) |
| 206 | + `(without [this# k#] (if (contains? #{~@(map keyword base-fields)} k#) |
| 207 | + (dissoc (with-meta (into {} this#) ~'__meta) k#) |
207 | 208 | (new ~tagname ~@(remove #{'__extmap} fields) |
208 | | - (not-empty (dissoc ~'__extmap ~'k))))))]) |
| 209 | + (not-empty (dissoc ~'__extmap k#))))))]) |
209 | 210 | (ijavamap [[i m]] |
210 | 211 | [(conj i 'java.util.Map 'java.io.Serializable) |
211 | 212 | (conj m |
212 | | - `(size [~'this] (.count ~'this)) |
213 | | - `(isEmpty [~'this] (= 0 (.count ~'this))) |
214 | | - `(containsValue [~'this ~'v] (-> ~'this vals (.contains ~'v))) |
215 | | - `(get [~'this ~'k] (.valAt ~'this ~'k)) |
216 | | - `(put [~'this ~'k ~'v] (throw (UnsupportedOperationException.))) |
217 | | - `(remove [~'this ~'k] (throw (UnsupportedOperationException.))) |
218 | | - `(putAll [~'this ~'m] (throw (UnsupportedOperationException.))) |
219 | | - `(clear [~'this] (throw (UnsupportedOperationException.))) |
220 | | - `(keySet [~'this] (set (keys ~'this))) |
221 | | - `(values [~'this] (vals ~'this)) |
222 | | - `(entrySet [~'this] (set ~'this)))]) |
| 213 | + `(size [this#] (.count this#)) |
| 214 | + `(isEmpty [this#] (= 0 (.count this#))) |
| 215 | + `(containsValue [this# v#] (-> this# vals (.contains v#))) |
| 216 | + `(get [this# k#] (.valAt this# k#)) |
| 217 | + `(put [this# k# v#] (throw (UnsupportedOperationException.))) |
| 218 | + `(remove [this# k#] (throw (UnsupportedOperationException.))) |
| 219 | + `(putAll [this# m#] (throw (UnsupportedOperationException.))) |
| 220 | + `(clear [this#] (throw (UnsupportedOperationException.))) |
| 221 | + `(keySet [this#] (set (keys this#))) |
| 222 | + `(values [this#] (vals this#)) |
| 223 | + `(entrySet [this#] (set this#)))]) |
223 | 224 | ] |
224 | 225 | (let [[i m] (-> [interfaces methods] eqhash iobj ilookup imap ijavamap)] |
225 | 226 | `(deftype* ~tagname ~classname ~(conj hinted-fields '__meta '__extmap) |
226 | 227 | :implements ~(vec i) |
227 | | - ~@m))))) |
| 228 | + ~@m)))))) |
228 | 229 |
|
229 | 230 | (defmacro defrecord |
230 | 231 | "Alpha - subject to change |
|
0 commit comments