summaryrefslogtreecommitdiff
path: root/src/jvm/clojure
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2010-04-05 11:02:09 -0400
committerRich Hickey <richhickey@gmail.com>2010-04-05 11:02:09 -0400
commite6e39d5931fbdf3dfa68cd2d059b8e26ce45c965 (patch)
tree9dadb9dd9c327fe52ad8d9a33d4d5f5c58cf0007 /src/jvm/clojure
parentba6cc3bde1a1ea9801b2133748a45f1277166368 (diff)
catch duplicate map keys for literals and hash- and array-map calls. Fixes #87
Diffstat (limited to 'src/jvm/clojure')
-rw-r--r--src/jvm/clojure/lang/PersistentArrayMap.java11
-rw-r--r--src/jvm/clojure/lang/PersistentHashMap.java25
-rw-r--r--src/jvm/clojure/lang/RT.java4
3 files changed, 31 insertions, 9 deletions
diff --git a/src/jvm/clojure/lang/PersistentArrayMap.java b/src/jvm/clojure/lang/PersistentArrayMap.java
index 8f63e5f8..7965c92e 100644
--- a/src/jvm/clojure/lang/PersistentArrayMap.java
+++ b/src/jvm/clojure/lang/PersistentArrayMap.java
@@ -60,6 +60,17 @@ IPersistentMap createHT(Object[] init){
return PersistentHashMap.create(meta(), init);
}
+static public PersistentArrayMap createWithCheck(Object[] init){
+ for(int i=0;i< init.length;i += 2)
+ {
+ for(int j=i+2;j<init.length;j += 2)
+ {
+ if(equalKey(init[i],init[j]))
+ throw new IllegalArgumentException("Duplicate key: " + init[i]);
+ }
+ }
+ return new PersistentArrayMap(init);
+}
/**
* This ctor captures/aliases the passed array, so do not modify later
*
diff --git a/src/jvm/clojure/lang/PersistentHashMap.java b/src/jvm/clojure/lang/PersistentHashMap.java
index 4fae3f30..6f956a7f 100644
--- a/src/jvm/clojure/lang/PersistentHashMap.java
+++ b/src/jvm/clojure/lang/PersistentHashMap.java
@@ -58,15 +58,13 @@ public static PersistentHashMap create(Object... init){
return (PersistentHashMap) ret.persistent();
}
-public static PersistentHashMap create(List init){
+public static PersistentHashMap createWithCheck(Object... init){
ITransientMap ret = EMPTY.asTransient();
- for(Iterator i = init.iterator(); i.hasNext();)
+ for(int i = 0; i < init.length; i += 2)
{
- Object key = i.next();
- if(!i.hasNext())
- throw new IllegalArgumentException(String.format("No value supplied for key: %s", key));
- Object val = i.next();
- ret = ret.assoc(key, val);
+ ret = ret.assoc(init[i], init[i + 1]);
+ if(ret.count() != i/2 + 1)
+ throw new IllegalArgumentException("Duplicate key: " + init[i]);
}
return (PersistentHashMap) ret.persistent();
}
@@ -82,6 +80,19 @@ static public PersistentHashMap create(ISeq items){
return (PersistentHashMap) ret.persistent();
}
+static public PersistentHashMap createWithCheck(ISeq items){
+ ITransientMap ret = EMPTY.asTransient();
+ for(int i=0; items != null; items = items.next().next(), ++i)
+ {
+ if(items.next() == null)
+ throw new IllegalArgumentException(String.format("No value supplied for key: %s", items.first()));
+ ret = ret.assoc(items.first(), RT.second(items));
+ if(ret.count() != i + 1)
+ throw new IllegalArgumentException("Duplicate key: " + items.first());
+ }
+ return (PersistentHashMap) ret.persistent();
+}
+
/*
* @param init {key1,val1,key2,val2,...}
*/
diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java
index 22b57cf7..13afd8fd 100644
--- a/src/jvm/clojure/lang/RT.java
+++ b/src/jvm/clojure/lang/RT.java
@@ -1018,8 +1018,8 @@ static public IPersistentMap map(Object... init){
if(init == null)
return PersistentArrayMap.EMPTY;
else if(init.length <= PersistentArrayMap.HASHTABLE_THRESHOLD)
- return new PersistentArrayMap(init);
- return PersistentHashMap.create(init);
+ return PersistentArrayMap.createWithCheck(init);
+ return PersistentHashMap.createWithCheck(init);
}
static public IPersistentSet set(Object... init){