Remove redundant iterator classes, make ChainIterator inner class of ChainIterable
authorMikhail Golubev <mikhail.golubev@jetbrains.com>
Fri, 25 Sep 2015 12:21:03 +0000 (15:21 +0300)
committerMikhail Golubev <mikhail.golubev@jetbrains.com>
Fri, 25 Sep 2015 12:38:35 +0000 (15:38 +0300)
Previously ChainIterator and RepeatIterable were used solely in the
IteratorsTest.

python/src/com/jetbrains/python/toolbox/ChainIterable.java
python/src/com/jetbrains/python/toolbox/ChainIterationMixin.java [deleted file]
python/src/com/jetbrains/python/toolbox/ChainIterator.java [deleted file]
python/src/com/jetbrains/python/toolbox/ChainedListBase.java
python/src/com/jetbrains/python/toolbox/RepeatIterable.java [deleted file]
python/src/com/jetbrains/python/toolbox/RepeatIterator.java [deleted file]
python/testSrc/com/jetbrains/python/toolbox/IteratorsTest.java

index b091ab24162f2399a57d8dfca9aa041b8634fe51..cf19ad7a9bfd2455894d3b114f9101d91dd939e9 100644 (file)
@@ -20,6 +20,7 @@ import org.jetbrains.annotations.Nullable;
 
 import java.util.Collections;
 import java.util.Iterator;
+import java.util.NoSuchElementException;
 
 /**
  * Iterable that splices other iterables and iterates over them sequentially.
@@ -41,6 +42,7 @@ public class ChainIterable<T> extends ChainedListBase<Iterable<T>> implements It
   }
 
 
+  @Override
   public ChainIterable<T> add(@NotNull Iterable<T> another) {
     return (ChainIterable<T>)super.add(another);
   }
@@ -59,7 +61,7 @@ public class ChainIterable<T> extends ChainedListBase<Iterable<T>> implements It
    * Convenience: add an item wrapping it into a SingleIterable behind the scenes.
    */
   public ChainIterable<T> addItem(@NotNull T item) {
-    return (ChainIterable<T>)super.add(Collections.<T>singleton(item));
+    return add(Collections.singleton(item));
   }
 
   /**
@@ -70,50 +72,60 @@ public class ChainIterable<T> extends ChainedListBase<Iterable<T>> implements It
     return (myPayload == null);
   }
 
+  @Override
   public Iterator<T> iterator() {
+    return new ChainIterator<T>(this);
+  }
 
+  @Override
+  public String toString() {
+    return FP.fold(new FP.StringCollector<T>(), this, new StringBuilder()).toString();
+  }
 
-    class IterMixedIn extends ChainIterationMixin<T, Iterable<T>> {
-      IterMixedIn(ChainedListBase<Iterable<T>> link) {
-        super(link);
-      }
-
-      @Override
-      public Iterator<T> toIterator(Iterable<T> first) {
-        return first.iterator();
-      }
+  private static class ChainIterator<T> implements Iterator<T> {
+  
+    private ChainedListBase<Iterable<T>> myLink; // link of the chain we're currently at
+    private Iterator<T> myCurrent;
+  
+    public ChainIterator(@Nullable ChainedListBase<Iterable<T>> initial) {
+      myLink = initial;
     }
-    final IterMixedIn mixin = new IterMixedIn(this);
-
-
-    class Iter extends ChainedListBase<Iterable<T>> implements Iterator<T> {
-
-      Iter(ChainedListBase<Iterable<T>> piggybacked) {
-        super(piggybacked.myPayload);
-        myNext = piggybacked.myNext;
-      }
-
-      public boolean hasNext() {
-        return mixin.hasNext();
+  
+    // returns either null or a non-exhausted iterator.
+    @Nullable
+    private Iterator<T> getCurrent() {
+      while ((myCurrent == null || !myCurrent.hasNext()) && (myLink != null && myLink.myPayload != null)) { // fix myCurrent
+        if (myCurrent == null) {
+          myCurrent = myLink.myPayload.iterator();
+          assert myCurrent != null;
+        }
+        else {
+          myLink= myLink.myNext;
+          myCurrent = null;
+        }
       }
-
-      public void remove() {
-        throw new UnsupportedOperationException(); // we don't remove things
+      return myCurrent;
+    }
+  
+    @Override
+    public boolean hasNext() {
+      return getCurrent() != null;
+    }
+  
+    @Override
+    public T next() {
+      final Iterator<T> current = getCurrent();
+      if (current != null) {
+        return current.next();
       }
-
-      public T next() {
-        //noinspection RedundantCast
-        return (T)mixin.next();
+      else {
+        throw new NoSuchElementException();
       }
-
     }
-
-    return new Iter(this);
-
-  }
-
-  @Override
-  public String toString() {
-    return FP.fold(new FP.StringCollector<T>(), this, new StringBuilder()).toString();
+  
+    @Override
+    public void remove() {
+      throw new UnsupportedOperationException("Cannot remove from ChainIterator");
+    }
   }
 }
diff --git a/python/src/com/jetbrains/python/toolbox/ChainIterationMixin.java b/python/src/com/jetbrains/python/toolbox/ChainIterationMixin.java
deleted file mode 100644 (file)
index 1387a40..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2000-2014 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.jetbrains.python.toolbox;
-
-import org.jetbrains.annotations.Nullable;
-
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-/**
- * Common logic of chain iterators.
- * User: dcheryasov
- * Date: Nov 20, 2009 9:10:39 AM
- */
-/* explicitly not public */
-abstract class ChainIterationMixin<T, TPayload> {
-  protected ChainedListBase<TPayload> myLink; // link of the chain we're currently at
-
-  protected Iterator<T> myCurrent;
-
-  public ChainIterationMixin(ChainedListBase<TPayload> link) {
-    myLink = link;
-  }
-
-  abstract public Iterator<T> toIterator(TPayload first);
-
-  // returns either null or a non-exhausted iterator.
-  @Nullable
-  public Iterator<T> getCurrent() {
-    while ((myCurrent == null || !myCurrent.hasNext()) && (myLink != null && myLink.myPayload != null)) { // fix myCurrent
-      if (myCurrent == null) {
-        myCurrent = toIterator(myLink.myPayload);
-        assert myCurrent != null;
-      }
-      else {
-        myLink= myLink.myNext;
-        myCurrent = null;
-      }
-    }
-    return myCurrent;
-  } 
-
-  public boolean hasNext() {
-    return getCurrent() != null;
-  }
-
-  public T next() {
-    Iterator<T> current = getCurrent();
-    if (current != null) return current.next();
-    else throw new NoSuchElementException();
-  }
-
-}
diff --git a/python/src/com/jetbrains/python/toolbox/ChainIterator.java b/python/src/com/jetbrains/python/toolbox/ChainIterator.java
deleted file mode 100644 (file)
index 7e20c37..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2000-2014 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.jetbrains.python.toolbox;
-
-import org.jetbrains.annotations.Nullable;
-
-import java.util.Iterator;
-
-/**
- * An iterator that combines several other iterators and exhaust them one by one, in chain.
- * User: dcheryasov
- * Date: Nov 19, 2009 3:49:38 AM
- */
-public class ChainIterator<T> extends ChainedListBase<Iterator<T>> implements Iterator<T> {
-
-  private ChainIterationMixin<T, Iterator<T>> myMixin;
-
-  /**
-   * Creates new instance.
-   * @param initial initial iterator. If null, the new iterator is empty, use {@link #add} to add initial content.
-   */
-  public ChainIterator(@Nullable Iterator<T> initial) {
-    super(initial);
-
-    myMixin = new ChainIterationMixin<T, Iterator<T>>(this) {
-      @Override
-      public Iterator<T> toIterator(Iterator<T> first) {
-        return first;
-      }
-    };
-  }
-
-
-  /**
-   * Adds another iterator to the chain. Values from this iterator will follow the values of the iterator passed to the constructor.
-   * Adding after the iteration has started is safe. 
-   * @param another iterator to add to the end of the chain.
-   * @return self, for easy chaining.
-   */
-  public ChainIterator<T> add(Iterator<T> another) {
-    return (ChainIterator<T>)super.add(another);
-  }
-
-
-  public boolean hasNext() {
-    return myMixin.hasNext();
-  }
-
-  public T next() {
-    return myMixin.next();
-  }
-
-  public void remove() {
-    throw new UnsupportedOperationException("Cannot remove from ChainIterator");
-  }
-}
index d1e5651ea9f3591f156f78711cec34d7d4311c24..23fa29636740ea1471c38825cdf2acfbc4aae082 100644 (file)
@@ -28,15 +28,6 @@ public /*abstract */class ChainedListBase<TPayload> {
     myPayload = initial;
   }
 
-  /**
-   * Wrap payload into a new linked list element.
-   * @param payload
-   * @return
-   */
-  /*
-  abstract protected ChainedListBase<TPayload> createInstance(TPayload payload);
-  */
-
   /**
    * Add another element to the end of our linked list
    * @param another
diff --git a/python/src/com/jetbrains/python/toolbox/RepeatIterable.java b/python/src/com/jetbrains/python/toolbox/RepeatIterable.java
deleted file mode 100644 (file)
index 262c927..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2000-2014 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.jetbrains.python.toolbox;
-
-import org.jetbrains.annotations.NotNull;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Iterable that endlessly repeat the same sequence.
- * User: dcheryasov
- * Date: Nov 8, 2009 6:32:08 AM
- */
-public class RepeatIterable<T> implements Iterable<T> {
-  private final List<T> master;
-
-  /**
-   * Create an iterator that repeats the contents of given list.
-   * @param master the list to repeat
-   */
-  public RepeatIterable(@NotNull List<T> master) {
-    this.master = master;
-  }
-
-  /**
-   * Create an iterator that repeats given value.
-   * @param single the value to repeat
-   */
-  public RepeatIterable(@NotNull T single) {
-    master = new ArrayList<T>(1);
-    master.add(single);
-  }
-
-  public Iterator<T> iterator() {
-    return new RepeatIterator<T>(master);
-  }
-}
diff --git a/python/src/com/jetbrains/python/toolbox/RepeatIterator.java b/python/src/com/jetbrains/python/toolbox/RepeatIterator.java
deleted file mode 100644 (file)
index 01a1839..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2000-2014 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.jetbrains.python.toolbox;
-
-import org.jetbrains.annotations.NotNull;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.NoSuchElementException;
-
-/**
- * An iterator that endlessly repeats the same contents.
- * User: dcheryasov
- * Date: Nov 8, 2009 5:55:57 AM
- */
-public class RepeatIterator<T> implements Iterator<T> {
-  private final List<T> master;
-  private Iterator<T> source;
-
-  /**
-   * Create an iterator that repeats the contents of given list.
-   * @param master the list to repeat
-   */
-  public RepeatIterator(@NotNull List<T> master) {
-    this.master = master;
-    this.source = master.iterator();
-  }
-
-  /**
-   * Create an iterator that repeats given value.
-   * @param single the value to repeat
-   */
-  public RepeatIterator(@NotNull T single) {
-    master = new ArrayList<T>(1);
-    master.add(single);
-    source = master.iterator();
-  }
-
-  public boolean hasNext() {
-    return master.size() > 0;
-  }
-
-  public void remove() {
-    throw new UnsupportedOperationException("This is a read-only endless iterator");
-  }
-
-  public T next() {
-    if (! hasNext()) throw new NoSuchElementException();
-    if (!source.hasNext()) source = master.iterator();
-    return source.next();
-  }
-}
index 918615eb38e7ebaea403ccae7a9eacc7195cd833..c110610f52988741d090281f8222db090e1adc15 100644 (file)
@@ -32,19 +32,6 @@ public class IteratorsTest extends TestCase {
     super();
   }
 
-  public void testRepeatIterable() {
-    String value = "foo";
-    RepeatIterable<String> tested = new RepeatIterable<String>(value);
-    int count = 0;
-    int times = 10;
-    for (String what : tested) {
-      assertEquals(value, what);
-      count += 1;
-      if (count >= times) break;
-    }
-    assertEquals(times, count);
-  }
-
   public void testChainIterableByLists() {
     List<String> list1 = Arrays.asList("foo", "bar", "baz");
     List<String> list2 = Arrays.asList("ichi", "ni", "san");
@@ -113,83 +100,6 @@ public class IteratorsTest extends TestCase {
     assertEquals(all.size(), count);
   }
 
-
-  public void testChainIteratorByLists() {
-    List<String> list1 = Arrays.asList("foo", "bar", "baz");
-    List<String> list2 = Arrays.asList("ichi", "ni", "san");
-    List<String> list3 = Arrays.asList("a", "s", "d", "f");
-    List<String> all = new ArrayList<String>();
-    all.addAll(list1);
-    all.addAll(list2);
-    all.addAll(list3);
-    ChainIterator<String> tested = new ChainIterator<String>(list1.iterator()).add(list2.iterator()).add(list3.iterator());
-    int count = 0;
-    String what;
-    while (tested.hasNext()) {
-      what = tested.next();
-      assertEquals(all.get(count), what);
-      count += 1;
-    }
-    assertEquals(all.size(), count);
-  }
-
-  public void testChainIteratorEmptyFirst() {
-    List<String> list1 = Arrays.asList();
-    List<String> list2 = Arrays.asList("ichi", "ni", "san");
-    List<String> list3 = Arrays.asList("a", "s", "d", "f");
-    List<String> all = new ArrayList<String>();
-    all.addAll(list1);
-    all.addAll(list2);
-    all.addAll(list3);
-    ChainIterator<String> tested = new ChainIterator<String>(list1.iterator()).add(list2.iterator()).add(list3.iterator());
-    int count = 0;
-    String what;
-    while (tested.hasNext()) {
-      what = tested.next();
-      assertEquals(all.get(count), what);
-      count += 1;
-    }
-    assertEquals(all.size(), count);
-  }
-
-  public void testChainIteratorEmptyLast() {
-    List<String> list1 = Arrays.asList("foo", "bar", "baz");
-    List<String> list2 = Arrays.asList("ichi", "ni", "san");
-    List<String> list3 = Arrays.asList();
-    List<String> all = new ArrayList<String>();
-    all.addAll(list1);
-    all.addAll(list2);
-    all.addAll(list3);
-    ChainIterator<String> tested = new ChainIterator<String>(list1.iterator()).add(list2.iterator()).add(list3.iterator());
-    int count = 0;
-    String what;
-    while (tested.hasNext()) {
-      what = tested.next();
-      assertEquals(all.get(count), what);
-      count += 1;
-    }
-    assertEquals(all.size(), count);
-  }
-
-  public void testChainIteratorEmptyMiddle() {
-    List<String> list1 = Arrays.asList("foo", "bar", "baz");
-    List<String> list2 = Arrays.asList();
-    List<String> list3 = Arrays.asList("a", "s", "d", "f");
-    List<String> all = new ArrayList<String>();
-    all.addAll(list1);
-    all.addAll(list2);
-    all.addAll(list3);
-    ChainIterator<String> tested = new ChainIterator<String>(list1.iterator()).add(list2.iterator()).add(list3.iterator());
-    int count = 0;
-    String what;
-    while (tested.hasNext()) {
-      what = tested.next();
-      assertEquals(all.get(count), what);
-      count += 1;
-    }
-    assertEquals(all.size(), count);
-  }
-
   public void testToStringDoesntExhaustIterator() {
     final ChainIterable<String> initial = new ChainIterable<String>();
     initial.addItem("foo");