Skip to content

Commit c716a5a

Browse files
puredangerstuarthalloway
authored andcommitted
CLJ-1453 Fix iterator implementations to throw NSEE when exhausted
Signed-off-by: Stuart Halloway <stu@cognitect.com>
1 parent 60e4ff5 commit c716a5a

File tree

6 files changed

+60
-26
lines changed

6 files changed

+60
-26
lines changed

src/clj/clojure/gvec.clj

+12-3
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,10 @@
385385
(let [i (java.util.concurrent.atomic.AtomicInteger. 0)]
386386
(reify java.util.Iterator
387387
(hasNext [_] (< (.get i) cnt))
388-
(next [_] (.nth this (dec (.incrementAndGet i))))
388+
(next [_] (try
389+
(.nth this (dec (.incrementAndGet i)))
390+
(catch IndexOutOfBoundsException _
391+
(throw (java.util.NoSuchElementException.)))))
389392
(remove [_] (throw (UnsupportedOperationException.))))))
390393

391394
java.util.Collection
@@ -428,9 +431,15 @@
428431
(reify java.util.ListIterator
429432
(hasNext [_] (< (.get i) cnt))
430433
(hasPrevious [_] (pos? i))
431-
(next [_] (.nth this (dec (.incrementAndGet i))))
434+
(next [_] (try
435+
(.nth this (dec (.incrementAndGet i)))
436+
(catch IndexOutOfBoundsException _
437+
(throw (java.util.NoSuchElementException.)))))
432438
(nextIndex [_] (.get i))
433-
(previous [_] (.nth this (.decrementAndGet i)))
439+
(previous [_] (try
440+
(.nth this (.decrementAndGet i))
441+
(catch IndexOutOfBoundsException _
442+
(throw (java.util.NoSuchElementException.)))))
434443
(previousIndex [_] (dec (.get i)))
435444
(add [_ e] (throw (UnsupportedOperationException.)))
436445
(remove [_] (throw (UnsupportedOperationException.)))

src/jvm/clojure/lang/APersistentVector.java

+15-4
Original file line numberDiff line numberDiff line change
@@ -223,15 +223,21 @@ public boolean hasNext(){
223223
}
224224

225225
public Object next(){
226-
return nth(nexti++);
226+
if(nexti < count())
227+
return nth(nexti++);
228+
else
229+
throw new NoSuchElementException();
227230
}
228231

229232
public boolean hasPrevious(){
230233
return nexti > 0;
231234
}
232235

233236
public Object previous(){
234-
return nth(--nexti);
237+
if(nexti > 0)
238+
return nth(--nexti);
239+
else
240+
throw new NoSuchElementException();
235241
}
236242

237243
public int nextIndex(){
@@ -265,7 +271,10 @@ public boolean hasNext(){
265271
}
266272

267273
public Object next(){
268-
return nth(i++);
274+
if(i < end)
275+
return nth(i++);
276+
else
277+
throw new NoSuchElementException();
269278
}
270279

271280
public void remove(){
@@ -308,7 +317,9 @@ public boolean hasNext(){
308317
}
309318

310319
public Object next(){
311-
return nth(i++);
320+
if(i < count())
321+
return nth(i++);
322+
else throw new NoSuchElementException();
312323
}
313324

314325
public void remove(){

src/jvm/clojure/lang/ArrayIter.java

+10-10
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public class ArrayIter implements Iterator {
1919

2020
static public Iterator EMPTY_ITERATOR = new Iterator() {
2121
public boolean hasNext() { return false; }
22-
public Object next() { return null; }
22+
public Object next() { throw new java.util.NoSuchElementException(); }
2323
public void remove() { throw new UnsupportedOperationException("remove() not supported"); }
2424
};
2525

@@ -68,7 +68,7 @@ public boolean hasNext() {
6868
public Object next() {
6969
if(array != null && i < array.length)
7070
return array[i++];
71-
return null;
71+
throw new java.util.NoSuchElementException();
7272
}
7373

7474
public void remove() {
@@ -93,7 +93,7 @@ public boolean hasNext() {
9393
public Long next() {
9494
if(array != null && i < array.length)
9595
return Long.valueOf(array[i++]);
96-
return null;
96+
throw new java.util.NoSuchElementException();
9797
}
9898

9999
public void remove() {
@@ -117,7 +117,7 @@ public boolean hasNext() {
117117
public Double next() {
118118
if(array != null && i < array.length)
119119
return Double.valueOf(array[i++]);
120-
return null;
120+
throw new java.util.NoSuchElementException();
121121
}
122122

123123
public void remove() {
@@ -141,7 +141,7 @@ public boolean hasNext() {
141141
public Double next() {
142142
if(array != null && i < array.length)
143143
return array[i++];
144-
return null;
144+
throw new java.util.NoSuchElementException();
145145
}
146146

147147
public void remove() {
@@ -166,7 +166,7 @@ public boolean hasNext() {
166166
public Long next() {
167167
if(array != null && i < array.length)
168168
return Long.valueOf(array[i++]);
169-
return null;
169+
throw new java.util.NoSuchElementException();
170170
}
171171

172172
public void remove() {
@@ -191,7 +191,7 @@ public boolean hasNext() {
191191
public Byte next() {
192192
if(array != null && i < array.length)
193193
return array[i++];
194-
return null;
194+
throw new java.util.NoSuchElementException();
195195
}
196196

197197
public void remove() {
@@ -216,7 +216,7 @@ public boolean hasNext() {
216216
public Character next() {
217217
if(array != null && i < array.length)
218218
return array[i++];
219-
return null;
219+
throw new java.util.NoSuchElementException();
220220
}
221221

222222
public void remove() {
@@ -241,7 +241,7 @@ public boolean hasNext() {
241241
public Long next() {
242242
if(array != null && i < array.length)
243243
return Long.valueOf(array[i++]);
244-
return null;
244+
throw new java.util.NoSuchElementException();
245245
}
246246

247247
public void remove() {
@@ -266,7 +266,7 @@ public boolean hasNext() {
266266
public Boolean next() {
267267
if(array != null && i < array.length)
268268
return Boolean.valueOf(array[i++]);
269-
return null;
269+
throw new java.util.NoSuchElementException();
270270
}
271271

272272
public void remove() {

src/jvm/clojure/lang/PersistentArrayMap.java

+7-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import java.util.Arrays;
1515
import java.util.Iterator;
1616
import java.util.Map;
17+
import java.util.NoSuchElementException;
1718

1819
/**
1920
* Simple implementation of persistent map on an array
@@ -353,8 +354,12 @@ public boolean hasNext(){
353354
}
354355

355356
public Object next(){
356-
i += 2;
357-
return f.invoke(array[i],array[i+1]);
357+
try {
358+
i += 2;
359+
return f.invoke(array[i], array[i+1]);
360+
} catch(IndexOutOfBoundsException e) {
361+
throw new NoSuchElementException();
362+
}
358363
}
359364

360365
public void remove(){

src/jvm/clojure/lang/PersistentTreeMap.java

+7-3
Original file line numberDiff line numberDiff line change
@@ -855,9 +855,13 @@ public boolean hasNext(){
855855
}
856856

857857
public Object next(){
858-
Node t = (Node) stack.pop();
859-
push(asc ? t.right() : t.left());
860-
return t;
858+
try {
859+
Node t = (Node) stack.pop();
860+
push(asc ? t.right() : t.left());
861+
return t;
862+
} catch(EmptyStackException e) {
863+
throw new NoSuchElementException();
864+
}
861865
}
862866

863867
public void remove(){

src/jvm/clojure/lang/PersistentVector.java

+9-4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import java.util.ArrayList;
1717
import java.util.Iterator;
1818
import java.util.List;
19+
import java.util.NoSuchElementException;
1920
import java.util.concurrent.atomic.AtomicReference;
2021

2122
public class PersistentVector extends APersistentVector implements IObj, IEditableCollection, IReduce, IKVReduce{
@@ -294,12 +295,16 @@ public boolean hasNext(){
294295
}
295296

296297
public Object next(){
297-
if(i-base == 32){
298-
array = arrayFor(i);
299-
base += 32;
298+
if(i < end) {
299+
if(i-base == 32){
300+
array = arrayFor(i);
301+
base += 32;
300302
}
301-
return array[i++ & 0x01f];
303+
return array[i++ & 0x01f];
304+
} else {
305+
throw new NoSuchElementException();
302306
}
307+
}
303308

304309
public void remove(){
305310
throw new UnsupportedOperationException();

0 commit comments

Comments
 (0)