Skip to content

Commit 775ddb2

Browse files
authored
Merge pull request scala#10437 from som-snytt/deprecate/unabstracted
Avoid directly inheriting Iterator
2 parents 86f40c2 + ccec3dc commit 775ddb2

File tree

13 files changed

+59
-44
lines changed

13 files changed

+59
-44
lines changed

project/MimaFilters.scala

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,19 @@ object MimaFilters extends AutoPlugin {
4141

4242
// PR 10406
4343
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.reflect.runtime.JavaUniverse#PerRunReporting.deprecationWarning"),
44+
45+
// extend AbstractIterator
46+
ProblemFilters.exclude[MissingTypesProblem]("scala.collection.immutable.MapKeyIterator"),
47+
ProblemFilters.exclude[MissingTypesProblem]("scala.collection.immutable.MapKeyValueTupleHashIterator"),
48+
ProblemFilters.exclude[MissingTypesProblem]("scala.collection.immutable.MapKeyValueTupleIterator"),
49+
ProblemFilters.exclude[MissingTypesProblem]("scala.collection.immutable.MapKeyValueTupleReverseIterator"),
50+
ProblemFilters.exclude[MissingTypesProblem]("scala.collection.immutable.MapNodeRemoveAllSetNodeIterator"),
51+
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.immutable.MapNodeRemoveAllSetNodeIterator.next"),
52+
ProblemFilters.exclude[MissingTypesProblem]("scala.collection.immutable.MapValueIterator"),
53+
ProblemFilters.exclude[MissingTypesProblem]("scala.collection.immutable.NewVectorIterator"),
54+
ProblemFilters.exclude[MissingTypesProblem]("scala.collection.immutable.SetHashIterator"),
55+
ProblemFilters.exclude[MissingTypesProblem]("scala.collection.immutable.SetIterator"),
56+
ProblemFilters.exclude[MissingTypesProblem]("scala.collection.immutable.SetReverseIterator"),
4457
)
4558

4659
override val buildSettings = Seq(

src/compiler/scala/tools/nsc/backend/jvm/analysis/AliasingAnalyzer.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ package backend.jvm
1515
package analysis
1616

1717
import scala.annotation.switch
18+
import scala.collection.AbstractIterator
1819
import scala.collection.mutable
1920
import scala.tools.asm.Opcodes
2021
import scala.tools.asm.tree._
@@ -423,7 +424,7 @@ class BasicAliasingAnalyzer(methodNode: MethodNode, classInternalName: InternalN
423424
/**
424425
* An iterator over Int (required to prevent boxing the result of next).
425426
*/
426-
abstract class IntIterator extends Iterator[Int] {
427+
abstract class IntIterator extends AbstractIterator[Int] {
427428
def hasNext: Boolean
428429
def next(): Int
429430
}

src/compiler/scala/tools/nsc/backend/jvm/opt/BoxUnbox.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ package backend.jvm
1515
package opt
1616

1717
import scala.annotation.tailrec
18+
import scala.collection.AbstractIterator
1819
import scala.collection.mutable
1920
import scala.jdk.CollectionConverters._
2021
import scala.tools.asm.Opcodes._
@@ -551,7 +552,7 @@ abstract class BoxUnbox {
551552
* For a set of box creation operations and a corresponding set of box consumer operations,
552553
* this iterator returns all copy operations (load, store, dup) that are in between.
553554
*/
554-
class CopyOpsIterator(initialCreations: Set[BoxCreation], finalCons: Set[BoxConsumer], prodCons: ProdConsAnalyzer) extends Iterator[AbstractInsnNode] {
555+
class CopyOpsIterator(initialCreations: Set[BoxCreation], finalCons: Set[BoxConsumer], prodCons: ProdConsAnalyzer) extends AbstractIterator[AbstractInsnNode] {
555556
private val queue = mutable.Queue.empty[AbstractInsnNode] ++= initialCreations.iterator.flatMap(_.boxConsumers(prodCons, ultimate = false))
556557

557558
// a single copy operation can consume multiple producers: val a = if (b) box(1) else box(2).

src/compiler/scala/tools/nsc/util/JavaCharArrayReader.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ package scala
1414
package tools.nsc
1515
package util
1616

17+
import scala.collection.AbstractIterator
1718
import scala.collection.immutable.ArraySeq
1819
import scala.reflect.internal.Chars._
1920
import scala.util.chaining._
2021

2122
class JavaCharArrayReader(buf: ArraySeq.ofChar, start: Int, /* startline: int, startcol: int, */
22-
decodeUni: Boolean, error: String => Unit) extends Iterator[Char] with Cloneable {
23+
decodeUni: Boolean, error: String => Unit) extends AbstractIterator[Char] with Cloneable {
2324

2425
def this(buf: ArraySeq.ofChar, decodeUni: Boolean, error: String => Unit) =
2526
this(buf, 0, /* 1, 1, */ decodeUni, error)

src/interactive/scala/tools/nsc/interactive/Pickler.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ package scala.tools.nsc.interactive
1414

1515
import Lexer._
1616
import java.io.Writer
17+
import scala.collection.AbstractIterator
1718

1819
/** An abstract class for writing and reading Scala objects to and
1920
* from a legible representation. The representation follows the following grammar:
@@ -277,7 +278,7 @@ object Pickler {
277278
p.pickle(wr, x)
278279
}
279280
}
280-
def unpickle(rd: Lexer): Unpickled[Iterator[T]] = UnpickleSuccess(new Iterator[T] {
281+
def unpickle(rd: Lexer): Unpickled[Iterator[T]] = UnpickleSuccess(new AbstractIterator[T] {
281282
var first = true
282283
def hasNext = {
283284
val t = rd.token

src/library/scala/collection/convert/JavaCollectionWrappers.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ private[collection] object JavaCollectionWrappers extends Serializable {
4242
}
4343

4444
@SerialVersionUID(3L)
45-
class JIteratorWrapper[A](val underlying: ju.Iterator[A]) extends AbstractIterator[A] with Iterator[A] with Serializable {
45+
class JIteratorWrapper[A](val underlying: ju.Iterator[A]) extends AbstractIterator[A] with Serializable {
4646
def hasNext = underlying.hasNext
4747
def next() = underlying.next
4848
override def equals(other: Any): Boolean = other match {
@@ -53,7 +53,7 @@ private[collection] object JavaCollectionWrappers extends Serializable {
5353
}
5454

5555
@SerialVersionUID(3L)
56-
class JEnumerationWrapper[A](val underlying: ju.Enumeration[A]) extends AbstractIterator[A] with Iterator[A] with Serializable {
56+
class JEnumerationWrapper[A](val underlying: ju.Enumeration[A]) extends AbstractIterator[A] with Serializable {
5757
def hasNext = underlying.hasMoreElements
5858
def next() = underlying.nextElement
5959
override def equals(other: Any): Boolean = other match {

src/library/scala/collection/immutable/ChampCommon.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
package scala.collection.immutable
1414

15-
15+
import scala.collection.AbstractIterator
1616
import java.lang.Integer.bitCount
1717
import java.lang.Math.ceil
1818
import java.lang.System.arraycopy
@@ -104,7 +104,7 @@ private[collection] abstract class Node[T <: Node[T]] {
104104
*
105105
* @tparam T the trie node type we are iterating over
106106
*/
107-
private[immutable] abstract class ChampBaseIterator[T <: Node[T]] {
107+
private[immutable] abstract class ChampBaseIterator[A, T <: Node[T]] extends AbstractIterator[A] {
108108

109109
import Node.MaxDepth
110110

@@ -192,7 +192,7 @@ private[immutable] abstract class ChampBaseIterator[T <: Node[T]] {
192192
*
193193
* @tparam T the trie node type we are iterating over
194194
*/
195-
private[immutable] abstract class ChampBaseReverseIterator[T <: Node[T]] {
195+
private[immutable] abstract class ChampBaseReverseIterator[A, T <: Node[T]] extends AbstractIterator[A] {
196196

197197
import Node.MaxDepth
198198

src/library/scala/collection/immutable/HashMap.scala

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -698,12 +698,12 @@ private final class BitmapIndexedMapNode[K, +V](
698698
if ((dataMap & bitpos) != 0) {
699699
val index = indexFrom(dataMap, mask, bitpos)
700700
val payload = getPayload(index)
701-
if (key == payload._1) payload else throw new NoSuchElementException
701+
if (key == payload._1) payload else Iterator.empty.next()
702702
} else if ((nodeMap & bitpos) != 0) {
703703
val index = indexFrom(nodeMap, mask, bitpos)
704704
getNode(index).getTuple(key, originalHash, hash, shift + BitPartitionSize)
705705
} else {
706-
throw new NoSuchElementException
706+
Iterator.empty.next()
707707
}
708708
}
709709

@@ -1872,7 +1872,7 @@ private final class HashCollisionMapNode[K, +V ](
18721872

18731873
def size: Int = content.length
18741874

1875-
def apply(key: K, originalHash: Int, hash: Int, shift: Int): V = get(key, originalHash, hash, shift).getOrElse(throw new NoSuchElementException)
1875+
def apply(key: K, originalHash: Int, hash: Int, shift: Int): V = get(key, originalHash, hash, shift).getOrElse(Iterator.empty.next())
18761876

18771877
def get(key: K, originalHash: Int, hash: Int, shift: Int): Option[V] =
18781878
if (this.hash == hash) {
@@ -1882,7 +1882,7 @@ private final class HashCollisionMapNode[K, +V ](
18821882

18831883
override def getTuple(key: K, originalHash: Int, hash: Int, shift: Int): (K, V) = {
18841884
val index = indexOf(key)
1885-
if (index >= 0) content(index) else throw new NoSuchElementException
1885+
if (index >= 0) content(index) else Iterator.empty.next()
18861886
}
18871887

18881888
def getOrElse[V1 >: V](key: K, originalHash: Int, hash: Int, shift: Int, f: => V1): V1 = {
@@ -2095,11 +2095,10 @@ private final class HashCollisionMapNode[K, +V ](
20952095
}
20962096

20972097
private final class MapKeyIterator[K, V](rootNode: MapNode[K, V])
2098-
extends ChampBaseIterator[MapNode[K, V]](rootNode) with Iterator[K] {
2098+
extends ChampBaseIterator[K, MapNode[K, V]](rootNode) {
20992099

21002100
def next() = {
2101-
if (!hasNext)
2102-
throw new NoSuchElementException
2101+
if (!hasNext) Iterator.empty.next()
21032102

21042103
val key = currentValueNode.getKey(currentValueCursor)
21052104
currentValueCursor += 1
@@ -2110,11 +2109,10 @@ private final class MapKeyIterator[K, V](rootNode: MapNode[K, V])
21102109
}
21112110

21122111
private final class MapValueIterator[K, V](rootNode: MapNode[K, V])
2113-
extends ChampBaseIterator[MapNode[K, V]](rootNode) with Iterator[V] {
2112+
extends ChampBaseIterator[V, MapNode[K, V]](rootNode) {
21142113

21152114
def next() = {
2116-
if (!hasNext)
2117-
throw new NoSuchElementException
2115+
if (!hasNext) Iterator.empty.next()
21182116

21192117
val value = currentValueNode.getValue(currentValueCursor)
21202118
currentValueCursor += 1
@@ -2124,11 +2122,10 @@ private final class MapValueIterator[K, V](rootNode: MapNode[K, V])
21242122
}
21252123

21262124
private final class MapKeyValueTupleIterator[K, V](rootNode: MapNode[K, V])
2127-
extends ChampBaseIterator[MapNode[K, V]](rootNode) with Iterator[(K, V)] {
2125+
extends ChampBaseIterator[(K, V), MapNode[K, V]](rootNode) {
21282126

21292127
def next() = {
2130-
if (!hasNext)
2131-
throw new NoSuchElementException
2128+
if (!hasNext) Iterator.empty.next()
21322129

21332130
val payload = currentValueNode.getPayload(currentValueCursor)
21342131
currentValueCursor += 1
@@ -2139,11 +2136,10 @@ private final class MapKeyValueTupleIterator[K, V](rootNode: MapNode[K, V])
21392136
}
21402137

21412138
private final class MapKeyValueTupleReverseIterator[K, V](rootNode: MapNode[K, V])
2142-
extends ChampBaseReverseIterator[MapNode[K, V]](rootNode) with Iterator[(K, V)] {
2139+
extends ChampBaseReverseIterator[(K, V), MapNode[K, V]](rootNode) {
21432140

21442141
def next() = {
2145-
if (!hasNext)
2146-
throw new NoSuchElementException
2142+
if (!hasNext) Iterator.empty.next()
21472143

21482144
val payload = currentValueNode.getPayload(currentValueCursor)
21492145
currentValueCursor -= 1
@@ -2153,13 +2149,12 @@ private final class MapKeyValueTupleReverseIterator[K, V](rootNode: MapNode[K, V
21532149
}
21542150

21552151
private final class MapKeyValueTupleHashIterator[K, V](rootNode: MapNode[K, V])
2156-
extends ChampBaseReverseIterator[MapNode[K, V]](rootNode) with Iterator[Any] {
2152+
extends ChampBaseReverseIterator[Any, MapNode[K, V]](rootNode) {
21572153
private[this] var hash = 0
21582154
private[this] var value: V = _
21592155
override def hashCode(): Int = MurmurHash3.tuple2Hash(hash, value.##, MurmurHash3.productSeed)
21602156
def next(): MapKeyValueTupleHashIterator[K, V] = {
2161-
if (!hasNext)
2162-
throw new NoSuchElementException
2157+
if (!hasNext) Iterator.empty.next()
21632158

21642159
hash = currentValueNode.getHash(currentValueCursor)
21652160
value = currentValueNode.getValue(currentValueCursor)
@@ -2169,7 +2164,7 @@ private final class MapKeyValueTupleHashIterator[K, V](rootNode: MapNode[K, V])
21692164
}
21702165

21712166
/** Used in HashMap[K, V]#removeAll(HashSet[K]) */
2172-
private final class MapNodeRemoveAllSetNodeIterator[K](rootSetNode: SetNode[K]) extends ChampBaseIterator(rootSetNode) {
2167+
private final class MapNodeRemoveAllSetNodeIterator[K](rootSetNode: SetNode[K]) extends ChampBaseIterator[K, SetNode[K]](rootSetNode) {
21732168
/** Returns the result of immutably removing all keys in `rootSetNode` from `rootMapNode` */
21742169
def removeAll[V](rootMapNode: BitmapIndexedMapNode[K, V]): BitmapIndexedMapNode[K, V] = {
21752170
var curr = rootMapNode
@@ -2185,6 +2180,8 @@ private final class MapNodeRemoveAllSetNodeIterator[K](rootSetNode: SetNode[K])
21852180
}
21862181
curr
21872182
}
2183+
2184+
override def next() = Iterator.empty.next()
21882185
}
21892186

21902187
/**
@@ -2370,7 +2367,7 @@ private[immutable] final class HashMapBuilder[K, V] extends ReusableBuilder[(K,
23702367
ensureUnaliased()
23712368
xs match {
23722369
case hm: HashMap[K, V] =>
2373-
new ChampBaseIterator[MapNode[K, V]](hm.rootNode) {
2370+
new ChampBaseIterator[(K, V), MapNode[K, V]](hm.rootNode) {
23742371
while(hasNext) {
23752372
val originalHash = currentValueNode.getHash(currentValueCursor)
23762373
update(
@@ -2383,6 +2380,8 @@ private[immutable] final class HashMapBuilder[K, V] extends ReusableBuilder[(K,
23832380
)
23842381
currentValueCursor += 1
23852382
}
2383+
2384+
override def next() = Iterator.empty.next()
23862385
}
23872386
case hm: collection.mutable.HashMap[K, V] =>
23882387
val iter = hm.nodeIterator

src/library/scala/collection/immutable/HashSet.scala

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1883,11 +1883,10 @@ private final class HashCollisionSetNode[A](val originalHash: Int, val hash: Int
18831883
}
18841884

18851885
private final class SetIterator[A](rootNode: SetNode[A])
1886-
extends ChampBaseIterator[SetNode[A]](rootNode) with Iterator[A] {
1886+
extends ChampBaseIterator[A, SetNode[A]](rootNode) {
18871887

18881888
def next() = {
1889-
if (!hasNext)
1890-
throw new NoSuchElementException
1889+
if (!hasNext) Iterator.empty.next()
18911890

18921891
val payload = currentValueNode.getPayload(currentValueCursor)
18931892
currentValueCursor += 1
@@ -1898,11 +1897,10 @@ private final class SetIterator[A](rootNode: SetNode[A])
18981897
}
18991898

19001899
private final class SetReverseIterator[A](rootNode: SetNode[A])
1901-
extends ChampBaseReverseIterator[SetNode[A]](rootNode) with Iterator[A] {
1900+
extends ChampBaseReverseIterator[A, SetNode[A]](rootNode) {
19021901

19031902
def next(): A = {
1904-
if (!hasNext)
1905-
throw new NoSuchElementException
1903+
if (!hasNext) Iterator.empty.next()
19061904

19071905
val payload = currentValueNode.getPayload(currentValueCursor)
19081906
currentValueCursor -= 1
@@ -1913,13 +1911,12 @@ private final class SetReverseIterator[A](rootNode: SetNode[A])
19131911
}
19141912

19151913
private final class SetHashIterator[A](rootNode: SetNode[A])
1916-
extends ChampBaseIterator[SetNode[A]](rootNode) with Iterator[AnyRef] {
1914+
extends ChampBaseIterator[AnyRef, SetNode[A]](rootNode) {
19171915
private[this] var hash = 0
19181916
override def hashCode(): Int = hash
19191917

19201918
def next(): AnyRef = {
1921-
if (!hasNext)
1922-
throw new NoSuchElementException
1919+
if (!hasNext) Iterator.empty.next()
19231920

19241921
hash = currentValueNode.getHash(currentValueCursor)
19251922
currentValueCursor += 1
@@ -2088,7 +2085,7 @@ private[collection] final class HashSetBuilder[A] extends ReusableBuilder[A, Has
20882085
ensureUnaliased()
20892086
xs match {
20902087
case hm: HashSet[A] =>
2091-
new ChampBaseIterator[SetNode[A]](hm.rootNode) {
2088+
new ChampBaseIterator[A, SetNode[A]](hm.rootNode) {
20922089
while(hasNext) {
20932090
val originalHash = currentValueNode.getHash(currentValueCursor)
20942091
update(
@@ -2100,6 +2097,7 @@ private[collection] final class HashSetBuilder[A] extends ReusableBuilder[A, Has
21002097
)
21012098
currentValueCursor += 1
21022099
}
2100+
override def next() = Iterator.empty.next()
21032101
}
21042102
case other =>
21052103
val it = other.iterator

src/library/scala/collection/immutable/Vector.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2229,7 +2229,7 @@ private object VectorStatics {
22292229
}
22302230

22312231

2232-
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 {
2232+
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 {
22332233

22342234
private[this] var a1: Arr1 = v.prefix1
22352235
private[this] var a2: Arr2 = _

src/library/scala/util/matching/Regex.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -803,7 +803,7 @@ object Regex {
803803
* @see [[java.util.regex.Matcher]]
804804
*/
805805
class MatchIterator(val source: CharSequence, val regex: Regex, private[Regex] val _groupNames: Seq[String])
806-
extends AbstractIterator[String] with Iterator[String] with MatchData { self =>
806+
extends AbstractIterator[String] with MatchData { self =>
807807

808808
@deprecated("groupNames does not include inline group names, and should not be used anymore", "2.13.7")
809809
val groupNames: Seq[String] = _groupNames

src/reflect/scala/reflect/internal/Scopes.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ trait Scopes extends api.Scopes { self: SymbolTable =>
6464
}
6565

6666
/** A default Scope iterator, that retrieves elements in the order given by ScopeEntry. */
67-
private[Scopes] class ScopeIterator(owner: Scope) extends Iterator[Symbol] {
67+
private[Scopes] class ScopeIterator(owner: Scope) extends AbstractIterator[Symbol] {
6868
private[this] var elem: ScopeEntry = owner.elems
6969

7070
def hasNext: Boolean = (elem ne null) && (elem.owner == this.owner)

src/reflect/scala/reflect/internal/util/Collections.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ package scala
1414
package reflect.internal.util
1515

1616
import scala.reflect.ClassTag
17+
import scala.collection.AbstractIterator
1718
import scala.collection.{immutable, mutable}
1819
import scala.annotation.tailrec
1920
import mutable.ListBuffer
@@ -314,7 +315,7 @@ trait Collections {
314315
}
315316

316317
final def mapFilter2[A, B, C](itA: Iterator[A], itB: Iterator[B])(f: (A, B) => Option[C]): Iterator[C] =
317-
new Iterator[C] {
318+
new AbstractIterator[C] {
318319
private[this] var head: Option[C] = None
319320
private[this] def advanceHead(): Unit =
320321
while (head.isEmpty && itA.hasNext && itB.hasNext) {

0 commit comments

Comments
 (0)