diff options
author | Rich Hickey <richhickey@gmail.com> | 2010-04-05 11:23:55 -0400 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2010-04-05 11:23:55 -0400 |
commit | c733148ba0fb3ff7bbab133f5375422972e62d08 (patch) | |
tree | 0cbe5723116e143f0d1105d712fba09067eaf12a | |
parent | e6e39d5931fbdf3dfa68cd2d059b8e26ce45c965 (diff) |
catch duplicate set keys for literals and hash-set calls.
-rw-r--r-- | src/clj/clojure/core.clj | 4 | ||||
-rw-r--r-- | src/jvm/clojure/lang/LispReader.java | 2 | ||||
-rw-r--r-- | src/jvm/clojure/lang/PersistentHashSet.java | 35 | ||||
-rw-r--r-- | src/jvm/clojure/lang/RT.java | 2 | ||||
-rw-r--r-- | test/clojure/test_clojure/data_structures.clj | 17 |
5 files changed, 39 insertions, 21 deletions
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj index b5909407..1508a76c 100644 --- a/src/clj/clojure/core.clj +++ b/src/clj/clojure/core.clj @@ -289,7 +289,7 @@ "Returns a new hash set with supplied keys." ([] #{}) ([& keys] - (clojure.lang.PersistentHashSet/create keys))) + (clojure.lang.PersistentHashSet/createWithCheck keys))) (defn sorted-map "keyval => key val @@ -2773,7 +2773,7 @@ (defn set "Returns a set of the distinct elements of coll." - [coll] (apply hash-set coll)) + [coll] (clojure.lang.PersistentHashSet/create #^clojure.lang.ISeq (seq coll))) (defn #^{:private true} filter-key [keyfn pred amap] diff --git a/src/jvm/clojure/lang/LispReader.java b/src/jvm/clojure/lang/LispReader.java index dc8ce972..137c8a4c 100644 --- a/src/jvm/clojure/lang/LispReader.java +++ b/src/jvm/clojure/lang/LispReader.java @@ -1008,7 +1008,7 @@ public static class MapReader extends AFn{ public static class SetReader extends AFn{ public Object invoke(Object reader, Object leftbracket) throws Exception{ PushbackReader r = (PushbackReader) reader; - return PersistentHashSet.create(readDelimitedList('}', r, true)); + return PersistentHashSet.createWithCheck(readDelimitedList('}', r, true)); } } diff --git a/src/jvm/clojure/lang/PersistentHashSet.java b/src/jvm/clojure/lang/PersistentHashSet.java index eced8663..12170d4b 100644 --- a/src/jvm/clojure/lang/PersistentHashSet.java +++ b/src/jvm/clojure/lang/PersistentHashSet.java @@ -47,6 +47,41 @@ static public PersistentHashSet create(ISeq items){ return ret; } +public static PersistentHashSet createWithCheck(Object... init){ + PersistentHashSet ret = EMPTY; + for(int i = 0; i < init.length; i++) + { + ret = (PersistentHashSet) ret.cons(init[i]); + if(ret.count() != i + 1) + throw new IllegalArgumentException("Duplicate key: " + init[i]); + } + return ret; +} + +public static PersistentHashSet createWithCheck(List init){ + PersistentHashSet ret = EMPTY; + int i=0; + for(Object key : init) + { + ret = (PersistentHashSet) ret.cons(key); + if(ret.count() != i + 1) + throw new IllegalArgumentException("Duplicate key: " + key); + ++i; + } + return ret; +} + +static public PersistentHashSet createWithCheck(ISeq items){ + PersistentHashSet ret = EMPTY; + for(int i=0; items != null; items = items.next(), ++i) + { + ret = (PersistentHashSet) ret.cons(items.first()); + if(ret.count() != i + 1) + throw new IllegalArgumentException("Duplicate key: " + items.first()); + } + return ret; +} + PersistentHashSet(IPersistentMap meta, IPersistentMap impl){ super(impl); this._meta = meta; diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java index 13afd8fd..58d91a44 100644 --- a/src/jvm/clojure/lang/RT.java +++ b/src/jvm/clojure/lang/RT.java @@ -1023,7 +1023,7 @@ static public IPersistentMap map(Object... init){ } static public IPersistentSet set(Object... init){ - return PersistentHashSet.create(init); + return PersistentHashSet.createWithCheck(init); } static public IPersistentVector vector(Object... init){ diff --git a/test/clojure/test_clojure/data_structures.clj b/test/clojure/test_clojure/data_structures.clj index 5a6bba86..330bbed4 100644 --- a/test/clojure/test_clojure/data_structures.clj +++ b/test/clojure/test_clojure/data_structures.clj @@ -534,23 +534,6 @@ (hash-set 1 2) (hash-set 2 1) (hash-set 3 1 2) (hash-set 1 2 3) ) - ; equal and unique - (are [x] (and (= (hash-set x) #{x}) - (= (hash-set x x) #{x})) - nil - false true - 0 42 - 0.0 3.14 - 2/3 - 0M 1M - \c - "" "abc" - 'sym - :kw - () '(1 2) - [] [1 2] - {} {:a 1 :b 2} - #{} #{1 2} ) (are [x y] (= x y) ; equal classes |