From 5119be63eabe502570099989479b58b4e87903e4 Mon Sep 17 00:00:00 2001 From: Natsu Kagami Date: Fri, 30 May 2025 16:38:08 +0200 Subject: [PATCH] Port scala/scala#10437 to scala2-library-cc This is a Tasty breaking change. --- .../convert/JavaCollectionWrappers.scala | 4 +- .../collection/immutable/ChampCommon.scala | 5 ++- .../scala/collection/immutable/HashMap.scala | 41 +++++++++---------- .../scala/collection/immutable/HashSet.scala | 18 ++++---- .../scala/collection/immutable/Vector.scala | 2 +- 5 files changed, 34 insertions(+), 36 deletions(-) diff --git a/scala2-library-cc/src/scala/collection/convert/JavaCollectionWrappers.scala b/scala2-library-cc/src/scala/collection/convert/JavaCollectionWrappers.scala index e826bdeb23db..868ccb3b4b19 100644 --- a/scala2-library-cc/src/scala/collection/convert/JavaCollectionWrappers.scala +++ b/scala2-library-cc/src/scala/collection/convert/JavaCollectionWrappers.scala @@ -39,13 +39,13 @@ private[collection] object JavaCollectionWrappers extends Serializable { } @SerialVersionUID(3L) - class JIteratorWrapper[A](val underlying: ju.Iterator[A]) extends AbstractIterator[A] with Iterator[A] with Serializable { + class JIteratorWrapper[A](val underlying: ju.Iterator[A]) extends AbstractIterator[A] with Serializable { def hasNext = underlying.hasNext def next() = underlying.next } @SerialVersionUID(3L) - class JEnumerationWrapper[A](val underlying: ju.Enumeration[A]) extends AbstractIterator[A] with Iterator[A] with Serializable { + class JEnumerationWrapper[A](val underlying: ju.Enumeration[A]) extends AbstractIterator[A] with Serializable { def hasNext = underlying.hasMoreElements def next() = underlying.nextElement } diff --git a/scala2-library-cc/src/scala/collection/immutable/ChampCommon.scala b/scala2-library-cc/src/scala/collection/immutable/ChampCommon.scala index 3da269dccbd8..c872da8543fa 100644 --- a/scala2-library-cc/src/scala/collection/immutable/ChampCommon.scala +++ b/scala2-library-cc/src/scala/collection/immutable/ChampCommon.scala @@ -13,6 +13,7 @@ package scala.collection.immutable +import scala.collection.AbstractIterator import java.lang.Integer.bitCount import java.lang.Math.ceil import java.lang.System.arraycopy @@ -105,7 +106,7 @@ private[collection] abstract class Node[T <: Node[T]] { * * @tparam T the trie node type we are iterating over */ -private[immutable] abstract class ChampBaseIterator[T <: Node[T]] { +private[immutable] abstract class ChampBaseIterator[A, T <: Node[T]] extends AbstractIterator[A] { import Node.MaxDepth @@ -192,7 +193,7 @@ private[immutable] abstract class ChampBaseIterator[T <: Node[T]] { * * @tparam T the trie node type we are iterating over */ -private[immutable] abstract class ChampBaseReverseIterator[T <: Node[T]] { +private[immutable] abstract class ChampBaseReverseIterator[A, T <: Node[T]] extends AbstractIterator[A] { import Node.MaxDepth diff --git a/scala2-library-cc/src/scala/collection/immutable/HashMap.scala b/scala2-library-cc/src/scala/collection/immutable/HashMap.scala index 2d1179ef0ee6..2514c8190a32 100644 --- a/scala2-library-cc/src/scala/collection/immutable/HashMap.scala +++ b/scala2-library-cc/src/scala/collection/immutable/HashMap.scala @@ -699,12 +699,12 @@ private final class BitmapIndexedMapNode[K, +V]( if ((dataMap & bitpos) != 0) { val index = indexFrom(dataMap, mask, bitpos) val payload = getPayload(index) - if (key == payload._1) payload else throw new NoSuchElementException + if (key == payload._1) payload else Iterator.empty.next() } else if ((nodeMap & bitpos) != 0) { val index = indexFrom(nodeMap, mask, bitpos) getNode(index).getTuple(key, originalHash, hash, shift + BitPartitionSize) } else { - throw new NoSuchElementException + Iterator.empty.next() } } @@ -1873,7 +1873,7 @@ private final class HashCollisionMapNode[K, +V ]( def size: Int = content.length - def apply(key: K, originalHash: Int, hash: Int, shift: Int): V = get(key, originalHash, hash, shift).getOrElse(throw new NoSuchElementException) + def apply(key: K, originalHash: Int, hash: Int, shift: Int): V = get(key, originalHash, hash, shift).getOrElse(Iterator.empty.next()) def get(key: K, originalHash: Int, hash: Int, shift: Int): Option[V] = if (this.hash == hash) { @@ -1883,7 +1883,7 @@ private final class HashCollisionMapNode[K, +V ]( override def getTuple(key: K, originalHash: Int, hash: Int, shift: Int): (K, V) = { val index = indexOf(key) - if (index >= 0) content(index) else throw new NoSuchElementException + if (index >= 0) content(index) else Iterator.empty.next() } def getOrElse[V1 >: V](key: K, originalHash: Int, hash: Int, shift: Int, f: => V1): V1 = { @@ -2096,11 +2096,10 @@ private final class HashCollisionMapNode[K, +V ]( } private final class MapKeyIterator[K, V](rootNode: MapNode[K, V]) - extends ChampBaseIterator[MapNode[K, V]](rootNode) with Iterator[K] { + extends ChampBaseIterator[K, MapNode[K, V]](rootNode) { def next() = { - if (!hasNext) - throw new NoSuchElementException + if (!hasNext) Iterator.empty.next() val key = currentValueNode.getKey(currentValueCursor) currentValueCursor += 1 @@ -2111,11 +2110,10 @@ private final class MapKeyIterator[K, V](rootNode: MapNode[K, V]) } private final class MapValueIterator[K, V](rootNode: MapNode[K, V]) - extends ChampBaseIterator[MapNode[K, V]](rootNode) with Iterator[V] { + extends ChampBaseIterator[V, MapNode[K, V]](rootNode) { def next() = { - if (!hasNext) - throw new NoSuchElementException + if (!hasNext) Iterator.empty.next() val value = currentValueNode.getValue(currentValueCursor) currentValueCursor += 1 @@ -2125,11 +2123,10 @@ private final class MapValueIterator[K, V](rootNode: MapNode[K, V]) } private final class MapKeyValueTupleIterator[K, V](rootNode: MapNode[K, V]) - extends ChampBaseIterator[MapNode[K, V]](rootNode) with Iterator[(K, V)] { + extends ChampBaseIterator[(K, V), MapNode[K, V]](rootNode) { def next() = { - if (!hasNext) - throw new NoSuchElementException + if (!hasNext) Iterator.empty.next() val payload = currentValueNode.getPayload(currentValueCursor) currentValueCursor += 1 @@ -2140,11 +2137,10 @@ private final class MapKeyValueTupleIterator[K, V](rootNode: MapNode[K, V]) } private final class MapKeyValueTupleReverseIterator[K, V](rootNode: MapNode[K, V]) - extends ChampBaseReverseIterator[MapNode[K, V]](rootNode) with Iterator[(K, V)] { + extends ChampBaseReverseIterator[(K, V), MapNode[K, V]](rootNode) { def next() = { - if (!hasNext) - throw new NoSuchElementException + if (!hasNext) Iterator.empty.next() val payload = currentValueNode.getPayload(currentValueCursor) currentValueCursor -= 1 @@ -2154,13 +2150,12 @@ private final class MapKeyValueTupleReverseIterator[K, V](rootNode: MapNode[K, V } private final class MapKeyValueTupleHashIterator[K, V](rootNode: MapNode[K, V]) - extends ChampBaseReverseIterator[MapNode[K, V]](rootNode) with Iterator[Any] { + extends ChampBaseReverseIterator[Any, MapNode[K, V]](rootNode) { private[this] var hash = 0 private[this] var value: V = _ override def hashCode(): Int = MurmurHash3.tuple2Hash(hash, value.##, MurmurHash3.productSeed) def next() = { - if (!hasNext) - throw new NoSuchElementException + if (!hasNext) Iterator.empty.next() hash = currentValueNode.getHash(currentValueCursor) value = currentValueNode.getValue(currentValueCursor) @@ -2170,7 +2165,7 @@ private final class MapKeyValueTupleHashIterator[K, V](rootNode: MapNode[K, V]) } /** Used in HashMap[K, V]#removeAll(HashSet[K]) */ -private final class MapNodeRemoveAllSetNodeIterator[K](rootSetNode: SetNode[K]) extends ChampBaseIterator(rootSetNode) { +private final class MapNodeRemoveAllSetNodeIterator[K](rootSetNode: SetNode[K]) extends ChampBaseIterator[K, SetNode[K]](rootSetNode) { /** Returns the result of immutably removing all keys in `rootSetNode` from `rootMapNode` */ def removeAll[V](rootMapNode: BitmapIndexedMapNode[K, V]): BitmapIndexedMapNode[K, V] = { var curr = rootMapNode @@ -2186,6 +2181,8 @@ private final class MapNodeRemoveAllSetNodeIterator[K](rootSetNode: SetNode[K]) } curr } + + override def next() = Iterator.empty.next() } /** @@ -2371,7 +2368,7 @@ private[immutable] final class HashMapBuilder[K, V] extends ReusableBuilder[(K, ensureUnaliased() xs match { case hm: HashMap[K, V] => - new ChampBaseIterator[MapNode[K, V]](hm.rootNode) { + new ChampBaseIterator[(K, V), MapNode[K, V]](hm.rootNode) { while(hasNext) { val originalHash = currentValueNode.getHash(currentValueCursor) update( @@ -2384,6 +2381,8 @@ private[immutable] final class HashMapBuilder[K, V] extends ReusableBuilder[(K, ) currentValueCursor += 1 } + + override def next() = Iterator.empty.next() } case hm: collection.mutable.HashMap[K, V] => val iter = hm.nodeIterator diff --git a/scala2-library-cc/src/scala/collection/immutable/HashSet.scala b/scala2-library-cc/src/scala/collection/immutable/HashSet.scala index b4b8f9fdf27c..3533cb2942fe 100644 --- a/scala2-library-cc/src/scala/collection/immutable/HashSet.scala +++ b/scala2-library-cc/src/scala/collection/immutable/HashSet.scala @@ -1884,11 +1884,10 @@ private final class HashCollisionSetNode[A](val originalHash: Int, val hash: Int } private final class SetIterator[A](rootNode: SetNode[A]) - extends ChampBaseIterator[SetNode[A]](rootNode) with Iterator[A] { + extends ChampBaseIterator[A, SetNode[A]](rootNode) { def next() = { - if (!hasNext) - throw new NoSuchElementException + if (!hasNext) Iterator.empty.next() val payload = currentValueNode.getPayload(currentValueCursor) currentValueCursor += 1 @@ -1899,11 +1898,10 @@ private final class SetIterator[A](rootNode: SetNode[A]) } private final class SetReverseIterator[A](rootNode: SetNode[A]) - extends ChampBaseReverseIterator[SetNode[A]](rootNode) with Iterator[A] { + extends ChampBaseReverseIterator[A, SetNode[A]](rootNode) { def next(): A = { - if (!hasNext) - throw new NoSuchElementException + if (!hasNext) Iterator.empty.next() val payload = currentValueNode.getPayload(currentValueCursor) currentValueCursor -= 1 @@ -1914,13 +1912,12 @@ private final class SetReverseIterator[A](rootNode: SetNode[A]) } private final class SetHashIterator[A](rootNode: SetNode[A]) - extends ChampBaseIterator[SetNode[A]](rootNode) with Iterator[AnyRef] { + extends ChampBaseIterator[AnyRef, SetNode[A]](rootNode) { private[this] var hash = 0 override def hashCode(): Int = hash def next(): AnyRef = { - if (!hasNext) - throw new NoSuchElementException + if (!hasNext) Iterator.empty.next() hash = currentValueNode.getHash(currentValueCursor) currentValueCursor += 1 @@ -2089,7 +2086,7 @@ private[collection] final class HashSetBuilder[A] extends ReusableBuilder[A, Has ensureUnaliased() xs match { case hm: HashSet[A] => - new ChampBaseIterator[SetNode[A]](hm.rootNode) { + new ChampBaseIterator[A, SetNode[A]](hm.rootNode) { while(hasNext) { val originalHash = currentValueNode.getHash(currentValueCursor) update( @@ -2101,6 +2098,7 @@ private[collection] final class HashSetBuilder[A] extends ReusableBuilder[A, Has ) currentValueCursor += 1 } + override def next() = Iterator.empty.next() } case other => val it = other.iterator diff --git a/scala2-library-cc/src/scala/collection/immutable/Vector.scala b/scala2-library-cc/src/scala/collection/immutable/Vector.scala index d584d4a446af..593fddd89f5b 100644 --- a/scala2-library-cc/src/scala/collection/immutable/Vector.scala +++ b/scala2-library-cc/src/scala/collection/immutable/Vector.scala @@ -2230,7 +2230,7 @@ private object VectorStatics { } -private final class NewVectorIterator[A](v: Vector[A], private[this] var totalLength: Int, private[this] val sliceCount: Int) extends Iterator[A] with java.lang.Cloneable { +private final class NewVectorIterator[A](v: Vector[A], private[this] var totalLength: Int, private[this] val sliceCount: Int) extends AbstractIterator[A] with java.lang.Cloneable { private[this] var a1: Arr1 = v.prefix1 private[this] var a2: Arr2 = _