Skip to content

Commit

Permalink
Collections library tidying and deprecation. Separate parts are liste…
Browse files Browse the repository at this point in the history
…d below.

Collections library tidying, part one: scripting.

Everything in scala.collection.scripting is deprecated now, along with the
<< method that is implemented in a few other classes.  Scripting does not
seem used at all, and anyone who did can easily write a wrapper that does
the same thing.

Deprecated *Proxy collections.

The only place proxies were used in the library was in swing.ListView, and
that was easy to change to a lazy val.

Proxy itself is used in ScalaNumberProxy and such, so it was left
undeprecated.

Deprecated Synchronized* traits from collections.

Synchronizability does not compose well, and it requires careful examination
of every method (which has not actually been done).

Places where the Scala codebase needs to be fixed (eventually) include:
  scala.reflect.internal.util.Statistics$QuantMap
  scala.tools.nsc.interactive.Global (several places)

Deprecated LinkedList (including Double- and -Like variants).

Interface is idiosyncratic and dangerously low-level.  Although some
low-level functionality of this sort would be useful, this doesn't seem
to be the ideal implementation.

Also deprecated the extractFirst method in Queue as it exposes LinkedList.
Cannot shift internal representations away from LinkedList at this time
because of that method.

Deprecated non-finality of several toX collection methods.

Improved documentation of most toX collection methods to describe what the
expectation is for their behavior.  Additionally deprecated overriding of
  - toIterator in IterableLike (should always forward to iterator)
  - toTraversable in TraversableLike (should always return self)
  - toIndexedSeq in immutable.IndexedSeq (should always return self)
  - toMap in immutable.Map (should always return self)
  - toSet in immutable.Set (should always return self)

Did not do anything with IterableLike.toIterable or Seq/SeqLike.toSeq since
for some odd reason immutable.Range overrides those.

Deprecated Forwarders from collections.

Forwarding, without an automatic mechanism to keep up to date with changes
in the forwarded class, is inherently unreliable.  Absent a mechanism to
keep current, they're deprecated.  ListBuffer is the only class in the
collections library that uses forwarders, and that functionality can be
rolled into ListBuffer itself.

Deprecating immutable set/map adaptors.

They're a bad idea (barring compiler support) for the same reason that all
the other adaptors are a bad idea: they get out of date and probably have a
variety of performance bugs.

Deprecated inheritance from leaf classes in immutable collections.

Inheriting from leaf-classes in immutable collections is rarely a good idea
since whenever you use any interesting collections method you'll revert to
the original class.  Also, the methods are often designed to work with only
particular behavior, and an override would be difficult (at best) to make
work.  Fortunately, people seem to have realized this and there are few to
no cases of people extending PagedSeq and TreeSet and the like.

Note that in many cases the classes will become sealed not final.

Deprecated overriding of methods and inheritance from various mutable
collections.

Some mutable collections seem unsuited for overriding since to override
anything interesting you would need vast knowledge of internal data
structures and/or access to private methods.  These include
  - ArrayBuilder.ofX classes.
  - ArrayOps
  - Some methods of BitSet (moved others from private to protected final)
  - Some methods of HashTable and FlatHashTable
  - Some methods of HashMap and HashSet (esp += and -= which just forward)
  - Some methods of other maps and sets (LinkedHashX, ListMap, TreeSet)
  - PriorityQueue
  - UnrolledBuffer

This is a somewhat aggressive deprecation, the theory being better to try it
out now and back off if it's too much than not attempt the change and be
stuck with collections that can neither be safely inherited nor have
implementation details changed.

Note that I have made no changes--in this commit--which would cause
deprecation warnings in any of the Scala projects available on Maven (at
least as gathered by Adriaan).  There are deprecation warnings induced
within the library (esp. for classes/traits that should become static) and
the compiler.  I have not attempted to fix all the deprecations in the
compiler as some of them touch the IDE API (but these mostly involved
Synchronized which is inherently unsafe, so this should be fixed
eventually in coordination with the IDE code base(s)).

Updated test checks to include new deprecations.

Used a higher level implementation for messages in JavapClass.
  • Loading branch information
Ichoran committed Nov 7, 2013
1 parent e5ccdb0 commit 3cc99d7
Show file tree
Hide file tree
Showing 88 changed files with 215 additions and 25 deletions.
2 changes: 1 addition & 1 deletion src/library/scala/collection/GenTraversableOnce.scala
Expand Up @@ -518,7 +518,7 @@ trait GenTraversableOnce[+A] extends Any {
*/
def toIterator: Iterator[A]

/** Converts this $coll to a mutable buffer.
/** Uses the contents of this $coll to create a new mutable buffer.
* $willNotTerminateInf
* @return a buffer containing all elements of this $coll.
*/
Expand Down
20 changes: 18 additions & 2 deletions src/library/scala/collection/IterableLike.scala
Expand Up @@ -83,10 +83,26 @@ self =>
iterator.foldRight(z)(op)
override /*TraversableLike*/ def reduceRight[B >: A](op: (A, B) => B): B =
iterator.reduceRight(op)


/** Returns this $coll as an iterable collection.
*
* A new collection will not be built; lazy collections will stay lazy.
*
* $willNotTerminateInf
* @return an `Iterable` containing all elements of this $coll.
*/
override /*TraversableLike*/ def toIterable: Iterable[A] =
thisCollection
override /*TraversableLike*/ def toIterator: Iterator[A] =
iterator

/** Returns an Iterator over the elements in this $coll. Produces the same
* result as `iterator`.
* $willNotTerminateInf
* @return an Iterator containing all elements of this $coll.
*/
@deprecatedOverriding("toIterator should stay consistent with iterator for all Iterables: override iterator instead.", "2.11.0")
override def toIterator: Iterator[A] = iterator

override /*TraversableLike*/ def head: A =
iterator.next()

Expand Down
1 change: 1 addition & 0 deletions src/library/scala/collection/IterableProxyLike.scala
Expand Up @@ -23,6 +23,7 @@ import mutable.Buffer
* @version 2.8
* @since 2.8
*/
@deprecated("Proxying is deprecated due to lack of use and compiler-level support.", "2.11.0")
trait IterableProxyLike[+A, +Repr <: IterableLike[A, Repr] with Iterable[A]]
extends IterableLike[A, Repr]
with TraversableProxyLike[A, Repr] {
Expand Down
1 change: 1 addition & 0 deletions src/library/scala/collection/MapProxyLike.scala
Expand Up @@ -18,6 +18,7 @@ package collection
* @version 2.8
* @since 2.8
*/
@deprecated("Proxying is deprecated due to lack of use and compiler-level support.", "2.11.0")
trait MapProxyLike[A, +B, +This <: MapLike[A, B, This] with Map[A, B]]
extends MapLike[A, B, This]
with IterableProxyLike[(A, B), This]
Expand Down
2 changes: 1 addition & 1 deletion src/library/scala/collection/SeqLike.scala
Expand Up @@ -622,7 +622,7 @@ trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[
/** Converts this $coll to a sequence.
* $willNotTerminateInf
*
* Overridden for efficiency.
* A new collection will not be built; in particular, lazy sequences will stay lazy.
*/
override def toSeq: Seq[A] = thisCollection

Expand Down
1 change: 1 addition & 0 deletions src/library/scala/collection/SeqProxy.scala
Expand Up @@ -18,4 +18,5 @@ package collection
* @version 2.8
* @since 2.8
*/
@deprecated("Proxying is deprecated due to lack of use and compiler-level support.", "2.11.0")
trait SeqProxy[+A] extends Seq[A] with SeqProxyLike[A, Seq[A]]
1 change: 1 addition & 0 deletions src/library/scala/collection/SeqProxyLike.scala
Expand Up @@ -23,6 +23,7 @@ import generic._
* @version 2.8
* @since 2.8
*/
@deprecated("Proxying is deprecated due to lack of use and compiler-level support.", "2.11.0")
trait SeqProxyLike[+A, +Repr <: SeqLike[A, Repr] with Seq[A]] extends SeqLike[A, Repr] with IterableProxyLike[A, Repr] {
override def size = self.size
override def toSeq: Seq[A] = self.toSeq
Expand Down
1 change: 1 addition & 0 deletions src/library/scala/collection/SetProxyLike.scala
Expand Up @@ -17,6 +17,7 @@ package collection
* @author Martin Odersky
* @version 2.8
*/
@deprecated("Proxying is deprecated due to lack of use and compiler-level support.", "2.11.0")
trait SetProxyLike[A, +This <: SetLike[A, This] with Set[A]] extends SetLike[A, This] with IterableProxyLike[A, This] {
def empty: This
override def contains(elem: A): Boolean = self.contains(elem)
Expand Down
2 changes: 2 additions & 0 deletions src/library/scala/collection/TraversableLike.scala
Expand Up @@ -623,7 +623,9 @@ trait TraversableLike[+A, +Repr] extends Any
}
}

@deprecatedOverriding("Enforce contract of toTraversable that if it is Traversable it returns itself.", "2.11.0")
def toTraversable: Traversable[A] = thisCollection

def toIterator: Iterator[A] = toStream.iterator
def toStream: Stream[A] = toBuffer.toStream
// Override to provide size hint.
Expand Down
1 change: 1 addition & 0 deletions src/library/scala/collection/TraversableProxyLike.scala
Expand Up @@ -24,6 +24,7 @@ import scala.reflect.ClassTag
* @version 2.8
* @since 2.8
*/
@deprecated("Proxying is deprecated due to lack of use and compiler-level support.", "2.11.0")
trait TraversableProxyLike[+A, +Repr <: TraversableLike[A, Repr] with Traversable[A]] extends TraversableLike[A, Repr] with Proxy {
def self: Repr

Expand Down
Expand Up @@ -26,6 +26,7 @@ import scala.collection._
* @version 2.8
* @since 2.8
*/
@deprecated("Forwarding is inherently unreliable since it is not automated and methods can be forgotten.", "2.11.0")
trait IterableForwarder[+A] extends Iterable[A] with TraversableForwarder[A] {

/** The iterable object to which calls are forwarded */
Expand Down
1 change: 1 addition & 0 deletions src/library/scala/collection/generic/SeqForwarder.scala
Expand Up @@ -25,6 +25,7 @@ import scala.collection.immutable.Range
* @version 2.8
* @since 2.8
*/
@deprecated("Forwarding is inherently unreliable since it is not automated and new methods can be forgotten.", "2.11.0")
trait SeqForwarder[+A] extends Seq[A] with IterableForwarder[A] {

protected override def underlying: Seq[A]
Expand Down
Expand Up @@ -27,6 +27,7 @@ import scala.reflect.ClassTag
* @version 2.8
* @since 2.8
*/
@deprecated("Forwarding is inherently unreliable since it is not automated and new methods can be forgotten.", "2.11.0")
trait TraversableForwarder[+A] extends Traversable[A] {
/** The traversable object to which calls are forwarded. */
protected def underlying: Traversable[A]
Expand Down
1 change: 1 addition & 0 deletions src/library/scala/collection/immutable/HashMap.scala
Expand Up @@ -33,6 +33,7 @@ import parallel.immutable.ParHashMap
* @define willNotTerminateInf
*/
@SerialVersionUID(2L)
@deprecatedInheritance("The implementation details of immutable hash maps make inheriting from them unwise.", "2.11.0")
class HashMap[A, +B] extends AbstractMap[A, B]
with Map[A, B]
with MapLike[A, B, HashMap[A, B]]
Expand Down
1 change: 1 addition & 0 deletions src/library/scala/collection/immutable/HashSet.scala
Expand Up @@ -30,6 +30,7 @@ import scala.collection.parallel.immutable.ParHashSet
* @define coll immutable hash set
*/
@SerialVersionUID(2L)
@deprecatedInheritance("The implementation details of immutable hash sets make inheriting from them unwise.", "2.11.0")
class HashSet[A] extends AbstractSet[A]
with Set[A]
with GenericSetTemplate[A, HashSet]
Expand Down
6 changes: 6 additions & 0 deletions src/library/scala/collection/immutable/IndexedSeq.scala
Expand Up @@ -23,6 +23,12 @@ trait IndexedSeq[+A] extends Seq[A]
with GenericTraversableTemplate[A, IndexedSeq]
with IndexedSeqLike[A, IndexedSeq[A]] {
override def companion: GenericCompanion[IndexedSeq] = IndexedSeq

/** Returns this $coll as an indexed sequence.
*
* A new indexed sequence will not be built; lazy collections will stay lazy.
*/
@deprecatedOverriding("Immutable indexed sequences should do nothing on toIndexedSeq except cast themselves as an indexed sequence.", "2.11.0")
override def toIndexedSeq: IndexedSeq[A] = this
override def seq: IndexedSeq[A] = this
}
Expand Down
1 change: 1 addition & 0 deletions src/library/scala/collection/immutable/ListMap.scala
Expand Up @@ -49,6 +49,7 @@ object ListMap extends ImmutableMapFactory[ListMap] {
* @define willNotTerminateInf
*/
@SerialVersionUID(301002838095710379L)
@deprecatedInheritance("The semantics of immutable collections makes inheriting from ListMap error-prone.", "2.11.0")
class ListMap[A, +B]
extends AbstractMap[A, B]
with Map[A, B]
Expand Down
1 change: 1 addition & 0 deletions src/library/scala/collection/immutable/ListSet.scala
Expand Up @@ -64,6 +64,7 @@ object ListSet extends ImmutableSetFactory[ListSet] {
* @define mayNotTerminateInf
* @define willNotTerminateInf
*/
@deprecatedInheritance("The semantics of immutable collections makes inheriting from ListSet error-prone.", "2.11.0")
class ListSet[A] extends AbstractSet[A]
with Set[A]
with GenericSetTemplate[A, ListSet]
Expand Down
6 changes: 6 additions & 0 deletions src/library/scala/collection/immutable/Map.scala
Expand Up @@ -32,6 +32,12 @@ trait Map[A, +B] extends Iterable[(A, B)]
with MapLike[A, B, Map[A, B]] { self =>

override def empty: Map[A, B] = Map.empty

/** Returns this $coll as an immutable map.
*
* A new map will not be built; lazy collections will stay lazy.
*/
@deprecatedOverriding("Immutable maps should do nothing on toMap except return themselves cast as a map.", "2.11.0")
override def toMap[T, U](implicit ev: (A, B) <:< (T, U)): immutable.Map[T, U] =
self.asInstanceOf[immutable.Map[T, U]]

Expand Down
1 change: 1 addition & 0 deletions src/library/scala/collection/immutable/MapProxy.scala
Expand Up @@ -23,6 +23,7 @@ package immutable
* @version 2.0, 31/12/2006
* @since 2.8
*/
@deprecated("Proxying is deprecated due to lack of use and compiler-level support.", "2.11.0")
trait MapProxy[A, +B] extends Map[A, B] with MapProxyLike[A, B, Map[A, B]] {
override def repr = this
private def newProxy[B1 >: B](newSelf: Map[A, B1]): MapProxy[A, B1] =
Expand Down
1 change: 1 addition & 0 deletions src/library/scala/collection/immutable/PagedSeq.scala
Expand Up @@ -126,6 +126,7 @@ import PagedSeq._
* @define mayNotTerminateInf
* @define willNotTerminateInf
*/
@deprecatedInheritance("The implementation details of paged sequences make inheriting from them unwise.", "2.11.0")
class PagedSeq[T: ClassTag] protected(
more: (Array[T], Int, Int) => Int,
first1: Page[T],
Expand Down
1 change: 1 addition & 0 deletions src/library/scala/collection/immutable/Queue.scala
Expand Up @@ -38,6 +38,7 @@ import scala.annotation.tailrec
*/

@SerialVersionUID(-7622936493364270175L)
@deprecatedInheritance("The implementation details of immutable queues make inheriting from them unwise.", "2.11.0")
class Queue[+A] protected(protected val in: List[A], protected val out: List[A])
extends AbstractSeq[A]
with LinearSeq[A]
Expand Down
1 change: 1 addition & 0 deletions src/library/scala/collection/immutable/Range.scala
Expand Up @@ -42,6 +42,7 @@ import scala.collection.parallel.immutable.ParRange
* and its complexity is O(1).
*/
@SerialVersionUID(7618862778670199309L)
@deprecatedInheritance("The implementation details of Range makes inheriting from it unwise.", "2.11.0")
class Range(val start: Int, val end: Int, val step: Int)
extends scala.collection.AbstractSeq[Int]
with IndexedSeq[Int]
Expand Down
8 changes: 8 additions & 0 deletions src/library/scala/collection/immutable/Set.scala
Expand Up @@ -33,7 +33,15 @@ trait Set[A] extends Iterable[A]
with Parallelizable[A, ParSet[A]]
{
override def companion: GenericCompanion[Set] = Set


/** Returns this $coll as an immutable map.
*
* A new map will not be built; lazy collections will stay lazy.
*/
@deprecatedOverriding("Immutable sets should do nothing on toSet but return themselves cast as a Set.", "2.11.0")
override def toSet[B >: A]: Set[B] = this.asInstanceOf[Set[B]]

override def seq: Set[A] = this
protected override def parCombiner = ParSet.newCombiner[A] // if `immutable.SetLike` gets introduced, please move this there!
}
Expand Down
1 change: 1 addition & 0 deletions src/library/scala/collection/immutable/SetProxy.scala
Expand Up @@ -22,6 +22,7 @@ package immutable
*
* @since 2.8
*/
@deprecated("Proxying is deprecated due to lack of use and compiler-level support.", "2.11.0")
trait SetProxy[A] extends Set[A] with SetProxyLike[A, Set[A]] {
override def repr = this
private def newProxy[B >: A](newSelf: Set[B]): SetProxy[B] =
Expand Down
1 change: 1 addition & 0 deletions src/library/scala/collection/immutable/Stack.scala
Expand Up @@ -46,6 +46,7 @@ object Stack extends SeqFactory[Stack] {
* @define willNotTerminateInf
*/
@SerialVersionUID(1976480595012942526L)
@deprecated("Stack is an inelegant and potentially poorly-performing wrapper around List. Use List instead: stack push x becomes x :: list; stack.pop is list.tail.", "2.11.0")
class Stack[+A] protected (protected val elems: List[A])
extends AbstractSeq[A]
with LinearSeq[A]
Expand Down
1 change: 1 addition & 0 deletions src/library/scala/collection/immutable/TreeMap.scala
Expand Up @@ -44,6 +44,7 @@ object TreeMap extends ImmutableSortedMapFactory[TreeMap] {
* @define mayNotTerminateInf
* @define willNotTerminateInf
*/
@deprecatedInheritance("The implementation details of immutable tree maps make inheriting from them unwise.", "2.11.0")
class TreeMap[A, +B] private (tree: RB.Tree[A, B])(implicit val ordering: Ordering[A])
extends SortedMap[A, B]
with SortedMapLike[A, B, TreeMap[A, B]]
Expand Down
1 change: 1 addition & 0 deletions src/library/scala/collection/immutable/TreeSet.scala
Expand Up @@ -49,6 +49,7 @@ object TreeSet extends ImmutableSortedSetFactory[TreeSet] {
* @define willNotTerminateInf
*/
@SerialVersionUID(-5685982407650748405L)
@deprecatedInheritance("The implementation details of immutable tree sets make inheriting from them unwise.", "2.11.0")
class TreeSet[A] private (tree: RB.Tree[A, Unit])(implicit val ordering: Ordering[A])
extends SortedSet[A] with SortedSetLike[A, TreeSet[A]] with Serializable {

Expand Down
1 change: 1 addition & 0 deletions src/library/scala/collection/immutable/WrappedString.scala
Expand Up @@ -29,6 +29,7 @@ import mutable.{Builder, StringBuilder}
* @define Coll `WrappedString`
* @define coll wrapped string
*/
@deprecatedInheritance("Inherit from StringLike instead of WrappedString.", "2.11.0")
class WrappedString(val self: String) extends AbstractSeq[Char] with IndexedSeq[Char] with StringLike[WrappedString] {

override protected[this] def thisCollection: WrappedString = this
Expand Down
9 changes: 9 additions & 0 deletions src/library/scala/collection/mutable/ArrayBuilder.scala
Expand Up @@ -52,6 +52,7 @@ object ArrayBuilder {
*
* @tparam T type of elements for the array builder, subtype of `AnyRef` with a `ClassTag` context bound.
*/
@deprecatedInheritance("ArrayBuilder.ofRef is an internal implementation not intended for subclassing.", "2.11.0")
class ofRef[T <: AnyRef : ClassTag] extends ArrayBuilder[T] {

private var elems: Array[T] = _
Expand Down Expand Up @@ -116,6 +117,7 @@ object ArrayBuilder {
}

/** A class for array builders for arrays of `byte`s. */
@deprecatedInheritance("ArrayBuilder.ofByte is an internal implementation not intended for subclassing.", "2.11.0")
class ofByte extends ArrayBuilder[Byte] {

private var elems: Array[Byte] = _
Expand Down Expand Up @@ -180,6 +182,7 @@ object ArrayBuilder {
}

/** A class for array builders for arrays of `short`s. */
@deprecatedInheritance("ArrayBuilder.ofShort is an internal implementation not intended for subclassing.", "2.11.0")
class ofShort extends ArrayBuilder[Short] {

private var elems: Array[Short] = _
Expand Down Expand Up @@ -244,6 +247,7 @@ object ArrayBuilder {
}

/** A class for array builders for arrays of `char`s. */
@deprecatedInheritance("ArrayBuilder.ofChar is an internal implementation not intended for subclassing.", "2.11.0")
class ofChar extends ArrayBuilder[Char] {

private var elems: Array[Char] = _
Expand Down Expand Up @@ -308,6 +312,7 @@ object ArrayBuilder {
}

/** A class for array builders for arrays of `int`s. */
@deprecatedInheritance("ArrayBuilder.ofInt is an internal implementation not intended for subclassing.", "2.11.0")
class ofInt extends ArrayBuilder[Int] {

private var elems: Array[Int] = _
Expand Down Expand Up @@ -372,6 +377,7 @@ object ArrayBuilder {
}

/** A class for array builders for arrays of `long`s. */
@deprecatedInheritance("ArrayBuilder.ofLong is an internal implementation not intended for subclassing.", "2.11.0")
class ofLong extends ArrayBuilder[Long] {

private var elems: Array[Long] = _
Expand Down Expand Up @@ -436,6 +442,7 @@ object ArrayBuilder {
}

/** A class for array builders for arrays of `float`s. */
@deprecatedInheritance("ArrayBuilder.ofFloat is an internal implementation not intended for subclassing.", "2.11.0")
class ofFloat extends ArrayBuilder[Float] {

private var elems: Array[Float] = _
Expand Down Expand Up @@ -500,6 +507,7 @@ object ArrayBuilder {
}

/** A class for array builders for arrays of `double`s. */
@deprecatedInheritance("ArrayBuilder.ofDouble is an internal implementation not intended for subclassing.", "2.11.0")
class ofDouble extends ArrayBuilder[Double] {

private var elems: Array[Double] = _
Expand Down Expand Up @@ -628,6 +636,7 @@ object ArrayBuilder {
}

/** A class for array builders for arrays of `Unit` type. */
@deprecatedInheritance("ArrayBuilder.ofUnit is an internal implementation not intended for subclassing.", "2.11.0")
class ofUnit extends ArrayBuilder[Unit] {

private var elems: Array[Unit] = _
Expand Down
5 changes: 3 additions & 2 deletions src/library/scala/collection/mutable/ArrayLike.scala
Expand Up @@ -10,8 +10,9 @@ package scala
package collection
package mutable

/** A common supertrait of `ArrayOps` and `WrappedArray` that factors out most
* operations on arrays and wrapped arrays.
/** A common supertrait of `ArrayOps` and `WrappedArray` that factors out the
* `deep` method for arrays and wrapped arrays and serves as a marker trait
* for array wrappers.
*
* @tparam A type of the elements contained in the array like object.
* @tparam Repr the type of the actual collection containing the elements.
Expand Down
1 change: 1 addition & 0 deletions src/library/scala/collection/mutable/ArrayOps.scala
Expand Up @@ -33,6 +33,7 @@ import parallel.mutable.ParArray
* @define mayNotTerminateInf
* @define willNotTerminateInf
*/
@deprecatedInheritance("ArrayOps will be sealed to facilitate greater flexibility with array/collections integration in future releases.", "2.11.0")
trait ArrayOps[T] extends Any with ArrayLike[T, Array[T]] with CustomParallelizable[T, ParArray[T]] {

private def elementClass: Class[_] =
Expand Down

0 comments on commit 3cc99d7

Please sign in to comment.