summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2010-04-05 11:23:55 -0400
committerRich Hickey <richhickey@gmail.com>2010-04-05 11:23:55 -0400
commitc733148ba0fb3ff7bbab133f5375422972e62d08 (patch)
tree0cbe5723116e143f0d1105d712fba09067eaf12a
parente6e39d5931fbdf3dfa68cd2d059b8e26ce45c965 (diff)
catch duplicate set keys for literals and hash-set calls.
-rw-r--r--src/clj/clojure/core.clj4
-rw-r--r--src/jvm/clojure/lang/LispReader.java2
-rw-r--r--src/jvm/clojure/lang/PersistentHashSet.java35
-rw-r--r--src/jvm/clojure/lang/RT.java2
-rw-r--r--test/clojure/test_clojure/data_structures.clj17
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