summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2009-11-20 13:57:22 +0000
committerMartin Odersky <odersky@gmail.com>2009-11-20 13:57:22 +0000
commitc317201d1f6ff6f9f8548ad805cf6e8ff933e1ca (patch)
tree41de85e1efedecfa746992d6303299fd950f2007
parent3cf0e5a010ca8d3bd1828bbc096f587a01ba604f (diff)
downloadscala-c317201d1f6ff6f9f8548ad805cf6e8ff933e1ca.tar.gz
scala-c317201d1f6ff6f9f8548ad805cf6e8ff933e1ca.tar.bz2
scala-c317201d1f6ff6f9f8548ad805cf6e8ff933e1ca.zip
Simplifiations in collections libraries, enable...
Simplifiations in collections libraries, enabled by introduction of Self type in TraversableLike.
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala2
-rw-r--r--src/library/scala/collection/TraversableLike.scala3
-rw-r--r--src/library/scala/collection/immutable/Set.scala6
-rw-r--r--src/library/scala/collection/mutable/BufferLike.scala5
-rw-r--r--src/library/scala/collection/mutable/BufferProxy.scala6
-rw-r--r--src/library/scala/collection/mutable/History.scala12
-rw-r--r--src/library/scala/collection/mutable/LinkedHashMap.scala2
-rw-r--r--src/library/scala/collection/mutable/ObservableBuffer.scala7
-rw-r--r--src/library/scala/collection/mutable/ObservableMap.scala8
-rw-r--r--src/library/scala/collection/mutable/ObservableSet.scala8
-rw-r--r--src/library/scala/collection/mutable/Publisher.scala38
-rw-r--r--src/library/scala/collection/mutable/RevertibleHistory.scala2
-rw-r--r--src/library/scala/collection/mutable/Subscriber.scala7
-rw-r--r--src/library/scala/collection/mutable/SynchronizedBuffer.scala10
-rw-r--r--src/library/scala/collection/mutable/SynchronizedMap.scala4
-rw-r--r--test/files/jvm/serialization.scala2
-rw-r--r--test/files/pos/collections.scala2
17 files changed, 66 insertions, 58 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index f7069b25ad..f4216f7958 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -1275,7 +1275,7 @@ trait Namers { self: Analyzer =>
context.error(sym.pos, "`lazy' definitions may not be initialized early")
if (sym.info.typeSymbol == FunctionClass(0) &&
sym.isValueParameter && sym.owner.isClass && sym.owner.hasFlag(CASE))
- context.error(sym.pos, "pass-by-name arguments not allowed for case class parameters");
+ context.error(sym.pos, "pass-by-name arguments not allowed for case class parameters")
if (sym hasFlag DEFERRED) { // virtual classes count, too
if (sym.hasAnnotation(definitions.NativeAttr))
sym.resetFlag(DEFERRED)
diff --git a/src/library/scala/collection/TraversableLike.scala b/src/library/scala/collection/TraversableLike.scala
index a0e330831f..b06eecc104 100644
--- a/src/library/scala/collection/TraversableLike.scala
+++ b/src/library/scala/collection/TraversableLike.scala
@@ -72,6 +72,9 @@ self =>
protected[this] def thisCollection: Traversable[A] = this.asInstanceOf[Traversable[A]]
protected[this] def toCollection(repr: Repr): Traversable[A] = repr.asInstanceOf[Traversable[A]]
+ /** The type implementing this traversable */
+ protected type Self = Repr
+
/** Create a new builder for this collection type.
*/
protected[this] def newBuilder: Builder[A, Repr]
diff --git a/src/library/scala/collection/immutable/Set.scala b/src/library/scala/collection/immutable/Set.scala
index cc935afe93..80f98aa679 100644
--- a/src/library/scala/collection/immutable/Set.scala
+++ b/src/library/scala/collection/immutable/Set.scala
@@ -21,10 +21,10 @@ import generic._
* <pre>
* <b>def</b> contains(elem: A): Boolean
* <b>def</b> iterator: Iterator[A]
- * <b>def</b> + (elem: A): This
- * <b>def</b> - (elem: A): This</pre>
+ * <b>def</b> + (elem: A): Self
+ * <b>def</b> - (elem: A): Self</pre>
* <p>
- * where <code>This</code> is the type of the set.
+ * where <code>Self</code> is the type of the set.
* </p>
*
* @author Matthias Zenger
diff --git a/src/library/scala/collection/mutable/BufferLike.scala b/src/library/scala/collection/mutable/BufferLike.scala
index 20c2d67658..e941a4e438 100644
--- a/src/library/scala/collection/mutable/BufferLike.scala
+++ b/src/library/scala/collection/mutable/BufferLike.scala
@@ -71,12 +71,11 @@ trait BufferLike[A, +This <: BufferLike[A, This] with Buffer[A]]
def clear()
// Abstract methods new in this class
-
/** Prepend a single element to this buffer and return
* the identity of the buffer.
* @param elem the element to prepend.
*/
- def +=:(elem: A): This
+ def +=:(elem: A): this.type
@deprecated("use `+=:' instead")
final def +:(elem: A): This = +=:(elem)
@@ -126,7 +125,7 @@ trait BufferLike[A, +This <: BufferLike[A, This] with Buffer[A]]
*
* @param iter the iterable object.
*/
- def ++=:(iter: Traversable[A]): This = { insertAll(0, iter); this }
+ def ++=:(iter: Traversable[A]): this.type = { insertAll(0, iter); this }
@deprecated("use ++=: instead")
final def ++:(iter: Traversable[A]): This = ++=:(iter)
diff --git a/src/library/scala/collection/mutable/BufferProxy.scala b/src/library/scala/collection/mutable/BufferProxy.scala
index a31beda57b..4dd2280e02 100644
--- a/src/library/scala/collection/mutable/BufferProxy.scala
+++ b/src/library/scala/collection/mutable/BufferProxy.scala
@@ -88,10 +88,10 @@ trait BufferProxy[A] extends Buffer[A] with Proxy {
*
* @param elem the element to append.
*/
- def +=:(elem: A): Buffer[A] = self.+=:(elem)
+ def +=:(elem: A): this.type = { self.+=:(elem); this }
- override def ++=:(iter: scala.collection.Traversable[A]): Buffer[A] = self.++=:(iter)
- override def ++=:(iter: scala.collection.Iterator[A]): Buffer[A] = self.++=:(iter)
+ override def ++=:(iter: scala.collection.Traversable[A]): this.type = { self.++=:(iter); this }
+ override def ++=:(iter: scala.collection.Iterator[A]): this.type = { self.++=:(iter); this }
/** Prepend an element to this list.
*
diff --git a/src/library/scala/collection/mutable/History.scala b/src/library/scala/collection/mutable/History.scala
index dcc6539630..1e65814edb 100644
--- a/src/library/scala/collection/mutable/History.scala
+++ b/src/library/scala/collection/mutable/History.scala
@@ -1,6 +1,6 @@
/* __ *\
** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL **
+** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/tPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
@@ -24,16 +24,16 @@ package mutable
*/
@serializable
@SerialVersionUID(5219213543849892588L)
-class History[A, B] extends AnyRef with Subscriber[A, B] with Iterable[(B, A)]
+class History[Evt, Pub] extends Subscriber[Evt, Pub] with Iterable[(Pub, Evt)]
{
- protected val log: Queue[(B, A)] = new Queue[(B, A)]
+ protected val log: Queue[(Pub, Evt)] = new Queue
val maxHistory: Int = 1000
/**
* @param pub ...
* @param event ...
*/
- def notify(pub: B, event: A) {
+ def notify(pub: Pub, event: Evt) {
if (log.length >= maxHistory)
log.dequeue
@@ -41,8 +41,8 @@ class History[A, B] extends AnyRef with Subscriber[A, B] with Iterable[(B, A)]
}
override def size: Int = log.length
- def iterator: Iterator[(B, A)] = log.iterator
- def events: Iterator[A] = log.iterator.map { case (_, e) => e }
+ def iterator: Iterator[(Pub, Evt)] = log.iterator
+ def events: Iterator[Evt] = log.iterator map (_._2)
def clear() { log.clear }
diff --git a/src/library/scala/collection/mutable/LinkedHashMap.scala b/src/library/scala/collection/mutable/LinkedHashMap.scala
index b0cad79ef4..308db1a4d4 100644
--- a/src/library/scala/collection/mutable/LinkedHashMap.scala
+++ b/src/library/scala/collection/mutable/LinkedHashMap.scala
@@ -15,8 +15,8 @@ package mutable
import generic._
/** This class implements mutable maps using a hashtable.
+ * The iterator and all traversal methods of this class visit elements in the order they were inserted.
*
- * @author Matthias Zenger
* @author Martin Odersky
* @version 2.8
* @since 2.7
diff --git a/src/library/scala/collection/mutable/ObservableBuffer.scala b/src/library/scala/collection/mutable/ObservableBuffer.scala
index e1cd8ace4d..b90f1a805c 100644
--- a/src/library/scala/collection/mutable/ObservableBuffer.scala
+++ b/src/library/scala/collection/mutable/ObservableBuffer.scala
@@ -23,10 +23,9 @@ import script._
* @version 1.0, 08/07/2003
* @since 1
*/
-trait ObservableBuffer[A, This <: ObservableBuffer[A, This]]
- extends Buffer[A]
- with Publisher[Message[A] with Undoable, This]
-{ self: This =>
+trait ObservableBuffer[A] extends Buffer[A] with Publisher[Message[A] with Undoable]
+{
+ type Pub <: ObservableBuffer[A]
abstract override def +=(element: A): this.type = {
super.+=(element)
diff --git a/src/library/scala/collection/mutable/ObservableMap.scala b/src/library/scala/collection/mutable/ObservableMap.scala
index 4de49c34b2..64b61dfe95 100644
--- a/src/library/scala/collection/mutable/ObservableMap.scala
+++ b/src/library/scala/collection/mutable/ObservableMap.scala
@@ -25,10 +25,10 @@ import script._
* @version 2.0, 31/12/2006
* @since 1
*/
-trait ObservableMap[A, B, This <: ObservableMap[A, B, This]]
- extends Map[A, B]
- with Publisher[Message[(A, B)] with Undoable, This]
-{ self: This =>
+trait ObservableMap[A, B] extends Map[A, B] with Publisher[Message[(A, B)] with Undoable]
+{
+
+ type Pub <: ObservableMap[A, B]
abstract override def += (kv: (A, B)): this.type = {
val (key, value) = kv
diff --git a/src/library/scala/collection/mutable/ObservableSet.scala b/src/library/scala/collection/mutable/ObservableSet.scala
index bb61e6c363..899a9a16aa 100644
--- a/src/library/scala/collection/mutable/ObservableSet.scala
+++ b/src/library/scala/collection/mutable/ObservableSet.scala
@@ -23,10 +23,10 @@ import script._
* @version 1.0, 08/07/2003
* @since 1
*/
-trait ObservableSet[A, This <: ObservableSet[A, This]]
- extends Set[A]
- with Publisher[Message[A] with Undoable, This]
-{ self: This =>
+trait ObservableSet[A] extends Set[A] with Publisher[Message[A] with Undoable]
+{
+
+ type Pub <: ObservableSet[A]
abstract override def +=(elem: A): this.type = {
if (!contains(elem)) {
diff --git a/src/library/scala/collection/mutable/Publisher.scala b/src/library/scala/collection/mutable/Publisher.scala
index 6d1eae7b78..29e7e9b371 100644
--- a/src/library/scala/collection/mutable/Publisher.scala
+++ b/src/library/scala/collection/mutable/Publisher.scala
@@ -18,32 +18,38 @@ package mutable
* a filter which can be used to constrain the number of events sent to the
* subscriber. Subscribers may suspend their subscription, or reactivate a
* suspended subscription. Class <code>Publisher</code> is typically used
- * as a mixin. The type variable <code>This</code> models self types.
+ * as a mixin. The abstract type <code>Pub</code> models the type of the publisher itself.
*
* @author Matthias Zenger
- * @version 1.0, 08/07/2003
+ * @author Martin Odersky
+ * @version 2.8
* @since 1
*/
-trait Publisher[A, This <: Publisher[A, This]] {
- self: This =>
+trait Publisher[Evt] {
- type SubThis = Subscriber[A, This]
- type Filter = A => Boolean
+ type Pub <: Publisher[Evt]
+ type Sub = Subscriber[Evt, Pub]
+ type Filter = Evt => Boolean
- private val filters = new HashMap[SubThis, Set[Filter]] with MultiMap[SubThis, Filter]
- private val suspended = new HashSet[SubThis]
+ /** The publisher itself of type `Pub'. Implemented by a cast from `this' here.
+ * Needs to be overridden if the actual publisher is different from `this'.
+ */
+ protected val self: Pub = this.asInstanceOf[Pub]
+
+ private val filters = new HashMap[Sub, Set[Filter]] with MultiMap[Sub, Filter]
+ private val suspended = new HashSet[Sub]
- def subscribe(sub: SubThis) { subscribe(sub, event => true) }
- def subscribe(sub: SubThis, filter: Filter) { filters(sub) += filter }
- def suspendSubscription(sub: SubThis) { suspended += sub }
- def activateSubscription(sub: SubThis) { suspended -= sub }
- def removeSubscription(sub: SubThis) { filters -= sub }
+ def subscribe(sub: Sub) { subscribe(sub, event => true) }
+ def subscribe(sub: Sub, filter: Filter) { filters(sub) += filter }
+ def suspendSubscription(sub: Sub) { suspended += sub }
+ def activateSubscription(sub: Sub) { suspended -= sub }
+ def removeSubscription(sub: Sub) { filters -= sub }
def removeSubscriptions() { filters.clear }
- protected def publish(event: A) {
+ protected def publish(event: Evt) {
filters.keysIterator.foreach(sub =>
if (filters.entryExists(sub, p => p(event)))
- sub.notify(this, event)
+ sub.notify(self, event)
)
}
@@ -52,7 +58,7 @@ trait Publisher[A, This <: Publisher[A, This]] {
* @return true, iff both publishers contain the same sequence of elements.
*/
override def equals(obj: Any): Boolean = obj match {
- case that: Publisher[_, _] =>
+ case that: Publisher[_] =>
(this.filters equals that.filters) &&
(this.suspended equals that.suspended)
case _ =>
diff --git a/src/library/scala/collection/mutable/RevertibleHistory.scala b/src/library/scala/collection/mutable/RevertibleHistory.scala
index 08b6b56cac..8706cab585 100644
--- a/src/library/scala/collection/mutable/RevertibleHistory.scala
+++ b/src/library/scala/collection/mutable/RevertibleHistory.scala
@@ -23,7 +23,7 @@ package mutable
* @since 2.8
*/
@serializable
-class RevertibleHistory[A <: Undoable, B] extends History[A, B] with Undoable {
+class RevertibleHistory[Evt <: Undoable, Pub] extends History[Evt, Pub] with Undoable {
/** Rollback the full history.
*/
diff --git a/src/library/scala/collection/mutable/Subscriber.scala b/src/library/scala/collection/mutable/Subscriber.scala
index abf92f0840..431c157449 100644
--- a/src/library/scala/collection/mutable/Subscriber.scala
+++ b/src/library/scala/collection/mutable/Subscriber.scala
@@ -19,9 +19,10 @@ package mutable
* target="contentFrame"><code>Publisher</code></a>.
*
* @author Matthias Zenger
- * @version 1.0, 08/07/2003
+ * @author Martin Odersky
+ * @version 2.8
* @since 1
*/
-trait Subscriber[-A, -B] {
- def notify(pub: B, event: A): Unit
+trait Subscriber[-Evt, -Pub] {
+ def notify(pub: Pub, event: Evt): Unit
}
diff --git a/src/library/scala/collection/mutable/SynchronizedBuffer.scala b/src/library/scala/collection/mutable/SynchronizedBuffer.scala
index 590757be61..269b359e28 100644
--- a/src/library/scala/collection/mutable/SynchronizedBuffer.scala
+++ b/src/library/scala/collection/mutable/SynchronizedBuffer.scala
@@ -42,7 +42,7 @@ trait SynchronizedBuffer[A] extends Buffer[A] {
*
* @param elem the element to append.
*/
- override def +(elem: A): Buffer[A] = synchronized {
+ override def +(elem: A): Self = synchronized {
super.+(elem)
}
@@ -60,7 +60,7 @@ trait SynchronizedBuffer[A] extends Buffer[A] {
*
* @param iter the iterable object.
*/
- override def ++(iter: Traversable[A]): Buffer[A] = synchronized {
+ override def ++(iter: Traversable[A]): Self = synchronized {
super.++(iter)
}
@@ -95,7 +95,7 @@ trait SynchronizedBuffer[A] extends Buffer[A] {
*
* @param elem the element to append.
*/
- abstract override def +=:(elem: A): Buffer[A] = synchronized {
+ abstract override def +=:(elem: A): this.type = synchronized[this.type] {
super.+=:(elem)
}
@@ -105,7 +105,7 @@ trait SynchronizedBuffer[A] extends Buffer[A] {
*
* @param iter the iterable object.
*/
- override def ++=:(iter: Traversable[A]): Buffer[A] = synchronized {
+ override def ++=:(iter: Traversable[A]): this.type = synchronized[this.type] {
super.++=:(iter)
}
@@ -181,7 +181,7 @@ trait SynchronizedBuffer[A] extends Buffer[A] {
*
* @return an <code>ArrayBuffer</code> with the same elements.
*/
- override def clone(): Buffer[A] = synchronized {
+ override def clone(): Self = synchronized {
super.clone()
}
diff --git a/src/library/scala/collection/mutable/SynchronizedMap.scala b/src/library/scala/collection/mutable/SynchronizedMap.scala
index 650c939936..a2ad697985 100644
--- a/src/library/scala/collection/mutable/SynchronizedMap.scala
+++ b/src/library/scala/collection/mutable/SynchronizedMap.scala
@@ -38,7 +38,7 @@ trait SynchronizedMap[A, B] extends Map[A, B] {
override def valuesIterable: scala.collection.Iterable[B] = synchronized { super.valuesIterable }
@deprecated("Use `valuesIterator' instead") override def values: Iterator[B] = synchronized { super.valuesIterator }
override def valuesIterator: Iterator[B] = synchronized { super.valuesIterator }
- override def clone() = synchronized { super.clone() }
+ override def clone(): Self = synchronized { super.clone() }
override def foreach[U](f: ((A, B)) => U) = synchronized { super.foreach(f) }
override def apply(key: A): B = synchronized { super.apply(key) }
override def keySet: scala.collection.Set[A] = synchronized { super.keySet }
@@ -50,7 +50,7 @@ trait SynchronizedMap[A, B] extends Map[A, B] {
@deprecated("See Map.+ for explanation") override def +(kv: (A, B)): this.type = synchronized[this.type] { super.+(kv) }
// can't override -, -- same type!
- // @deprecated override def -(key: A): This = synchronized { super.-(key) }
+ // @deprecated override def -(key: A): Self = synchronized { super.-(key) }
// !!! todo: also add all other methods
}
diff --git a/test/files/jvm/serialization.scala b/test/files/jvm/serialization.scala
index 81d21e6dc5..f6ab36e229 100644
--- a/test/files/jvm/serialization.scala
+++ b/test/files/jvm/serialization.scala
@@ -220,7 +220,7 @@ object Test3_mutable {
x3 ++= Test2_immutable.x1.map(p => p._1)
@serializable
- class Feed extends Publisher[String, Feed]
+ class Feed extends Publisher[String]
val x8 = new History[String, Feed]
diff --git a/test/files/pos/collections.scala b/test/files/pos/collections.scala
index 61a25528c7..23b23d016e 100644
--- a/test/files/pos/collections.scala
+++ b/test/files/pos/collections.scala
@@ -2,7 +2,7 @@ package mixins;
import scala.collection.mutable._;
-class Collections extends HashSet[Int] with ObservableSet[Int,Collections] {
+class Collections extends HashSet[Int] with ObservableSet[Int] {
override def +=(elem: Int): this.type = super.+=(elem);
override def -=(elem: Int): this.type = super.-=(elem);
override def clear: Unit = super.clear;