Skip to content

Commit c2b229e

Browse files
khinsenstuarthalloway
authored andcommitted
Remove potential conflicts between field names and method argument names in defrecord
Signed-off-by: Stuart Halloway <[email protected]>
1 parent 725547f commit c2b229e

File tree

1 file changed

+45
-44
lines changed

1 file changed

+45
-44
lines changed

src/clj/clojure/core_deftype.clj

Lines changed: 45 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -146,32 +146,33 @@
146146
fields (conj fields '__meta '__extmap)]
147147
(when (some #{:volatile-mutable :unsynchronized-mutable} (mapcat (comp keys meta) hinted-fields))
148148
(throw (IllegalArgumentException. ":volatile-mutable or :unsynchronized-mutable not supported for record fields")))
149+
(let [gs (gensym)]
149150
(letfn
150151
[(eqhash [[i m]]
151152
[i
152153
(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]
155156
(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)))))))))])
161162
(iobj [[i m]]
162163
[(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))))])
165166
(ilookup [[i m]]
166167
[(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])
170171
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#
175176
~@(let [hinted-target (with-meta 'gtarget {:tag tagname})]
176177
(mapcat
177178
(fn [fld]
@@ -186,45 +187,45 @@
186187
(imap [[i m]]
187188
[(conj i 'clojure.lang.IPersistentMap)
188189
(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)]
198199
~'__extmap))
199-
`(assoc [~'this ~'gk__4242 ~'gv__4242]
200-
(condp identical? ~'gk__4242
200+
`(assoc [this# k# ~gs]
201+
(condp identical? k#
201202
~@(mapcat (fn [fld]
202-
[(keyword fld) (list* `new tagname (replace {fld 'gv__4242} fields))])
203+
[(keyword fld) (list* `new tagname (replace {fld gs} fields))])
203204
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#)
207208
(new ~tagname ~@(remove #{'__extmap} fields)
208-
(not-empty (dissoc ~'__extmap ~'k))))))])
209+
(not-empty (dissoc ~'__extmap k#))))))])
209210
(ijavamap [[i m]]
210211
[(conj i 'java.util.Map 'java.io.Serializable)
211212
(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#)))])
223224
]
224225
(let [[i m] (-> [interfaces methods] eqhash iobj ilookup imap ijavamap)]
225226
`(deftype* ~tagname ~classname ~(conj hinted-fields '__meta '__extmap)
226227
:implements ~(vec i)
227-
~@m)))))
228+
~@m))))))
228229

229230
(defmacro defrecord
230231
"Alpha - subject to change

0 commit comments

Comments
 (0)