summaryrefslogtreecommitdiff
path: root/src/library
diff options
context:
space:
mode:
authorAntonio Cunei <antonio.cunei@epfl.ch>2010-01-15 17:18:18 +0000
committerAntonio Cunei <antonio.cunei@epfl.ch>2010-01-15 17:18:18 +0000
commit1ee78f5a8d1ac4beb3dff19f8aa147feea508e33 (patch)
tree977e78a276ba4939cc40d55dd77149ae3e0e10e9 /src/library
parent914d6ff44e34a1c15a920d6c055df062cc31b4f3 (diff)
downloadscala-1ee78f5a8d1ac4beb3dff19f8aa147feea508e33.tar.gz
scala-1ee78f5a8d1ac4beb3dff19f8aa147feea508e33.tar.bz2
scala-1ee78f5a8d1ac4beb3dff19f8aa147feea508e33.zip
Merged revisions 20429,20437-20438,20444-20447,...
Merged revisions 20429,20437-20438,20444-20447,20449-20451,20453,20456-20457,20459,20463- 20466,20468-20469,20476-20478,20480-20482,20484,20486-20491,20495-20496, 20500-20502,20504,20515,20519,20522-20525 via svnmerge from https://lampsvn.epfl.ch/svn-repos/scala/scala/trunk ........ r20429 | milessabin | 2010-01-10 13:08:40 +0100 (Sun, 10 Jan 2010) | 1 line Weaken the test for co-definition to equality of paths (equality of files fails where implementing types differ). Review by odersky. ........ r20437 | extempore | 2010-01-11 05:58:17 +0100 (Mon, 11 Jan 2010) | 3 lines Fix for an unfortunate bug introduced in r19020 which was causing a great many unnecessary and unreachable MatchErrors to appear in generated bytecode. ........ r20438 | rytz | 2010-01-11 09:55:42 +0100 (Mon, 11 Jan 2010) | 1 line speed up ClassPath.findClass. review by community ........ r20444 | prokopec | 2010-01-11 16:44:22 +0100 (Mon, 11 Jan 2010) | 2 lines Red black tree patch and test. no review ........ r20445 | odersky | 2010-01-11 16:48:20 +0100 (Mon, 11 Jan 2010) | 1 line Revised List#mapConserve so that it tests wrt eq not ==. ........ r20446 | odersky | 2010-01-11 16:48:58 +0100 (Mon, 11 Jan 2010) | 1 line Removed extraneous clause is isStrictlyMoreSpecific ........ r20447 | odersky | 2010-01-11 16:49:51 +0100 (Mon, 11 Jan 2010) | 1 line Avoided a crash scenario in the presentation compiler. ........ r20449 | prokopec | 2010-01-11 17:09:36 +0100 (Mon, 11 Jan 2010) | 2 lines Fixed #2810. no review ........ r20450 | extempore | 2010-01-11 17:26:44 +0100 (Mon, 11 Jan 2010) | 3 lines Fix for #2883, a regression introduced in r18789. It was only a regression because the pattern matcher has extractor bugs which don't manifest for case classes. Underlying bug remains. No review. ........ r20451 | extempore | 2010-01-11 17:31:44 +0100 (Mon, 11 Jan 2010) | 1 line Commented out some (debugging?) code which was breaking the build. ........ r20453 | extempore | 2010-01-11 18:16:56 +0100 (Mon, 11 Jan 2010) | 1 line Fix and test case for #2364, which regressed with the fix to #2721. ........ r20456 | milessabin | 2010-01-11 18:44:32 +0100 (Mon, 11 Jan 2010) | 1 line Reverting stray commit to Eclipse metadata. ........ r20457 | extempore | 2010-01-11 18:57:42 +0100 (Mon, 11 Jan 2010) | 2 lines Moved the test for #2364 to pending because it apparently uses some nonstandard classes. ........ r20459 | extempore | 2010-01-12 00:29:25 +0100 (Tue, 12 Jan 2010) | 8 lines A few repl features. Added the following commands: :history <N> shows N lines of history :h? <str> greps the history for str Altered tab-completion to be less verbose on the first tab, but notice when tab has been hit twice without any other input, and then be more verbose. And prettified the repl help text. ........ r20463 | plocinic | 2010-01-12 12:24:14 +0100 (Tue, 12 Jan 2010) | 1 line Compare typeParams correctly for symbols so that the build manager no longer reports false changes, cloneInfo instead instead of symbols. No review. ........ r20464 | extempore | 2010-01-12 14:44:43 +0100 (Tue, 12 Jan 2010) | 1 line Added toMap to TraversableLike. ........ r20465 | extempore | 2010-01-12 15:11:02 +0100 (Tue, 12 Jan 2010) | 2 lines A fix for at least one manifestation of #2865. Infinite collections and "size" don't mix! ........ r20466 | cunei | 2010-01-12 16:11:07 +0100 (Tue, 12 Jan 2010) | 3 lines Deprecated "=>?". Closes #2860 (see #2819). ........ r20468 | dragos | 2010-01-12 17:55:26 +0100 (Tue, 12 Jan 2010) | 5 lines Updated attempt at removing @inline warnings: - fixed a bug in closure elimination causing VerifyErrors - fixed a broken assert in GenICode that fired when -Ydebug was used - added final modifiers ........ r20469 | odersky | 2010-01-12 18:17:50 +0100 (Tue, 12 Jan 2010) | 1 line Closes #2867. review by extempore. ........ r20476 | plocinic | 2010-01-13 12:05:24 +0100 (Wed, 13 Jan 2010) | 1 line When comparing type aliases use info instead of tpe so that the changes are correctly detected. Fixes #2650. No review. ........ r20477 | extempore | 2010-01-13 14:08:53 +0100 (Wed, 13 Jan 2010) | 2 lines Overrode slice in the StringLike derivatives to use substring. Closes #2895. Review by community. ........ r20478 | odersky | 2010-01-13 14:37:30 +0100 (Wed, 13 Jan 2010) | 1 line more statistics hooks. no review necessary. ........ r20480 | extempore | 2010-01-13 15:38:37 +0100 (Wed, 13 Jan 2010) | 3 lines A variety of bugfixes discovered by findbugs. Most of them are examples of equality comparisons which are guaranteed to return false because someone is not comparing what they think they're comparing. ........ r20481 | moors | 2010-01-13 16:44:11 +0100 (Wed, 13 Jan 2010) | 2 lines closes #2421: more complete fix, now also check validity of inferred type arguments for expressions inferred for implicit values review by odersky ........ r20482 | extempore | 2010-01-13 17:02:41 +0100 (Wed, 13 Jan 2010) | 1 line Fix for #2817. Review by mharrah. ........ r20484 | odersky | 2010-01-13 17:27:40 +0100 (Wed, 13 Jan 2010) | 1 line Fixes #2755, but leaving open to analyze issue raised by Paul. review by extempore. ........ r20486 | odersky | 2010-01-13 17:36:06 +0100 (Wed, 13 Jan 2010) | 1 line Closes #2866, #2870. Attempt to fix #2733 by having only non-local members be visible for imports. However, this causes the interpreter to fail. review by extempore. ........ r20487 | odersky | 2010-01-13 17:36:29 +0100 (Wed, 13 Jan 2010) | 1 line new tests. no review. ........ r20488 | dubochet | 2010-01-13 18:00:14 +0100 (Wed, 13 Jan 2010) | 1 line [scaladoc] Use cases are printed. Reduced memory footprint of Scaladoc model. Review by community. ........ r20489 | moors | 2010-01-13 18:27:01 +0100 (Wed, 13 Jan 2010) | 1 line better fix for see #2421 after feedback from Martin ........ r20490 | extempore | 2010-01-13 23:50:40 +0100 (Wed, 13 Jan 2010) | 2 lines Reverts r20311 since I'm not seeing what's going on in #2876 and the optimization can wait. ........ r20491 | prokopec | 2010-01-14 00:42:33 +0100 (Thu, 14 Jan 2010) | 1 line Added ConcurrentMap and Properties conversion classes and test. ........ r20495 | extempore | 2010-01-14 02:22:05 +0100 (Thu, 14 Jan 2010) | 2 lines Finished up fixing #2773. Interpreter tries not to accidentally import synthetic locals from previous scopes. ........ r20496 | rytz | 2010-01-14 09:43:51 +0100 (Thu, 14 Jan 2010) | 1 line fix for .net compiler (flatten is skipped). no review (already done by dragos). ........ r20500 | dubochet | 2010-01-14 14:22:03 +0100 (Thu, 14 Jan 2010) | 1 line [scaladoc] Use cases are marked as such in the documentation (using some changes in r20488). Review by odersky. ........ r20501 | milessabin | 2010-01-14 17:10:18 +0100 (Thu, 14 Jan 2010) | 1 line Fixed #2889. No review necessary. ........ r20502 | plocinic | 2010-01-14 17:29:39 +0100 (Thu, 14 Jan 2010) | 1 line Closes #2649. No review. ........ r20504 | prokopec | 2010-01-14 18:02:45 +0100 (Thu, 14 Jan 2010) | 4 lines ConcurrentMap trait added to collection.mutable. JavaConversions now include conversions between Java ConcurrentMap objects and Scala ConcurrentMap objects. review by odersky ........ r20515 | phaller | 2010-01-15 00:55:41 +0100 (Fri, 15 Jan 2010) | 1 line Some optimizations to actor message queues and event handling. ........ r20519 | extempore | 2010-01-15 03:12:10 +0100 (Fri, 15 Jan 2010) | 1 line Fix and test for #2354. Review by community. ........ r20522 | milessabin | 2010-01-15 15:12:20 +0100 (Fri, 15 Jan 2010) | 1 line Fixes for various Scaladoc-related positions regressions with tests. Review by dubochet. ........ r20523 | dubochet | 2010-01-15 15:41:19 +0100 (Fri, 15 Jan 2010) | 1 line Fixed issue when searching for companion of class using "linkedSym" when value of same name is overloaded (for example companion of the Value class in an Enumeration). No review, already checked by odersky. ........ r20524 | dubochet | 2010-01-15 15:43:34 +0100 (Fri, 15 Jan 2010) | 1 line [scaladoc] Companion classes are printed. Original code contributed by Pedro Furlanetto. No review, checked by dubochet. ........ r20525 | cunei | 2010-01-15 17:58:28 +0100 (Fri, 15 Jan 2010) | 2 lines Reverted over-zealous replacement of 'PartialFunction' with '=>?'. ........
Diffstat (limited to 'src/library')
-rw-r--r--src/library/scala/Option.scala2
-rw-r--r--src/library/scala/PartialFunction.scala8
-rw-r--r--src/library/scala/Predef.scala4
-rw-r--r--src/library/scala/collection/IndexedSeqViewLike.scala76
-rw-r--r--src/library/scala/collection/IterableViewLike.scala28
-rw-r--r--src/library/scala/collection/Iterator.scala7
-rw-r--r--src/library/scala/collection/JavaConversions.scala164
-rw-r--r--src/library/scala/collection/SeqViewLike.scala26
-rw-r--r--src/library/scala/collection/TraversableLike.scala24
-rw-r--r--src/library/scala/collection/TraversableProxyLike.scala2
-rw-r--r--src/library/scala/collection/TraversableViewLike.scala23
-rw-r--r--src/library/scala/collection/immutable/List.scala8
-rw-r--r--src/library/scala/collection/immutable/RedBlack.scala77
-rw-r--r--src/library/scala/collection/immutable/StringOps.scala5
-rw-r--r--src/library/scala/collection/immutable/WrappedString.scala3
-rw-r--r--src/library/scala/collection/interfaces/TraversableMethods.scala2
-rw-r--r--src/library/scala/collection/mutable/ConcurrentMap.scala79
-rw-r--r--src/library/scala/collection/mutable/FlatHashTable.scala2
-rw-r--r--src/library/scala/collection/mutable/IndexedSeqView.scala5
-rw-r--r--src/library/scala/collection/mutable/PriorityQueue.scala2
-rw-r--r--src/library/scala/collection/views/Transformed.scala128
-rw-r--r--src/library/scala/concurrent/MailBox.scala6
-rw-r--r--src/library/scala/io/Source.scala2
-rw-r--r--src/library/scala/math/BigDecimal.scala2
-rw-r--r--src/library/scala/package.scala2
-rw-r--r--src/library/scala/runtime/ScalaRunTime.scala4
-rw-r--r--src/library/scala/util/control/Exception.scala14
-rw-r--r--src/library/scala/util/parsing/combinator/Parsers.scala14
-rw-r--r--src/library/scala/xml/Text.scala30
-rw-r--r--src/library/scala/xml/Utility.scala7
-rw-r--r--src/library/scala/xml/parsing/FactoryAdapter.scala4
-rw-r--r--src/library/scala/xml/parsing/MarkupParser.scala27
-rw-r--r--src/library/scala/xml/parsing/MarkupParserCommon.scala48
33 files changed, 580 insertions, 255 deletions
diff --git a/src/library/scala/Option.scala b/src/library/scala/Option.scala
index 6cb0fec929..8511fa78a5 100644
--- a/src/library/scala/Option.scala
+++ b/src/library/scala/Option.scala
@@ -110,7 +110,7 @@ sealed abstract class Option[+A] extends Product {
*
* @param pf the partial function.
*/
- def partialMap[B](pf: A =>? B): Option[B] =
+ def partialMap[B](pf: PartialFunction[A, B]): Option[B] =
if (!isEmpty && pf.isDefinedAt(this.get)) Some(pf(this.get)) else None
/** If the option is nonempty return it,
diff --git a/src/library/scala/PartialFunction.scala b/src/library/scala/PartialFunction.scala
index f62fa68565..f450596e57 100644
--- a/src/library/scala/PartialFunction.scala
+++ b/src/library/scala/PartialFunction.scala
@@ -38,7 +38,7 @@ trait PartialFunction[-A, +B] extends (A => B) {
* of this partial function and `that`. The resulting partial function
* takes `x` to `this(x)` where `this` is defined, and to `that(x)` where it is not.
*/
- def orElse[A1 <: A, B1 >: B](that: A1 =>? B1) : A1 =>? B1 =
+ def orElse[A1 <: A, B1 >: B](that: PartialFunction[A1, B1]) : PartialFunction[A1, B1] =
new PartialFunction[A1, B1] {
def isDefinedAt(x: A1): Boolean =
PartialFunction.this.isDefinedAt(x) || that.isDefinedAt(x)
@@ -54,7 +54,7 @@ trait PartialFunction[-A, +B] extends (A => B) {
* @return a partial function with the same domain as this partial function, which maps
* arguments `x` to `k(this(x))`.
*/
- override def andThen[C](k: B => C): A =>? C = new PartialFunction[A, C] {
+ override def andThen[C](k: B => C) : PartialFunction[A, C] = new PartialFunction[A, C] {
def isDefinedAt(x: A): Boolean = PartialFunction.this.isDefinedAt(x)
def apply(x: A): C = k(PartialFunction.this.apply(x))
}
@@ -92,7 +92,7 @@ object PartialFunction
* @param pf the partial function
* @return true, iff `x` is in the domain of `pf` and `pf(x) == true`.
*/
- def cond[T](x: T)(pf: T =>? Boolean): Boolean =
+ def cond[T](x: T)(pf: PartialFunction[T, Boolean]): Boolean =
(pf isDefinedAt x) && pf(x)
/** Transforms a PartialFunction[T, U] `pf' into Function1[T, Option[U]] `f'
@@ -104,6 +104,6 @@ object PartialFunction
* @param pf the PartialFunction[T, U]
* @return `Some(pf(x))` if `pf isDefinedAt x`, `None` otherwise.
*/
- def condOpt[T,U](x: T)(pf: T =>? U): Option[U] =
+ def condOpt[T,U](x: T)(pf: PartialFunction[T, U]): Option[U] =
if (pf isDefinedAt x) Some(pf(x)) else None
}
diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala
index 1b9f4b75ba..5684c91aaa 100644
--- a/src/library/scala/Predef.scala
+++ b/src/library/scala/Predef.scala
@@ -117,7 +117,7 @@ object Predef extends LowPriorityImplicits {
throw new IllegalArgumentException("requirement failed: "+ message)
}
- class Ensuring[A](x: A) {
+ final class Ensuring[A](val x: A) {
def ensuring(cond: Boolean): A = { assert(cond); x }
def ensuring(cond: Boolean, msg: Any): A = { assert(cond, msg); x }
def ensuring(cond: A => Boolean): A = { assert(cond(x)); x }
@@ -139,7 +139,7 @@ object Predef extends LowPriorityImplicits {
def unapply[A, B, C](x: Tuple3[A, B, C]): Option[Tuple3[A, B, C]] = Some(x)
}
- class ArrowAssoc[A](x: A) {
+ final class ArrowAssoc[A](val x: A) {
@inline def -> [B](y: B): Tuple2[A, B] = Tuple2(x, y)
def →[B](y: B): Tuple2[A, B] = ->(y)
}
diff --git a/src/library/scala/collection/IndexedSeqViewLike.scala b/src/library/scala/collection/IndexedSeqViewLike.scala
index 06fa6c8953..07f63ad2b0 100644
--- a/src/library/scala/collection/IndexedSeqViewLike.scala
+++ b/src/library/scala/collection/IndexedSeqViewLike.scala
@@ -24,28 +24,55 @@ import TraversableView.NoBuilder
trait IndexedSeqViewLike[+A,
+Coll,
+This <: IndexedSeqView[A, Coll] with IndexedSeqViewLike[A, Coll, This]]
- extends IndexedSeq[A]
- with IndexedSeqLike[A, This]
- with SeqView[A, Coll]
- with SeqViewLike[A, Coll, This]
- with views.IndexedSeqTransformations[A, Coll, This]
+ extends IndexedSeq[A] with IndexedSeqLike[A, This] with SeqView[A, Coll] with SeqViewLike[A, Coll, This]
{ self =>
- trait Transformed[+B] extends views.IndexedSeqLike[B, Coll] with super.Transformed[B]
+ trait Transformed[+B] extends IndexedSeqView[B, Coll] with super.Transformed[B]
- trait Sliced extends Transformed[A] with super.Sliced
- trait Mapped[B] extends Transformed[B] with super.Mapped[B]
- trait FlatMapped[B] extends Transformed[B] with super.FlatMapped[B]
- trait Appended[B >: A] extends Transformed[B] with super.Appended[B]
- trait Filtered extends Transformed[A] with super.Filtered
- trait TakenWhile extends Transformed[A] with super.TakenWhile
- trait DroppedWhile extends Transformed[A] with super.DroppedWhile
- trait Reversed extends Transformed[A] with super.Reversed
- trait Patched[B >: A] extends Transformed[B] with super.Patched[B]
+ trait Sliced extends Transformed[A] with super.Sliced {
+ /** Override to use IndexedSeq's foreach; todo: see whether this is really faster */
+ override def foreach[U](f: A => U) = super[Transformed].foreach(f)
+ }
+
+ trait Mapped[B] extends Transformed[B] with super.Mapped[B] {
+ override def foreach[U](f: B => U) = super[Transformed].foreach(f)
+ }
+
+ trait FlatMapped[B] extends Transformed[B] with super.FlatMapped[B] {
+ override def foreach[U](f: B => U) = super[Transformed].foreach(f)
+ }
+
+ trait Appended[B >: A] extends Transformed[B] with super.Appended[B] {
+ override def foreach[U](f: B => U) = super[Transformed].foreach(f)
+ }
+
+ trait Filtered extends Transformed[A] with super.Filtered {
+ override def foreach[U](f: A => U) = super[Transformed].foreach(f)
+ }
+
+ trait TakenWhile extends Transformed[A] with super.TakenWhile {
+ override def foreach[U](f: A => U) = super[Transformed].foreach(f)
+ }
+
+ trait DroppedWhile extends Transformed[A] with super.DroppedWhile {
+ override def foreach[U](f: A => U) = super[Transformed].foreach(f)
+ }
+
+ trait Reversed extends Transformed[A] with super.Reversed {
+ override def foreach[U](f: A => U) = super[Transformed].foreach(f)
+ }
+
+ trait Patched[B >: A] extends Transformed[B] with super.Patched[B] {
+ override def foreach[U](f: B => U) = super[Transformed].foreach(f)
+ }
trait Zipped[B] extends Transformed[(A, B)] {
protected[this] val other: Iterable[B]
- def length = self.length min other.size
+ /** Have to be careful here - other may be an infinite sequence. */
+ def length =
+ if (other.hasDefiniteSize) self.length min other.size
+ else other take self.length size
+
def apply(idx: Int): (A, B) = (self.apply(idx), other.iterator drop idx next)
override def stringPrefix = self.stringPrefix+"Z"
}
@@ -65,5 +92,22 @@ trait IndexedSeqViewLike[+A,
}
override def stringPrefix = self.stringPrefix+"Z"
}
+
+ /** Boilerplate method, to override in each subclass
+ * This method could be eliminated if Scala had virtual classes
+ */
+ protected override def newAppended[B >: A](that: Traversable[B]): Transformed[B] = new Appended[B] { val rest = that }
+ protected override def newMapped[B](f: A => B): Transformed[B] = new Mapped[B] { val mapping = f }
+ protected override def newFlatMapped[B](f: A => Traversable[B]): Transformed[B] = new FlatMapped[B] { val mapping = f }
+ protected override def newFiltered(p: A => Boolean): Transformed[A] = new Filtered { val pred = p }
+ protected override def newSliced(_from: Int, _until: Int): Transformed[A] = new Sliced { val from = _from; val until = _until }
+ protected override def newDroppedWhile(p: A => Boolean): Transformed[A] = new DroppedWhile { val pred = p }
+ protected override def newTakenWhile(p: A => Boolean): Transformed[A] = new TakenWhile { val pred = p }
+ protected override def newZipped[B](that: Iterable[B]): Transformed[(A, B)] = new Zipped[B] { val other = that }
+ protected override def newZippedAll[A1 >: A, B](that: Iterable[B], _thisElem: A1, _thatElem: B): Transformed[(A1, B)] = new ZippedAll[A1, B] { val other = that; val thisElem = _thisElem; val thatElem = _thatElem }
+ protected override def newReversed: Transformed[A] = new Reversed { }
+ protected override def newPatched[B >: A](_from: Int, _patch: Seq[B], _replaced: Int): Transformed[B] = new Patched[B] {
+ val from = _from; val patch = _patch; val replaced = _replaced
+ }
override def stringPrefix = "IndexedSeqView"
}
diff --git a/src/library/scala/collection/IterableViewLike.scala b/src/library/scala/collection/IterableViewLike.scala
index 831a244352..27323294c4 100644
--- a/src/library/scala/collection/IterableViewLike.scala
+++ b/src/library/scala/collection/IterableViewLike.scala
@@ -24,14 +24,10 @@ import TraversableView.NoBuilder
trait IterableViewLike[+A,
+Coll,
+This <: IterableView[A, Coll] with IterableViewLike[A, Coll, This]]
- extends Iterable[A]
- with IterableLike[A, This]
- with TraversableView[A, Coll]
- with TraversableViewLike[A, Coll, This]
- with views.IterableTransformations[A, Coll, This]
+extends Iterable[A] with IterableLike[A, This] with TraversableView[A, Coll] with TraversableViewLike[A, Coll, This]
{ self =>
- trait Transformed[+B] extends views.IterableLike[B, Coll] with super.Transformed[B]
+ trait Transformed[+B] extends IterableView[B, Coll] with super.Transformed[B]
trait Sliced extends Transformed[A] with super.Sliced {
override def iterator = self.iterator slice (from, until)
@@ -88,5 +84,25 @@ trait IterableViewLike[+A,
override def zipAll[B, A1 >: A, That](that: Iterable[B], thisElem: A1, thatElem: B)(implicit bf: CanBuildFrom[This, (A1, B), That]): That =
newZippedAll(that, thisElem, thatElem).asInstanceOf[That]
+ protected def newZipped[B](that: Iterable[B]): Transformed[(A, B)] = new Zipped[B] {
+ val other = that
+ }
+ protected def newZippedAll[A1 >: A, B](that: Iterable[B], _thisElem: A1, _thatElem: B): Transformed[(A1, B)] = new ZippedAll[A1, B] {
+ val other: Iterable[B] = that
+ val thisElem = _thisElem
+ val thatElem = _thatElem
+ }
+
+ /** Boilerplate method, to override in each subclass
+ * This method could be eliminated if Scala had virtual classes
+ */
+ protected override def newAppended[B >: A](that: Traversable[B]): Transformed[B] = new Appended[B] { val rest = that }
+ protected override def newMapped[B](f: A => B): Transformed[B] = new Mapped[B] { val mapping = f }
+ protected override def newFlatMapped[B](f: A => Traversable[B]): Transformed[B] = new FlatMapped[B] { val mapping = f }
+ protected override def newFiltered(p: A => Boolean): Transformed[A] = new Filtered { val pred = p }
+ protected override def newSliced(_from: Int, _until: Int): Transformed[A] = new Sliced { val from = _from; val until = _until }
+ protected override def newDroppedWhile(p: A => Boolean): Transformed[A] = new DroppedWhile { val pred = p }
+ protected override def newTakenWhile(p: A => Boolean): Transformed[A] = new TakenWhile { val pred = p }
+
override def stringPrefix = "IterableView"
}
diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala
index 5f28161ed3..c23765c9bc 100644
--- a/src/library/scala/collection/Iterator.scala
+++ b/src/library/scala/collection/Iterator.scala
@@ -411,7 +411,7 @@ trait Iterator[+A] { self =>
* @return a new iterator which yields each value `x` produced by this iterator for
* which `pf` is defined the image `pf(x)`.
*/
- def partialMap[B](pf: A =>? B): Iterator[B] = {
+ def partialMap[B](pf: PartialFunction[A, B]): Iterator[B] = {
val self = buffered
new Iterator[B] {
private def skip() = while (self.hasNext && !pf.isDefinedAt(self.head)) self.next()
@@ -1112,9 +1112,10 @@ trait Iterator[+A] { self =>
res.toList
}
- /** Traverses this iterator and returns all produced values in a list.
+ /** Lazily wraps a Stream around this iterator so its values are memoized.
*
- * @return a stream which contains all values produced by this iterator.
+ * @return a Stream which can repeatedly produce all the values
+ * produced by this iterator.
*/
def toStream: Stream[A] =
if (hasNext) Stream.cons(next, toStream) else Stream.empty
diff --git a/src/library/scala/collection/JavaConversions.scala b/src/library/scala/collection/JavaConversions.scala
index 15005f71ba..7af138067b 100644
--- a/src/library/scala/collection/JavaConversions.scala
+++ b/src/library/scala/collection/JavaConversions.scala
@@ -53,6 +53,7 @@ package scala.collection
*/
object JavaConversions {
import java.{ lang => jl, util => ju }
+ import java.util.{ concurrent => juc }
import scala.collection.{ generic, immutable, mutable, Traversable }
import scala.reflect.ClassManifest
@@ -178,10 +179,17 @@ object JavaConversions {
* @return A Java <code>Map</code> view of the argument.
*/
implicit def asMap[A, B](m : mutable.Map[A, B])(implicit ma : ClassManifest[A]) : ju.Map[A, B] = m match {
+ //case JConcurrentMapWrapper(wrapped) => wrapped
case JMapWrapper(wrapped) => wrapped
case _ => new MutableMapWrapper(m)(ma)
}
+ implicit def asConcurrentMap[A, B](m: mutable.ConcurrentMap[A, B])
+ (implicit ma: ClassManifest[A], mb: ClassManifest[B]): juc.ConcurrentMap[A, B] = m match {
+ case JConcurrentMapWrapper(wrapped) => wrapped
+ case _ => new ConcurrentMapWrapper(m)(ma, mb)
+ }
+
// Java => Scala
/**
@@ -303,8 +311,31 @@ object JavaConversions {
* @return A Scala mutable <code>Map</code> view of the argument.
*/
implicit def asMap[A, B](m : ju.Map[A, B]) = m match {
+ //case ConcurrentMapWrapper(wrapped) => wrapped
case MutableMapWrapper(wrapped) => wrapped
- case _ =>new JMapWrapper(m)
+ case _ => new JMapWrapper(m)
+ }
+
+ /**
+ * Implicitly converts a Java <code>ConcurrentMap</code> to a Scala mutable <code>ConcurrentMap</code>.
+ * The returned Scala <code>ConcurrentMap</code> is backed by the provided Java
+ * <code>ConcurrentMap</code> and any side-effects of using it via the Scala interface will
+ * be visible via the Java interface and vice versa.
+ * <p>
+ * If the Java <code>ConcurrentMap</code> was previously obtained from an implicit or
+ * explicit call of <code>asConcurrentMap(scala.collection.mutable.ConcurrentMap)</code> then the original
+ * Scala <code>ConcurrentMap</code> will be returned.
+ *
+ * @param m The <code>ConcurrentMap</code> to be converted.
+ * @return A Scala mutable <code>ConcurrrentMap</code> view of the argument.
+ */
+ implicit def asConcurrentMap[A, B](m: juc.ConcurrentMap[A, B]) = m match {
+ case ConcurrentMapWrapper(wrapped) => wrapped
+ case _ => new JConcurrentMapWrapper(m)
+ }
+
+ implicit def asMap(p: ju.Properties): mutable.Map[String, String] = p match {
+ case _ => new JPropertiesWrapper(p)
}
// Private implementations ...
@@ -410,7 +441,8 @@ object JavaConversions {
override def empty = JSetWrapper(new ju.HashSet[A])
}
- case class MutableMapWrapper[A, B](underlying : mutable.Map[A, B])(m : ClassManifest[A]) extends ju.AbstractMap[A, B] {
+ abstract class MutableMapWrapperLike[A, B](underlying: mutable.Map[A, B])(m: ClassManifest[A])
+ extends ju.AbstractMap[A, B] {
self =>
override def size = underlying.size
@@ -462,7 +494,12 @@ object JavaConversions {
}
}
- case class JMapWrapper[A, B](underlying : ju.Map[A, B]) extends mutable.Map[A, B] with mutable.MapLike[A, B, JMapWrapper[A, B]] {
+ case class MutableMapWrapper[A, B](underlying : mutable.Map[A, B])(m : ClassManifest[A])
+ extends MutableMapWrapperLike[A, B](underlying)(m)
+
+ abstract class JMapWrapperLike[A, B, +Repr <: mutable.MapLike[A, B, Repr] with mutable.Map[A, B]]
+ (underlying: ju.Map[A, B])
+ extends mutable.Map[A, B] with mutable.MapLike[A, B, Repr] {
override def size = underlying.size
def get(k : A) = {
@@ -498,6 +535,127 @@ object JavaConversions {
override def clear = underlying.clear
+ override def empty: Repr = null.asInstanceOf[Repr]
+ }
+
+ case class JMapWrapper[A, B](underlying : ju.Map[A, B])
+ extends JMapWrapperLike[A, B, JMapWrapper[A, B]](underlying) {
override def empty = JMapWrapper(new ju.HashMap[A, B])
}
+
+ case class ConcurrentMapWrapper[A, B](underlying: mutable.ConcurrentMap[A, B])
+ (m: ClassManifest[A], mv: ClassManifest[B])
+ extends MutableMapWrapperLike[A, B](underlying)(m) with juc.ConcurrentMap[A, B] {
+ self =>
+
+ override def remove(k : AnyRef) = {
+ if (!m.erasure.isInstance(k))
+ null.asInstanceOf[B]
+ else {
+ val k1 = k.asInstanceOf[A]
+ underlying.remove(k1) match {
+ case Some(v) => v
+ case None => null.asInstanceOf[B]
+ }
+ }
+ }
+
+ def putIfAbsent(k: A, v: B) = underlying.putIfAbsent(k, v) match {
+ case Some(v) => v
+ case None => null.asInstanceOf[B]
+ }
+
+ def remove(k: AnyRef, v: AnyRef) = {
+ if (!m.erasure.isInstance(k) || !mv.erasure.isInstance(v))
+ false
+ else {
+ val k1 = k.asInstanceOf[A]
+ val v1 = v.asInstanceOf[B]
+ underlying.remove(k1, v1)
+ }
+ }
+
+ def replace(k: A, v: B): B = underlying.replace(k, v) match {
+ case Some(v) => v
+ case None => null.asInstanceOf[B]
+ }
+
+ def replace(k: A, oldval: B, newval: B) = underlying.replace(k, oldval, newval)
+
+ }
+
+ case class JConcurrentMapWrapper[A, B](underlying: juc.ConcurrentMap[A, B])
+ extends JMapWrapperLike[A, B, JConcurrentMapWrapper[A, B]](underlying) with mutable.ConcurrentMap[A, B] {
+ override def get(k: A) = {
+ val v = underlying.get(k)
+ if (v != null) Some(v)
+ else None
+ }
+
+ override def empty = new JConcurrentMapWrapper(new juc.ConcurrentHashMap[A, B])
+
+ def putIfAbsent(k: A, v: B): Option[B] = {
+ val r = underlying.putIfAbsent(k, v)
+ if (r != null) Some(r) else None
+ }
+
+ def remove(k: A, v: B): Boolean = underlying.remove(k, v)
+
+ def replace(k: A, v: B): Option[B] = {
+ val prev = underlying.replace(k, v)
+ if (prev != null) Some(prev) else None
+ }
+
+ def replace(k: A, oldvalue: B, newvalue: B): Boolean = underlying.replace(k, oldvalue, newvalue)
+
+ }
+
+ case class JPropertiesWrapper(underlying: ju.Properties)
+ extends mutable.Map[String, String] with mutable.MapLike[String, String, JPropertiesWrapper] {
+ override def size = underlying.size
+
+ def get(k : String) = {
+ val v = underlying.get(k)
+ if (v != null)
+ Some(v.asInstanceOf[String])
+ else
+ None
+ }
+
+ def +=(kv: (String, String)): this.type = { underlying.put(kv._1, kv._2); this }
+ def -=(key: String): this.type = { underlying.remove(key); this }
+
+ override def put(k : String, v : String): Option[String] = {
+ val r = underlying.put(k, v)
+ if (r != null) Some(r.asInstanceOf[String]) else None
+ }
+
+ override def update(k : String, v : String) { underlying.put(k, v) }
+
+ override def remove(k : String): Option[String] = {
+ val r = underlying.remove(k)
+ if (r != null) Some(r.asInstanceOf[String]) else None
+ }
+
+ def iterator = new Iterator[(String, String)] {
+ val ui = underlying.entrySet.iterator
+ def hasNext = ui.hasNext
+ def next = { val e = ui.next ; (e.getKey.asInstanceOf[String], e.getValue.asInstanceOf[String]) }
+ }
+
+ override def clear = underlying.clear
+
+ override def empty = JPropertiesWrapper(new ju.Properties)
+
+ def getProperty(key: String) = underlying.getProperty(key)
+
+ def getProperty(key: String, defaultValue: String) = underlying.getProperty(key, defaultValue)
+
+ def setProperty(key: String, value: String) = underlying.setProperty(key, value)
+ }
+
}
+
+
+
+
diff --git a/src/library/scala/collection/SeqViewLike.scala b/src/library/scala/collection/SeqViewLike.scala
index 6f677616e7..1a8cd20013 100644
--- a/src/library/scala/collection/SeqViewLike.scala
+++ b/src/library/scala/collection/SeqViewLike.scala
@@ -23,14 +23,13 @@ import TraversableView.NoBuilder
trait SeqViewLike[+A,
+Coll,
+This <: SeqView[A, Coll] with SeqViewLike[A, Coll, This]]
- extends Seq[A]
- with SeqLike[A, This]
- with IterableView[A, Coll]
- with IterableViewLike[A, Coll, This]
- with views.SeqTransformations[A, Coll, This]
+ extends Seq[A] with SeqLike[A, This] with IterableView[A, Coll] with IterableViewLike[A, Coll, This]
{ self =>
- trait Transformed[+B] extends views.SeqLike[B, Coll] with super.Transformed[B]
+ trait Transformed[+B] extends SeqView[B, Coll] with super.Transformed[B] {
+ override def length: Int
+ override def apply(idx: Int): B
+ }
trait Sliced extends Transformed[A] with super.Sliced {
override def length = ((until min self.length) - from) max 0
@@ -144,6 +143,21 @@ trait SeqViewLike[+A,
override def stringPrefix = self.stringPrefix+"P"
}
+ /** Boilerplate method, to override in each subclass
+ * This method could be eliminated if Scala had virtual classes
+ */
+ protected override def newAppended[B >: A](that: Traversable[B]): Transformed[B] = new Appended[B] { val rest = that }
+ protected override def newMapped[B](f: A => B): Transformed[B] = new Mapped[B] { val mapping = f }
+ protected override def newFlatMapped[B](f: A => Traversable[B]): Transformed[B] = new FlatMapped[B] { val mapping = f }
+ protected override def newFiltered(p: A => Boolean): Transformed[A] = new Filtered { val pred = p }
+ protected override def newSliced(_from: Int, _until: Int): Transformed[A] = new Sliced { val from = _from; val until = _until }
+ protected override def newDroppedWhile(p: A => Boolean): Transformed[A] = new DroppedWhile { val pred = p }
+ protected override def newTakenWhile(p: A => Boolean): Transformed[A] = new TakenWhile { val pred = p }
+ protected override def newZipped[B](that: Iterable[B]): Transformed[(A, B)] = new Zipped[B] { val other = that }
+ protected override def newZippedAll[A1 >: A, B](that: Iterable[B], _thisElem: A1, _thatElem: B): Transformed[(A1, B)] = new ZippedAll[A1, B] { val other = that; val thisElem = _thisElem; val thatElem = _thatElem }
+ protected def newReversed: Transformed[A] = new Reversed { }
+ protected def newPatched[B >: A](_from: Int, _patch: Seq[B], _replaced: Int): Transformed[B] = new Patched[B] { val from = _from; val patch = _patch; val replaced = _replaced }
+
override def reverse: This = newReversed.asInstanceOf[This]
override def patch[B >: A, That](from: Int, patch: Seq[B], replaced: Int)(implicit bf: CanBuildFrom[This, B, That]): That = {
diff --git a/src/library/scala/collection/TraversableLike.scala b/src/library/scala/collection/TraversableLike.scala
index f570c4ca9a..fc666ddb92 100644
--- a/src/library/scala/collection/TraversableLike.scala
+++ b/src/library/scala/collection/TraversableLike.scala
@@ -292,13 +292,13 @@ self =>
* `pf` to each element on which it is defined and collecting the results.
* The order of the elements is preserved.
*
- * @usecase def partialMap[B](pf: A =>? B): $Coll[B]
+ * @usecase def partialMap[B](pf: PartialFunction[A, B]): $Coll[B]
*
* @return a new $coll resulting from applying the given partial function
* `pf` to each element on which it is defined and collecting the results.
* The order of the elements is preserved.
*/
- def partialMap[B, That](pf: A =>? B)(implicit bf: CanBuildFrom[Repr, B, That]): That = {
+ def partialMap[B, That](pf: PartialFunction[A, B])(implicit bf: CanBuildFrom[Repr, B, That]): That = {
val b = bf(repr)
for (x <- this) if (pf.isDefinedAt(x)) b += pf(x)
b.result
@@ -984,9 +984,7 @@ self =>
def toList: List[A] = (new ListBuffer[A] ++= thisCollection).toList
/** Converts this $coll to an iterable collection.
- *
- * Note: Will not terminate for infinite-sized collections.
- *
+ * $willNotTerminateInf
* @return an `Iterable` containing all elements of this $coll.
*/
def toIterable: Iterable[A] = toStream
@@ -1015,6 +1013,22 @@ self =>
*/
def toSet[B >: A]: immutable.Set[B] = immutable.Set() ++ thisCollection
+ /** Converts this $coll to a map. This method is unavailable unless
+ * the elements are members of Tuple2, each ((K, V)) becoming a key-value
+ * pair in the map. Duplicate keys will be overwritten by later keys:
+ * if this is an unordered collection, which key is in the resulting map
+ * is undefined.
+ * $willNotTerminateInf
+ * @return a map containing all elements of this $coll.
+ */
+ def toMap[T, U](implicit ev: A <:< (T, U)): immutable.Map[T, U] = {
+ val b = immutable.Map.newBuilder[T, U]
+ for (x <- this)
+ b += x
+
+ b.result
+ }
+
/** Displays all elements of this $coll in a string using start, end, and separator strings.
*
* @param start the starting string.
diff --git a/src/library/scala/collection/TraversableProxyLike.scala b/src/library/scala/collection/TraversableProxyLike.scala
index d8e3ed2a1b..24d6c7048d 100644
--- a/src/library/scala/collection/TraversableProxyLike.scala
+++ b/src/library/scala/collection/TraversableProxyLike.scala
@@ -36,7 +36,7 @@ trait TraversableProxyLike[+A, +This <: TraversableLike[A, This] with Traversabl
override def ++[B >: A, That](that: Iterator[B])(implicit bf: CanBuildFrom[This, B, That]): That = self.++(that)(bf)
override def map[B, That](f: A => B)(implicit bf: CanBuildFrom[This, B, That]): That = self.map(f)(bf)
override def flatMap[B, That](f: A => Traversable[B])(implicit bf: CanBuildFrom[This, B, That]): That = self.flatMap(f)(bf)
- override def partialMap[B, That](pf: A =>? B)(implicit bf: CanBuildFrom[This, B, That]): That = self.partialMap(pf)(bf)
+ override def partialMap[B, That](pf: PartialFunction[A, B])(implicit bf: CanBuildFrom[This, B, That]): That = self.partialMap(pf)(bf)
override def filter(p: A => Boolean): This = self.filter(p)
override def filterNot(p: A => Boolean): This = self.filterNot(p)
override def partition(p: A => Boolean): (This, This) = self.partition(p)
diff --git a/src/library/scala/collection/TraversableViewLike.scala b/src/library/scala/collection/TraversableViewLike.scala
index 7f4d0ebd71..84c33296db 100644
--- a/src/library/scala/collection/TraversableViewLike.scala
+++ b/src/library/scala/collection/TraversableViewLike.scala
@@ -33,9 +33,7 @@ import TraversableView.NoBuilder
trait TraversableViewLike[+A,
+Coll,
+This <: TraversableView[A, Coll] with TraversableViewLike[A, Coll, This]]
- extends Traversable[A]
- with TraversableLike[A, This]
- with views.TraversableTransformations[A, Coll, This] {
+ extends Traversable[A] with TraversableLike[A, This] {
self =>
override protected[this] def newBuilder: Builder[A, This] =
@@ -43,16 +41,16 @@ self =>
protected def underlying: Coll
- trait Transformed[+B] extends views.TraversableLike[B, Coll] {
- lazy val underlying = self.underlying
- }
-
def force[B >: A, That](implicit bf: CanBuildFrom[Coll, B, That]) = {
val b = bf(underlying)
b ++= this
b.result()
}
+ trait Transformed[+B] extends TraversableView[B, Coll] {
+ lazy val underlying = self.underlying
+ }
+
/** pre: from >= 0
*/
trait Sliced extends Transformed[A] {
@@ -133,6 +131,17 @@ self =>
override def stringPrefix = self.stringPrefix+"D"
}
+ /** Boilerplate method, to override in each subclass
+ * This method could be eliminated if Scala had virtual classes
+ */
+ protected def newAppended[B >: A](that: Traversable[B]): Transformed[B] = new Appended[B] { val rest = that }
+ protected def newMapped[B](f: A => B): Transformed[B] = new Mapped[B] { val mapping = f }
+ protected def newFlatMapped[B](f: A => Traversable[B]): Transformed[B] = new FlatMapped[B] { val mapping = f }
+ protected def newFiltered(p: A => Boolean): Transformed[A] = new Filtered { val pred = p }
+ protected def newSliced(_from: Int, _until: Int): Transformed[A] = new Sliced { val from = _from; val until = _until }
+ protected def newDroppedWhile(p: A => Boolean): Transformed[A] = new DroppedWhile { val pred = p }
+ protected def newTakenWhile(p: A => Boolean): Transformed[A] = new TakenWhile { val pred = p }
+
override def ++[B >: A, That](that: Traversable[B])(implicit bf: CanBuildFrom[This, B, That]): That = {
newAppended(that).asInstanceOf[That]
// was: if (bf.isInstanceOf[ByPassCanBuildFrom]) newAppended(that).asInstanceOf[That]
diff --git a/src/library/scala/collection/immutable/List.scala b/src/library/scala/collection/immutable/List.scala
index 2c36161003..2088f3ac78 100644
--- a/src/library/scala/collection/immutable/List.scala
+++ b/src/library/scala/collection/immutable/List.scala
@@ -98,7 +98,7 @@ sealed abstract class List[+A] extends LinearSeq[A]
/** Builds a new list by applying a function to all elements of this list.
* Like `xs map f`, but returns `xs` unchanged if function
- * `f` maps all elements to themselves (wrt ==).
+ * `f` maps all elements to themselves (wrt eq).
*
* Note: Unlike `map`, `mapConserve` is not tail-recursive.
*
@@ -106,15 +106,15 @@ sealed abstract class List[+A] extends LinearSeq[A]
* @tparam B the element type of the returned collection.
* @return a list resulting from applying the given function
* `f` to each element of this list and collecting the results.
- * @usecase def mapConserve[B](f: A => B): List[A]
+ * @usecase def mapConserve(f: A => A): List[A]
*/
- def mapConserve[B >: A] (f: A => B): List[B] = {
+ def mapConserve[B >: A <: AnyRef] (f: A => B): List[B] = {
def loop(ys: List[A]): List[B] =
if (ys.isEmpty) this
else {
val head0 = ys.head
val head1 = f(head0)
- if (head1 == head0) {
+ if (head1 eq head0.asInstanceOf[AnyRef]) {
loop(ys.tail)
} else {
val ys1 = head1 :: ys.tail.mapConserve(f)
diff --git a/src/library/scala/collection/immutable/RedBlack.scala b/src/library/scala/collection/immutable/RedBlack.scala
index 9fd082a7fd..dfb34552cd 100644
--- a/src/library/scala/collection/immutable/RedBlack.scala
+++ b/src/library/scala/collection/immutable/RedBlack.scala
@@ -33,7 +33,7 @@ abstract class RedBlack[A] {
def isBlack: Boolean
def lookup(x: A): Tree[B]
def update[B1 >: B](k: A, v: B1): Tree[B1] = blacken(upd(k, v))
- def delete(k: A): Tree[B] = del(k)
+ def delete(k: A): Tree[B] = blacken(del(k))
def foreach[U](f: (A, B) => U)
@deprecated("use `foreach' instead")
def visit[T](input: T)(f: (T, A, B) => (Boolean, T)): (Boolean, T)
@@ -80,16 +80,77 @@ abstract class RedBlack[A] {
else if (isSmaller(key, k)) balanceRight(isBlack, key, value, left, right.upd(k, v))
else mkTree(isBlack, k, v, left, right)
}
+ // Based on Stefan Kahrs' Haskell version of Okasaki's Red&Black Trees
+ // http://www.cse.unsw.edu.au/~dons/data/RedBlackTree.html
def del(k: A): Tree[B] = {
- if (isSmaller(k, key)) mkTree(isBlack, key, value, left.del(k), right)
- else if (isSmaller(key, k)) mkTree(isBlack, key, value, left, right.del(k))
- else if (left.isEmpty) right
- else if (right.isEmpty) left
- else {
- val s = right.smallest
- mkTree(isBlack, s.key, s.value, left, right.del(s.key))
+ def balance(x: A, xv: B, tl: Tree[B], tr: Tree[B]) = (tl, tr) match {
+ case (RedTree(y, yv, a, b), RedTree(z, zv, c, d)) =>
+ RedTree(x, xv, BlackTree(y, yv, a, b), BlackTree(z, zv, c, d))
+ case (RedTree(y, yv, RedTree(z, zv, a, b), c), d) =>
+ RedTree(y, yv, BlackTree(z, zv, a, b), BlackTree(x, xv, c, d))
+ case (RedTree(y, yv, a, RedTree(z, zv, b, c)), d) =>
+ RedTree(z, zv, BlackTree(y, yv, a, b), BlackTree(x, xv, c, d))
+ case (a, RedTree(y, yv, b, RedTree(z, zv, c, d))) =>
+ RedTree(y, yv, BlackTree(x, xv, a, b), BlackTree(z, zv, c, d))
+ case (a, RedTree(y, yv, RedTree(z, zv, b, c), d)) =>
+ RedTree(z, zv, BlackTree(x, xv, a, b), BlackTree(y, yv, c, d))
+ case (a, b) =>
+ BlackTree(x, xv, a, b)
+ }
+ def subl(t: Tree[B]) = t match {
+ case BlackTree(x, xv, a, b) => RedTree(x, xv, a, b)
+ case _ => error("Defect: invariance violation; expected black, got "+t)
+ }
+ def balLeft(x: A, xv: B, tl: Tree[B], tr: Tree[B]) = (tl, tr) match {
+ case (RedTree(y, yv, a, b), c) =>
+ RedTree(x, xv, BlackTree(y, yv, a, b), c)
+ case (bl, BlackTree(y, yv, a, b)) =>
+ balance(x, xv, bl, RedTree(y, yv, a, b))
+ case (bl, RedTree(y, yv, BlackTree(z, zv, a, b), c)) =>
+ RedTree(z, zv, BlackTree(x, xv, bl, a), balance(y, yv, b, subl(c)))
+ case _ => error("Defect: invariance violation at "+right)
+ }
+ def balRight(x: A, xv: B, tl: Tree[B], tr: Tree[B]) = (tl, tr) match {
+ case (a, RedTree(y, yv, b, c)) =>
+ RedTree(x, xv, a, BlackTree(y, yv, b, c))
+ case (BlackTree(y, yv, a, b), bl) =>
+ balance(x, xv, RedTree(y, yv, a, b), bl)
+ case (RedTree(y, yv, a, BlackTree(z, zv, b, c)), bl) =>
+ RedTree(z, zv, balance(y, yv, subl(a), b), BlackTree(x, xv, c, bl))
+ case _ => error("Defect: invariance violation at "+left)
+ }
+ def delLeft = left match {
+ case _: BlackTree[_] => balLeft(key, value, left.del(k), right)
+ case _ => RedTree(key, value, left.del(k), right)
+ }
+ def delRight = right match {
+ case _: BlackTree[_] => balRight(key, value, left, right.del(k))
+ case _ => RedTree(key, value, left, right.del(k))
+ }
+ def append(tl: Tree[B], tr: Tree[B]): Tree[B] = (tl, tr) match {
+ case (Empty, t) => t
+ case (t, Empty) => t
+ case (RedTree(x, xv, a, b), RedTree(y, yv, c, d)) =>
+ append(b, c) match {
+ case RedTree(z, zv, bb, cc) => RedTree(z, zv, RedTree(x, xv, a, bb), RedTree(y, yv, cc, d))
+ case bc => RedTree(x, xv, a, RedTree(y, yv, bc, d))
+ }
+ case (BlackTree(x, xv, a, b), BlackTree(y, yv, c, d)) =>
+ append(b, c) match {
+ case RedTree(z, zv, bb, cc) => RedTree(z, zv, BlackTree(x, xv, a, bb), BlackTree(y, yv, cc, d))
+ case bc => balLeft(x, xv, a, BlackTree(y, yv, bc, d))
+ }
+ case (a, RedTree(x, xv, b, c)) => RedTree(x, xv, append(a, b), c)
+ case (RedTree(x, xv, a, b), c) => RedTree(x, xv, a, append(b, c))
+ }
+ // RedBlack is neither A : Ordering[A], nor A <% Ordered[A]
+ k match {
+ case _ if isSmaller(k, key) => delLeft
+ case _ if isSmaller(key, k) => delRight
+ case _ => append(left, right)
}
}
+
def smallest: NonEmpty[B] = if (left.isEmpty) this else left.smallest
def toStream: Stream[(A,B)] =
diff --git a/src/library/scala/collection/immutable/StringOps.scala b/src/library/scala/collection/immutable/StringOps.scala
index 9138c2bbac..95509ab9d6 100644
--- a/src/library/scala/collection/immutable/StringOps.scala
+++ b/src/library/scala/collection/immutable/StringOps.scala
@@ -17,7 +17,7 @@ import mutable.StringBuilder
/**
* @since 2.8
*/
-class StringOps(override val repr: String) extends StringLike[String] {
+final class StringOps(override val repr: String) extends StringLike[String] {
override protected[this] def thisCollection: WrappedString = new WrappedString(repr)
override protected[this] def toCollection(repr: String): WrappedString = new WrappedString(repr)
@@ -25,5 +25,8 @@ class StringOps(override val repr: String) extends StringLike[String] {
/** Creates a string builder buffer as builder for this class */
override protected[this] def newBuilder = new StringBuilder
+ override def slice(from: Int, until: Int): String =
+ repr.substring(from max 0, until min repr.length)
+
override def toString = repr
}
diff --git a/src/library/scala/collection/immutable/WrappedString.scala b/src/library/scala/collection/immutable/WrappedString.scala
index e535cddfce..e10b3ab0ee 100644
--- a/src/library/scala/collection/immutable/WrappedString.scala
+++ b/src/library/scala/collection/immutable/WrappedString.scala
@@ -26,6 +26,9 @@ class WrappedString(override val self: String) extends IndexedSeq[Char] with Str
/** Creates a string builder buffer as builder for this class */
override protected[this] def newBuilder = WrappedString.newBuilder
+
+ override def slice(from: Int, until: Int): WrappedString =
+ new WrappedString(self.substring(from max 0, until min self.length))
}
/**
diff --git a/src/library/scala/collection/interfaces/TraversableMethods.scala b/src/library/scala/collection/interfaces/TraversableMethods.scala
index 4cf133d36a..08ade7586d 100644
--- a/src/library/scala/collection/interfaces/TraversableMethods.scala
+++ b/src/library/scala/collection/interfaces/TraversableMethods.scala
@@ -24,7 +24,7 @@ trait TraversableMethods[+A, +This <: TraversableLike[A, This] with Traversable[
// maps/iteration
def flatMap[B, That](f: A => Traversable[B])(implicit bf: CanBuildFrom[This, B, That]): That
def map[B, That](f: A => B)(implicit bf: CanBuildFrom[This, B, That]): That
- def partialMap[B, That](pf: A =>? B)(implicit bf: CanBuildFrom[This, B, That]): That
+ def partialMap[B, That](pf: PartialFunction[A, B])(implicit bf: CanBuildFrom[This, B, That]): That
// new collections
def ++[B >: A, That](that: Iterator[B])(implicit bf: CanBuildFrom[This, B, That]): That
diff --git a/src/library/scala/collection/mutable/ConcurrentMap.scala b/src/library/scala/collection/mutable/ConcurrentMap.scala
new file mode 100644
index 0000000000..d09bf57e1b
--- /dev/null
+++ b/src/library/scala/collection/mutable/ConcurrentMap.scala
@@ -0,0 +1,79 @@
+package scala.collection.mutable
+
+
+
+
+
+
+/**
+ * A template trait for mutable maps that allow concurrent access.
+ * $concurrentmapinfo
+ *
+ * @tparam A the key type of the map
+ * @tparam B the value type of the map
+ *
+ * @define concurrentmapinfo
+ * This is a base trait for all Scala concurrent map implementations. It
+ * provides all of the methods a Map does, with the difference that all the
+ * changes are atomic. It also describes methods specific to concurrent maps.
+ * Note: The concurrent maps do not accept `null` for keys or values.
+ *
+ * @define atomicop
+ * This is done atomically.
+ *
+ * @since 2.8
+ */
+trait ConcurrentMap[A, B] extends Map[A, B] {
+
+ /**
+ * Associates the given key with a given value, unless the key was already associated with some other value.
+ * $atomicop
+ *
+ * @param k key with which the specified value is to be associated with
+ * @param v value to be associated with the specified key
+ * @return `Some(oldvalue)` if there was a value `oldvalue` previously associated with the
+ * specified key, or `None` if there was no mapping for the specified key
+ */
+ def putIfAbsent(k: A, v: B): Option[B]
+
+ /**
+ * Removes the entry for the specified key if its currently mapped to the specified value.
+ * $atomicop
+ *
+ * @param k key for which the entry should be removed
+ * @param v value expected to be associated with the specified key if the removal is to take place
+ * @return `true` if the removal took place, `false` otherwise
+ */
+ def remove(k: A, v: B): Boolean
+
+ /**
+ * Replaces the entry for the given key only if it was previously mapped to a given value.
+ * $atomicop
+ *
+ * @param k key for which the entry should be replaced
+ * @param oldvalue value expected to be associated with the specified key if replacing is to happen
+ * @param newvalue value to be associated with the specified key
+ * @return `true` if the entry was replaced, `false` otherwise
+ */
+ def replace(k: A, oldvalue: B, newvalue: B): Boolean
+
+ /**
+ * Replaces the entry for the given key only if it was previously mapped to some value.
+ * $atomicop
+ *
+ * @param k key for which the entry should be replaced
+ * @param v value to be associated with the specified key
+ * @return `Some(v)` if the given key was previously mapped to some value `v`, or `None` otherwise
+ */
+ def replace(k: A, v: B): Option[B]
+
+}
+
+
+
+
+
+
+
+
+
diff --git a/src/library/scala/collection/mutable/FlatHashTable.scala b/src/library/scala/collection/mutable/FlatHashTable.scala
index 422559f089..0e73bf7fad 100644
--- a/src/library/scala/collection/mutable/FlatHashTable.scala
+++ b/src/library/scala/collection/mutable/FlatHashTable.scala
@@ -184,7 +184,7 @@ trait FlatHashTable[A] {
private def checkConsistent() {
for (i <- 0 until table.length)
if (table(i) != null && !containsEntry(table(i).asInstanceOf[A]))
- assert(false, i+" "+table(i)+" "+table.toString)
+ assert(false, i+" "+table(i)+" "+table.mkString)
}
protected def elemHashCode(elem: A) = if (elem == null) 0 else elem.hashCode()
diff --git a/src/library/scala/collection/mutable/IndexedSeqView.scala b/src/library/scala/collection/mutable/IndexedSeqView.scala
index db1735b543..e864845455 100644
--- a/src/library/scala/collection/mutable/IndexedSeqView.scala
+++ b/src/library/scala/collection/mutable/IndexedSeqView.scala
@@ -13,6 +13,7 @@ package scala.collection
package mutable
import generic._
+
import TraversableView.NoBuilder
/** A non-strict view of a mutable IndexedSeq.
@@ -29,7 +30,9 @@ self =>
def update(idx: Int, elem: A)
- trait Transformed[B] extends views.MutableIndexedSeq[B, Coll] with IndexedSeqView[B, Coll] with super.Transformed[B]
+ trait Transformed[B] extends IndexedSeqView[B, Coll] with super.Transformed[B] {
+ def update(idx: Int, elem: B)
+ }
trait Sliced extends Transformed[A] with super.Sliced {
override def update(idx: Int, elem: A) =
diff --git a/src/library/scala/collection/mutable/PriorityQueue.scala b/src/library/scala/collection/mutable/PriorityQueue.scala
index 203f1eee15..c4dac9effb 100644
--- a/src/library/scala/collection/mutable/PriorityQueue.scala
+++ b/src/library/scala/collection/mutable/PriorityQueue.scala
@@ -35,7 +35,7 @@ class PriorityQueue[A](implicit ord: Ordering[A])
{
import ord._
- private class ResizableArrayAccess[A] extends ResizableArray[A] {
+ private final class ResizableArrayAccess[A] extends ResizableArray[A] {
@inline def p_size0 = size0
@inline def p_size0_=(s: Int) = size0 = s
@inline def p_array = array
diff --git a/src/library/scala/collection/views/Transformed.scala b/src/library/scala/collection/views/Transformed.scala
deleted file mode 100644
index 189ca127c8..0000000000
--- a/src/library/scala/collection/views/Transformed.scala
+++ /dev/null
@@ -1,128 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2010, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.collection
-package views
-
-import generic.CanBuildFrom
-
-/** These classes act as accumulators for the majority of methods in the
- * collections hierarchy. By creating abstract classes rather than using
- * the traits exclusively, we avoid creating forwarders in dozens of distinct
- * anonymous classes and reduce the size of scala-library.jar by over 200K.
- */
-private[collection] trait Transformed
-private[collection] abstract class TraversableLike[+B, +Coll] extends TraversableView[B, Coll] with Transformed {
- override def foreach[C](f: B => C): Unit
-}
-private[collection] abstract class IterableLike[+B, +Coll] extends TraversableLike[B, Coll] with IterableView[B, Coll] {
- override def iterator: Iterator[B]
-}
-private[collection] abstract class SeqLike[+B, +Coll] extends IterableLike[B, Coll] with SeqView[B, Coll] {
- override def length: Int
- override def apply(idx: Int): B
-}
-private[collection] abstract class IndexedSeqLike[+B, +Coll] extends SeqLike[B, Coll] with IndexedSeqView[B, Coll] {
- /** Override to use IndexedSeq's foreach; todo: see whether this is really faster */
- override def foreach[U](f: B => U) = super[IndexedSeqView].foreach(f)
-}
-private[collection] abstract class MutableIndexedSeq[B, +Coll] extends IndexedSeqLike[B, Coll] {
- def update(idx: Int, elem: B)
-}
-
-/** The boilerplate in the following traits factored out of the *ViewLike classes
- * to reduce noise. It exists only to specialize the return type of each method.
- * It would be unnecessary if scala had virtual classes because the inner classes
- * of subtraits would subclass the parent trait inner classes, and the same method
- * would then suffice for both.
- */
-private[collection] trait TraversableTransformations[+A, +Coll, +This <: TraversableView[A, Coll] with TraversableViewLike[A, Coll, This]] {
- self: TraversableViewLike[A, Coll, This] =>
-
- /** Boilerplate methods, to override in each subclass. */
- protected def newAppended[B >: A](that: Traversable[B]): Transformed[B] = new Appended[B] { val rest = that }
- protected def newMapped[B](f: A => B): Transformed[B] = new Mapped[B] { val mapping = f }
- protected def newFlatMapped[B](f: A => Traversable[B]): Transformed[B] = new FlatMapped[B] { val mapping = f }
- protected def newFiltered(p: A => Boolean): Transformed[A] = new Filtered { val pred = p }
- protected def newSliced(_from: Int, _until: Int): Transformed[A] = new Sliced { val from = _from; val until = _until }
- protected def newDroppedWhile(p: A => Boolean): Transformed[A] = new DroppedWhile { val pred = p }
- protected def newTakenWhile(p: A => Boolean): Transformed[A] = new TakenWhile { val pred = p }
-}
-
-private[collection] trait IterableTransformations[+A, +Coll, +This <: IterableView[A, Coll] with IterableViewLike[A, Coll, This]]
- extends TraversableTransformations[A, Coll, This]
-{
- self: IterableViewLike[A, Coll, This] =>
-
- /** Inherited from TraversableView */
- protected override def newAppended[B >: A](that: Traversable[B]): Transformed[B] = new Appended[B] { val rest = that }
- protected override def newMapped[B](f: A => B): Transformed[B] = new Mapped[B] { val mapping = f }
- protected override def newFlatMapped[B](f: A => Traversable[B]): Transformed[B] = new FlatMapped[B] { val mapping = f }
- protected override def newFiltered(p: A => Boolean): Transformed[A] = new Filtered { val pred = p }
- protected override def newSliced(_from: Int, _until: Int): Transformed[A] = new Sliced { val from = _from; val until = _until }
- protected override def newDroppedWhile(p: A => Boolean): Transformed[A] = new DroppedWhile { val pred = p }
- protected override def newTakenWhile(p: A => Boolean): Transformed[A] = new TakenWhile { val pred = p }
-
- /** IterableView boilerplate contribution */
- protected def newZipped[B](that: Iterable[B]): Transformed[(A, B)] = new Zipped[B] {
- val other = that
- }
- protected def newZippedAll[A1 >: A, B](that: Iterable[B], _thisElem: A1, _thatElem: B): Transformed[(A1, B)] = new ZippedAll[A1, B] {
- val other: Iterable[B] = that
- val thisElem = _thisElem
- val thatElem = _thatElem
- }
-}
-
-private[collection] trait SeqTransformations[+A, +Coll, +This <: SeqView[A, Coll] with SeqViewLike[A, Coll, This]]
- extends IterableTransformations[A, Coll, This]
-{
- self: SeqViewLike[A, Coll, This] =>
-
- /** Inherited from IterableView */
- protected override def newAppended[B >: A](that: Traversable[B]): Transformed[B] = new Appended[B] { val rest = that }
- protected override def newMapped[B](f: A => B): Transformed[B] = new Mapped[B] { val mapping = f }
- protected override def newFlatMapped[B](f: A => Traversable[B]): Transformed[B] = new FlatMapped[B] { val mapping = f }
- protected override def newFiltered(p: A => Boolean): Transformed[A] = new Filtered { val pred = p }
- protected override def newSliced(_from: Int, _until: Int): Transformed[A] = new Sliced { val from = _from; val until = _until }
- protected override def newDroppedWhile(p: A => Boolean): Transformed[A] = new DroppedWhile { val pred = p }
- protected override def newTakenWhile(p: A => Boolean): Transformed[A] = new TakenWhile { val pred = p }
- protected override def newZipped[B](that: Iterable[B]): Transformed[(A, B)] = new Zipped[B] { val other = that }
- protected override def newZippedAll[A1 >: A, B](that: Iterable[B], _thisElem: A1, _thatElem: B): Transformed[(A1, B)] =
- new ZippedAll[A1, B] { val other = that; val thisElem = _thisElem; val thatElem = _thatElem }
-
- /** SeqView boilerplate contribution */
- protected def newReversed: Transformed[A] = new Reversed { }
- protected def newPatched[B >: A](_from: Int, _patch: Seq[B], _replaced: Int): Transformed[B] =
- new Patched[B] { val from = _from; val patch = _patch; val replaced = _replaced }
-}
-
-private[collection] trait IndexedSeqTransformations[+A, +Coll, +This <: IndexedSeqView[A, Coll] with IndexedSeqViewLike[A, Coll, This]]
- extends SeqTransformations[A, Coll, This]
-{
- self: IndexedSeqViewLike[A, Coll, This] =>
-
- /** Inherited from SeqView */
- protected override def newAppended[B >: A](that: Traversable[B]): Transformed[B] = new Appended[B] { val rest = that }
- protected override def newMapped[B](f: A => B): Transformed[B] = new Mapped[B] { val mapping = f }
- protected override def newFlatMapped[B](f: A => Traversable[B]): Transformed[B] = new FlatMapped[B] { val mapping = f }
- protected override def newFiltered(p: A => Boolean): Transformed[A] = new Filtered { val pred = p }
- protected override def newSliced(_from: Int, _until: Int): Transformed[A] = new Sliced { val from = _from; val until = _until }
- protected override def newDroppedWhile(p: A => Boolean): Transformed[A] = new DroppedWhile { val pred = p }
- protected override def newTakenWhile(p: A => Boolean): Transformed[A] = new TakenWhile { val pred = p }
-
- protected override def newZipped[B](that: Iterable[B]): Transformed[(A, B)] = new Zipped[B] { val other = that }
- protected override def newZippedAll[A1 >: A, B](that: Iterable[B], _thisElem: A1, _thatElem: B): Transformed[(A1, B)] =
- new ZippedAll[A1, B] { val other = that; val thisElem = _thisElem; val thatElem = _thatElem }
- protected override def newReversed: Transformed[A] = new Reversed { }
- protected override def newPatched[B >: A](_from: Int, _patch: Seq[B], _replaced: Int): Transformed[B] =
- new Patched[B] { val from = _from; val patch = _patch; val replaced = _replaced }
-}
diff --git a/src/library/scala/concurrent/MailBox.scala b/src/library/scala/concurrent/MailBox.scala
index 3b00d6165d..c23bbf1c80 100644
--- a/src/library/scala/concurrent/MailBox.scala
+++ b/src/library/scala/concurrent/MailBox.scala
@@ -26,7 +26,7 @@ class MailBox extends AnyRef with ListQueueCreator {
def isDefinedAt(msg: Message): Boolean
}
- private class Receiver[A](receiver: Message =>? A) extends PreReceiver {
+ private class Receiver[A](receiver: PartialFunction[Message, A]) extends PreReceiver {
def isDefinedAt(msg: Message) = receiver.isDefinedAt(msg)
@@ -85,7 +85,7 @@ class MailBox extends AnyRef with ListQueueCreator {
* Block until there is a message in the mailbox for which the processor
* <code>f</code> is defined.
*/
- def receive[A](f: Message =>? A): A = {
+ def receive[A](f: PartialFunction[Message, A]): A = {
val r = new Receiver(f)
scanSentMsgs(r)
r.receive()
@@ -95,7 +95,7 @@ class MailBox extends AnyRef with ListQueueCreator {
* Block until there is a message in the mailbox for which the processor
* <code>f</code> is defined or the timeout is over.
*/
- def receiveWithin[A](msec: Long)(f: Message =>? A): A = {
+ def receiveWithin[A](msec: Long)(f: PartialFunction[Message, A]): A = {
val r = new Receiver(f)
scanSentMsgs(r)
r.receiveWithin(msec)
diff --git a/src/library/scala/io/Source.scala b/src/library/scala/io/Source.scala
index e5cf73ff44..e88bfd0bf1 100644
--- a/src/library/scala/io/Source.scala
+++ b/src/library/scala/io/Source.scala
@@ -313,7 +313,7 @@ abstract class Source extends Iterator[Char]
}
/** The close() method closes the underlying resource. */
- def close: Unit =
+ def close(): Unit =
if (closeFunction != null) closeFunction()
/** The reset() method creates a fresh copy of this Source. */
diff --git a/src/library/scala/math/BigDecimal.scala b/src/library/scala/math/BigDecimal.scala
index 2f3c7f131b..6bd6b33484 100644
--- a/src/library/scala/math/BigDecimal.scala
+++ b/src/library/scala/math/BigDecimal.scala
@@ -100,7 +100,7 @@ object BigDecimal
*/
def apply(x: Array[Char]): BigDecimal = apply(x, defaultMathContext)
def apply(x: Array[Char], mc: MathContext): BigDecimal =
- new BigDecimal(new BigDec(x.toString, mc), mc)
+ new BigDecimal(new BigDec(x.mkString, mc), mc)
/** Translates the decimal String representation of a <code>BigDecimal</code>
* into a <code>BigDecimal</code>.
diff --git a/src/library/scala/package.scala b/src/library/scala/package.scala
index bc5b5d36f2..9fa09e3b72 100644
--- a/src/library/scala/package.scala
+++ b/src/library/scala/package.scala
@@ -64,8 +64,6 @@ package object scala {
type Range = scala.collection.immutable.Range
val Range = scala.collection.immutable.Range
- type =>? [-A, +B] = PartialFunction[A, B]
-
// Migrated from Predef
val $scope = scala.xml.TopScope
diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala
index ebce675347..ecc81c074e 100644
--- a/src/library/scala/runtime/ScalaRunTime.scala
+++ b/src/library/scala/runtime/ScalaRunTime.scala
@@ -100,7 +100,7 @@ object ScalaRunTime {
if (x == null) throw new UninitializedError else x
abstract class Try[+A] {
- def Catch[B >: A](handler: Throwable =>? B): B
+ def Catch[B >: A](handler: PartialFunction[Throwable, B]): B
def Finally(fin: => Unit): A
}
@@ -115,7 +115,7 @@ object ScalaRunTime {
def run() { result = block }
- def Catch[B >: A](handler: Throwable =>? B): B =
+ def Catch[B >: A](handler: PartialFunction[Throwable, B]): B =
if (exception == null) result
else if (handler isDefinedAt exception) handler(exception)
else throw exception
diff --git a/src/library/scala/util/control/Exception.scala b/src/library/scala/util/control/Exception.scala
index 67f9ec183b..356b11df51 100644
--- a/src/library/scala/util/control/Exception.scala
+++ b/src/library/scala/util/control/Exception.scala
@@ -23,14 +23,14 @@ object Exception
// We get lots of crashes using this, so for now we just use Class[_]
// type ExClass = Class[_ <: Throwable]
- type Catcher[+T] = Throwable =>? T
- type ExceptionCatcher[+T] = Exception =>? T
+ type Catcher[+T] = PartialFunction[Throwable, T]
+ type ExceptionCatcher[+T] = PartialFunction[Exception, T]
// due to the magic of contravariance, Throwable => T is a subtype of
// Exception => T, not the other way around. So we manually construct
// a Throwable => T and simply rethrow the non-Exceptions.
implicit def fromExceptionCatcher[T](pf: ExceptionCatcher[T]): Catcher[T] = {
- new (Throwable =>? T) {
+ new PartialFunction[Throwable, T] {
def isDefinedAt(x: Throwable) = x match {
case e: Exception if pf.isDefinedAt(e) => true
case _ => false
@@ -101,7 +101,7 @@ object Exception
/** Create a new Catch with the same isDefinedAt logic as this one,
* but with the supplied apply method replacing the current one. */
def withApply[U](f: (Throwable) => U): Catch[U] = {
- val pf2 = new (Throwable =>? U) {
+ val pf2 = new PartialFunction[Throwable, U] {
def isDefinedAt(x: Throwable) = pf isDefinedAt x
def apply(x: Throwable) = f(x)
}
@@ -139,8 +139,8 @@ object Exception
override def toString() = List("Try(<body>)", catcher.toString) mkString " "
}
- final val nothingCatcher: Throwable =>? Nothing =
- new (Throwable =>? Nothing) {
+ final val nothingCatcher: PartialFunction[Throwable, Nothing] =
+ new PartialFunction[Throwable, Nothing] {
def isDefinedAt(x: Throwable) = false
def apply(x: Throwable) = throw x
}
@@ -207,7 +207,7 @@ object Exception
classes exists (_ isAssignableFrom x.getClass)
private def pfFromExceptions(exceptions: Class[_]*) =
- new (Throwable =>? Nothing) {
+ new PartialFunction[Throwable, Nothing] {
def apply(x: Throwable) = throw x
def isDefinedAt(x: Throwable) = wouldMatch(x, exceptions)
}
diff --git a/src/library/scala/util/parsing/combinator/Parsers.scala b/src/library/scala/util/parsing/combinator/Parsers.scala
index 1205d2f911..3aa7cc7de1 100644
--- a/src/library/scala/util/parsing/combinator/Parsers.scala
+++ b/src/library/scala/util/parsing/combinator/Parsers.scala
@@ -93,7 +93,7 @@ trait Parsers {
* `f' applied to the result of this `ParseResult', packaged up as a new `ParseResult'.
* If `f' is not defined, `Failure'.
*/
- def mapPartial[U](f: T =>? U, error: T => String): ParseResult[U]
+ def mapPartial[U](f: PartialFunction[T, U], error: T => String): ParseResult[U]
def flatMapWithNext[U](f: T => Input => ParseResult[U]): ParseResult[U]
@@ -119,7 +119,7 @@ trait Parsers {
*/
case class Success[+T](result: T, override val next: Input) extends ParseResult[T] {
def map[U](f: T => U) = Success(f(result), next)
- def mapPartial[U](f: T =>? U, error: T => String): ParseResult[U]
+ def mapPartial[U](f: PartialFunction[T, U], error: T => String): ParseResult[U]
= if(f.isDefinedAt(result)) Success(f(result), next)
else Failure(error(result), next)
@@ -146,7 +146,7 @@ trait Parsers {
lastNoSuccess = this
def map[U](f: Nothing => U) = this
- def mapPartial[U](f: Nothing =>? U, error: Nothing => String): ParseResult[U] = this
+ def mapPartial[U](f: PartialFunction[Nothing, U], error: Nothing => String): ParseResult[U] = this
def flatMapWithNext[U](f: Nothing => Input => ParseResult[U]): ParseResult[U]
= this
@@ -345,7 +345,7 @@ trait Parsers {
* @return a parser that succeeds if the current parser succeeds <i>and</i> `f' is applicable
* to the result. If so, the result will be transformed by `f'.
*/
- def ^? [U](f: T =>? U, error: T => String): Parser[U] = Parser{ in =>
+ def ^? [U](f: PartialFunction[T, U], error: T => String): Parser[U] = Parser{ in =>
this(in).mapPartial(f, error)}.named(toString+"^?")
/** A parser combinator for partial function application
@@ -358,7 +358,7 @@ trait Parsers {
* @return a parser that succeeds if the current parser succeeds <i>and</i> `f' is applicable
* to the result. If so, the result will be transformed by `f'.
*/
- def ^? [U](f: T =>? U): Parser[U] = ^?(f, r => "Constructor function not defined at "+r)
+ def ^? [U](f: PartialFunction[T, U]): Parser[U] = ^?(f, r => "Constructor function not defined at "+r)
/** A parser combinator that parameterises a subsequent parser with the result of this one
@@ -495,7 +495,7 @@ trait Parsers {
* @return A parser that succeeds if `f' is applicable to the first element of the input,
* applying `f' to it to produce the result.
*/
- def accept[U](expected: String, f: Elem =>? U): Parser[U] = acceptMatch(expected, f)
+ def accept[U](expected: String, f: PartialFunction[Elem, U]): Parser[U] = acceptMatch(expected, f)
def acceptIf(p: Elem => Boolean)(err: Elem => String): Parser[Elem] = Parser { in =>
@@ -503,7 +503,7 @@ trait Parsers {
else Failure(err(in.first), in)
}
- def acceptMatch[U](expected: String, f: Elem =>? U): Parser[U] = Parser{ in =>
+ def acceptMatch[U](expected: String, f: PartialFunction[Elem, U]): Parser[U] = Parser{ in =>
if (f.isDefinedAt(in.first)) Success(f(in.first), in.rest)
else Failure(expected+" expected", in)
}
diff --git a/src/library/scala/xml/Text.scala b/src/library/scala/xml/Text.scala
index 84e4cbe78f..3090883bb8 100644
--- a/src/library/scala/xml/Text.scala
+++ b/src/library/scala/xml/Text.scala
@@ -13,16 +13,22 @@ package scala.xml
import collection.mutable.StringBuilder
-object Text {
- def apply(data: String) =
- if (data != null) new Text(data)
- else throw new IllegalArgumentException("tried to construct Text with null")
-
- def unapply(other: Any) = other match {
- case x: Text => Some(x.data)
- case _ => None
- }
-}
+// XXX This attempt to make Text not a case class revealed a bug in the pattern
+// matcher (see ticket #2883) so I've put the case back. (It was/is desirable that
+// it not be a case class because it is using the antipattern of passing constructor
+// parameters to the superclass where they become vals, but since they will also be
+// vals in the subclass, it acquires an underscore to avoid a name clash.)
+//
+// object Text {
+// def apply(data: String) =
+// if (data != null) new Text(data)
+// else throw new IllegalArgumentException("tried to construct Text with null")
+//
+// def unapply(other: Any): Option[String] = other match {
+// case x: Text => Some(x.data)
+// case _ => None
+// }
+// }
/** The class <code>Text</code> implements an XML node for text (PCDATA).
* It is used in both non-bound and bound XML representations.
@@ -31,9 +37,9 @@ object Text {
*
* @param text the text contained in this node, may not be null.
*/
-class Text(data: String) extends Atom[String](data)
+case class Text(_data: String) extends Atom[String](_data)
{
- if (data == null)
+ if (_data == null)
throw new IllegalArgumentException("tried to construct Text with null")
/** XXX More hashCode flailing. */
diff --git a/src/library/scala/xml/Utility.scala b/src/library/scala/xml/Utility.scala
index 78c0ee9475..1cfe9c79c9 100644
--- a/src/library/scala/xml/Utility.scala
+++ b/src/library/scala/xml/Utility.scala
@@ -289,9 +289,10 @@ object Utility extends AnyRef with parsing.TokenTests
*/
def getName(s: String, index: Int): String = {
if (index >= s.length) null
- else (s drop index) match {
- case Seq(x, xs @ _*) if isNameStart(x) => x.toString + (xs takeWhile isNameChar).mkString
- case _ => ""
+ else {
+ val xs = s drop index
+ if (xs.nonEmpty && isNameStart(xs.head)) xs takeWhile isNameChar
+ else ""
}
}
diff --git a/src/library/scala/xml/parsing/FactoryAdapter.scala b/src/library/scala/xml/parsing/FactoryAdapter.scala
index 2385f645b5..a83f9677a1 100644
--- a/src/library/scala/xml/parsing/FactoryAdapter.scala
+++ b/src/library/scala/xml/parsing/FactoryAdapter.scala
@@ -135,7 +135,9 @@ abstract class FactoryAdapter extends DefaultHandler with factory.XMLLoader[Node
hStack push null
var m: MetaData = Null
- var scpe: NamespaceBinding = scopeStack.top
+ var scpe: NamespaceBinding =
+ if (scopeStack.isEmpty) TopScope
+ else scopeStack.top
for (i <- 0 until attributes.getLength()) {
val qname = attributes getQName i
diff --git a/src/library/scala/xml/parsing/MarkupParser.scala b/src/library/scala/xml/parsing/MarkupParser.scala
index 2779fe1d7c..a15cd0f7e4 100644
--- a/src/library/scala/xml/parsing/MarkupParser.scala
+++ b/src/library/scala/xml/parsing/MarkupParser.scala
@@ -32,6 +32,7 @@ trait MarkupParser extends MarkupParserCommon with TokenTests
self: MarkupParser with MarkupHandler =>
type PositionType = Int
+ type InputType = Source
def xHandleError(that: Char, msg: String) = reportSyntaxError(msg)
@@ -47,6 +48,15 @@ trait MarkupParser extends MarkupParserCommon with TokenTests
//
var curInput: Source = input
+ def lookahead(): BufferedIterator[Char] = new BufferedIterator[Char] {
+ val stream = curInput.toStream
+ curInput = Source.fromIterable(stream)
+ val underlying = Source.fromIterable(stream).buffered
+
+ def hasNext = underlying.hasNext
+ def next = underlying.next
+ def head = underlying.head
+ }
/** the handler of the markup, returns this */
private val handle: MarkupHandler = this
@@ -57,7 +67,6 @@ trait MarkupParser extends MarkupParserCommon with TokenTests
/** holds the position in the source file */
var pos: Int = _
-
/* used when reading external subset */
var extIndex = -1
@@ -379,20 +388,8 @@ trait MarkupParser extends MarkupParserCommon with TokenTests
*/
def xCharData: NodeSeq = {
xToken("[CDATA[")
- val pos1 = pos
- val sb: StringBuilder = new StringBuilder()
- while (true) {
- if (ch==']' &&
- { sb.append(ch); nextch; ch == ']' } &&
- { sb.append(ch); nextch; ch == '>' } ) {
- sb.setLength(sb.length - 2);
- nextch;
- return PCData(sb.toString)
- } else sb.append( ch );
- nextch;
- }
- // bq: (todo) increase grace when meeting CDATA section
- throw FatalError("this cannot happen");
+ def mkResult(pos: Int, s: String): NodeSeq = PCData(s)
+ xTakeUntil(mkResult, () => pos, "]]>")
}
/** CharRef ::= "&amp;#" '0'..'9' {'0'..'9'} ";"
diff --git a/src/library/scala/xml/parsing/MarkupParserCommon.scala b/src/library/scala/xml/parsing/MarkupParserCommon.scala
index c4ba2ccf15..57c46c4685 100644
--- a/src/library/scala/xml/parsing/MarkupParserCommon.scala
+++ b/src/library/scala/xml/parsing/MarkupParserCommon.scala
@@ -18,9 +18,16 @@ import Utility.Escapes.{ pairs => unescape }
* All members should be accessed through those.
*/
private[scala] trait MarkupParserCommon extends TokenTests {
- // type InputType // Source, CharArrayReader
+ private final val SU: Char = 0x1A
+ protected def unreachable = Predef.error("Cannot be reached.")
+
// type HandleType // MarkupHandler, SymbolicXMLBuilder
- // type PositionType // Int, Position
+
+ type InputType // Source, CharArrayReader
+ type PositionType // Int, Position
+
+ /** Create a lookahead reader which does not influence the input */
+ def lookahead(): BufferedIterator[Char]
def ch: Char
def nextch: Char
@@ -48,4 +55,41 @@ private[scala] trait MarkupParserCommon extends TokenTests {
//
def returning[T](x: T)(f: T => Unit): T = { f(x) ; x }
+
+ /** Take characters from input stream until given String "until"
+ * is seen. Once seen, the accumulated characters are passed
+ * along with the current Position to the supplied handler function.
+ */
+ protected def xTakeUntil[T](
+ handler: (PositionType, String) => T,
+ positioner: () => PositionType,
+ until: String): T =
+ {
+ val sb = new StringBuilder
+ val head = until charAt 0
+ val rest = until drop 1
+
+ while (true) {
+ if (ch == head && peek(rest))
+ return handler(positioner(), sb.toString)
+ else if (ch == SU)
+ xHandleError(ch, "") // throws TruncatedXML in compiler
+
+ sb append ch
+ nextch
+ }
+ unreachable
+ }
+
+ /** Create a non-destructive lookahead reader and see if the head
+ * of the input would match the given String. If yes, return true
+ * and drop the entire String from input; if no, return false
+ * and leave input unchanged.
+ */
+ private def peek(lookingFor: String): Boolean =
+ (lookahead() take lookingFor.length sameElements lookingFor.iterator) && {
+ // drop the chars from the real reader (all lookahead + orig)
+ (0 to lookingFor.length) foreach (_ => nextch)
+ true
+ }
}