diff options
author | Rich Hickey <richhickey@gmail.com> | 2010-04-05 11:02:09 -0400 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2010-04-05 11:02:09 -0400 |
commit | e6e39d5931fbdf3dfa68cd2d059b8e26ce45c965 (patch) | |
tree | 9dadb9dd9c327fe52ad8d9a33d4d5f5c58cf0007 /src/jvm/clojure | |
parent | ba6cc3bde1a1ea9801b2133748a45f1277166368 (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.java | 11 | ||||
-rw-r--r-- | src/jvm/clojure/lang/PersistentHashMap.java | 25 | ||||
-rw-r--r-- | src/jvm/clojure/lang/RT.java | 4 |
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){ |