summaryrefslogtreecommitdiff
path: root/src/library
diff options
context:
space:
mode:
authorVojin Jovanovic <vojin.jovanovic@epfl.ch>2012-01-25 15:24:18 +0100
committerVojin Jovanovic <vojin.jovanovic@epfl.ch>2012-01-25 15:24:18 +0100
commitf814d40ea917592f78d2e8ca4c78f34ce4b5f297 (patch)
treecafac6a0d757419132fd75ab788f8163a619780b /src/library
parent85daadef89a9ed5c3901a5822221366ee6746d49 (diff)
parentde2b0c68785afc0f801fbe8d2750366e90c9fa70 (diff)
downloadscala-f814d40ea917592f78d2e8ca4c78f34ce4b5f297.tar.gz
scala-f814d40ea917592f78d2e8ca4c78f34ce4b5f297.tar.bz2
scala-f814d40ea917592f78d2e8ca4c78f34ce4b5f297.zip
Merge branch 'master' into execution-context
Diffstat (limited to 'src/library')
-rw-r--r--src/library/scala/Function1.scala10
-rw-r--r--src/library/scala/PartialFunction.scala30
-rw-r--r--src/library/scala/Predef.scala2
-rw-r--r--src/library/scala/StringContext.scala191
-rw-r--r--src/library/scala/collection/GenTraversableLike.scala23
-rw-r--r--src/library/scala/collection/GenTraversableOnce.scala2
-rwxr-xr-xsrc/library/scala/collection/JavaConverters.scala5
-rw-r--r--src/library/scala/collection/SeqLike.scala2
-rw-r--r--src/library/scala/collection/TraversableLike.scala5
-rw-r--r--src/library/scala/collection/TraversableOnce.scala2
-rw-r--r--src/library/scala/collection/TraversableProxyLike.scala2
-rw-r--r--src/library/scala/collection/generic/GenericTraversableTemplate.scala14
-rw-r--r--src/library/scala/collection/generic/MutableSortedSetFactory.scala33
-rw-r--r--src/library/scala/collection/generic/TraversableForwarder.scala2
-rw-r--r--src/library/scala/collection/immutable/IndexedSeq.scala2
-rw-r--r--src/library/scala/collection/immutable/List.scala21
-rw-r--r--src/library/scala/collection/immutable/Range.scala36
-rw-r--r--src/library/scala/collection/immutable/Stream.scala10
-rw-r--r--src/library/scala/collection/interfaces/TraversableOnceMethods.scala2
-rw-r--r--src/library/scala/collection/mutable/AVLTree.scala206
-rw-r--r--src/library/scala/collection/mutable/ListBuffer.scala46
-rw-r--r--src/library/scala/collection/mutable/SortedSet.scala49
-rw-r--r--src/library/scala/collection/mutable/TreeSet.scala123
-rw-r--r--src/library/scala/collection/parallel/ParIterableLike.scala2
-rw-r--r--src/library/scala/io/Codec.scala3
-rw-r--r--src/library/scala/reflect/Manifest.scala2
-rw-r--r--src/library/scala/reflect/ReflectionUtils.scala12
-rw-r--r--src/library/scala/reflect/api/Mirror.scala6
-rwxr-xr-xsrc/library/scala/reflect/api/Symbols.scala4
-rw-r--r--src/library/scala/reflect/api/TreePrinters.scala41
-rw-r--r--src/library/scala/reflect/macro/Context.scala (renamed from src/library/scala/reflect/api/MacroContext.scala)6
-rw-r--r--src/library/scala/reflect/package.scala2
-rw-r--r--src/library/scala/xml/include/sax/Main.scala2
33 files changed, 837 insertions, 61 deletions
diff --git a/src/library/scala/Function1.scala b/src/library/scala/Function1.scala
index dc8e67bbb0..7517e6604b 100644
--- a/src/library/scala/Function1.scala
+++ b/src/library/scala/Function1.scala
@@ -24,10 +24,18 @@ package scala
* assert(succ(0) == anonfun1(0))
* }
* }}}
+ *
+ * Note that `Function1` does not define a total function, as might
+ * be suggested by the existence of [[scala.PartialFunction]]. The only
+ * distinction between `Function1` and `PartialFunction` is that the
+ * latter can specify inputs which it will not handle.
+ *
*/
@annotation.implicitNotFound(msg = "No implicit view available from ${T1} => ${R}.")
trait Function1[@specialized(scala.Int, scala.Long, scala.Float, scala.Double) -T1, @specialized(scala.Unit, scala.Boolean, scala.Int, scala.Float, scala.Long, scala.Double) +R] extends AnyRef { self =>
- /** Apply the body of this function to the argument.
+ /** Apply the body of this function to the argument. It may throw an
+ * exception.
+ *
* @return the result of function application.
*/
def apply(v1: T1): R
diff --git a/src/library/scala/PartialFunction.scala b/src/library/scala/PartialFunction.scala
index b2910c2278..70caff0221 100644
--- a/src/library/scala/PartialFunction.scala
+++ b/src/library/scala/PartialFunction.scala
@@ -13,6 +13,36 @@ package scala
* The function `isDefinedAt` allows to test dynamically if a value is in
* the domain of the function.
*
+ * Even if `isDefinedAt` returns true for an `a: A`, calling `apply(a)` may
+ * still throw an exception, so the following code is legal:
+ *
+ * {{{
+ * val f: PartialFunction[Int, Any] = { case _ => 1/0 }
+ * }}}
+ *
+ * The main distinction between `PartialFunction` and [[scala.Function1]] is
+ * that the user of a `PartialFunction` may choose to do something different
+ * with input that is declared to be outside its domain. For example:
+ *
+ * {{{
+ * val sample = 1 to 10
+ * val isEven: PartialFunction[Int, String] = {
+ * case x if x % 2 == 0 => x+" is even"
+ * }
+ *
+ * // the method collect can use isDefinedAt to select which members to collect
+ * val evenNumbers = sample collect isEven
+ *
+ * val isOdd: PartialFunction[Int, String] = {
+ * case x if x % 2 == 1 => x+" is odd"
+ * }
+ *
+ * // the method orElse allows chaining another partial function to handle
+ * // input outside the declared domain
+ * val numbers = sample map (isEven orElse isOdd)
+ * }}}
+ *
+ *
* @author Martin Odersky
* @version 1.0, 16/07/2003
*/
diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala
index b175fb9e1d..824e048e73 100644
--- a/src/library/scala/Predef.scala
+++ b/src/library/scala/Predef.scala
@@ -269,7 +269,7 @@ object Predef extends LowPriorityImplicits {
def printf(text: String, xs: Any*) = Console.print(text.format(xs: _*))
def readLine(): String = Console.readLine()
- def readLine(text: String, args: Any*) = Console.readLine(text, args)
+ def readLine(text: String, args: Any*) = Console.readLine(text, args: _*)
def readBoolean() = Console.readBoolean()
def readByte() = Console.readByte()
def readShort() = Console.readShort()
diff --git a/src/library/scala/StringContext.scala b/src/library/scala/StringContext.scala
new file mode 100644
index 0000000000..6116547aa2
--- /dev/null
+++ b/src/library/scala/StringContext.scala
@@ -0,0 +1,191 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2012, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala
+
+import collection.mutable.ArrayBuffer
+
+/** A class to support string interpolation.
+ * This class supports string interpolation as outlined in Scala SIP-11.
+ * It needs to be fully documented once the SIP is accepted.
+ *
+ * @param parts The parts that make up the interpolated string,
+ * without the expressions that get inserted by interpolation.
+ */
+case class StringContext(parts: String*) {
+
+ import StringContext._
+
+ /** Checks that the given arguments `args` number one less than the number
+ * of `parts` supplied to the enclosing `StringContext`.
+ * @param `args` The arguments to be checked.
+ * @throws An `IllegalArgumentException` if this is not the case.
+ */
+ def checkLengths(args: Any*): Unit =
+ if (parts.length != args.length + 1)
+ throw new IllegalArgumentException("wrong number of arguments for interpolated string")
+
+
+ /** The simple string interpolator.
+ *
+ * It inserts its arguments between corresponding parts of the string context.
+ * It also treats standard escape sequences as defined in the Scala specification.
+ * @param `args` The arguments to be inserted into the resulting string.
+ * @throws An `IllegalArgumentException`
+ * if the number of `parts` in the enclosing `StringContext` does not exceed
+ * the number of arguments `arg` by exactly 1.
+ * @throws A `StringContext.InvalidEscapeException` if if a `parts` string contains a backslash (`\`) character
+ * that does not start a valid escape sequence.
+ */
+ def s(args: Any*) = {
+ checkLengths(args: _*)
+ val pi = parts.iterator
+ val ai = args.iterator
+ val bldr = new java.lang.StringBuilder(treatEscapes(pi.next))
+ while (ai.hasNext) {
+ bldr append ai.next
+ bldr append treatEscapes(pi.next)
+ }
+ bldr.toString
+ }
+
+ /** The formatted string interpolator.
+ *
+ * It inserts its arguments between corresponding parts of the string context.
+ * It also treats standard escape sequences as defined in the Scala specification.
+ * Finally, if an interpolated expression is followed by a `parts` string
+ * that starts with a formatting specifier, the expression is formatted according to that
+ * specifier. All specifiers allowed in Java format strings are handled, and in the same
+ * way they are treated in Java.
+ *
+ * @param `args` The arguments to be inserted into the resulting string.
+ * @throws An `IllegalArgumentException`
+ * if the number of `parts` in the enclosing `StringContext` does not exceed
+ * the number of arguments `arg` by exactly 1.
+ * @throws A `StringContext.InvalidEscapeException` if a `parts` string contains a backslash (`\`) character
+ * that does not start a valid escape sequence.
+ *
+ * Note: The `f` method works by assembling a format string from all the `parts` strings and using
+ * `java.lang.String.format` to format all arguments with that format string. The format string is
+ * obtained by concatenating all `parts` strings, and performing two transformations:
+ *
+ * 1. Let a _formatting position_ be a start of any `parts` string except the first one.
+ * If a formatting position does not refer to a `%` character (which is assumed to
+ * start a format specifier), then the string format specifier `%s` is inserted.
+ *
+ * 2. Any `%` characters not in formatting positions are left in the resulting
+ * string literally. This is achieved by replacing each such occurrence by a string
+ * format specifier `%s` and adding a corresponding argument string `"%"`.
+ */
+ def f(args: Any*) = {
+ checkLengths(args: _*)
+ val pi = parts.iterator
+ val ai = args.iterator
+ val bldr = new java.lang.StringBuilder
+ val args1 = new ArrayBuffer[Any]
+ def copyString(first: Boolean): Unit = {
+ val str = treatEscapes(pi.next)
+ var start = 0
+ var idx = 0
+ if (!first) {
+ if ((str charAt 0) != '%')
+ bldr append "%s"
+ idx = 1
+ }
+ val len = str.length
+ while (idx < len) {
+ if (str(idx) == '%') {
+ bldr append (str substring (start, idx)) append "%s"
+ args1 += "%"
+ start = idx + 1
+ }
+ idx += 1
+ }
+ bldr append (str substring (start, idx))
+ }
+ copyString(first = true)
+ while (pi.hasNext) {
+ args1 += ai.next
+ copyString(first = false)
+ }
+ bldr.toString format (args1: _*)
+ }
+}
+
+object StringContext {
+
+ /** An exception that is thrown if a string contains a backslash (`\`) character that
+ * that does not start a valid escape sequence.
+ * @param str The offending string
+ * @param idx The index of the offending backslash character in `str`.
+ */
+ class InvalidEscapeException(str: String, idx: Int)
+ extends IllegalArgumentException("invalid escape character at index "+idx+" in \""+str+"\"")
+
+ /** Expands standard Scala escape sequences in a string.
+ * Escape sequences are:
+ * control: `\b`, `\t`, `\n`, `\f`, `\r`
+ * escape: `\\`, `\"`, `\'`
+ * octal: `\d` `\dd` `\ddd` where `d` is an octal digit between `0` and `7`.
+ *
+ * @param A string that may contain escape sequences
+ * @return The string with all escape sequences expanded.
+ */
+ def treatEscapes(str: String): String = {
+ lazy val bldr = new java.lang.StringBuilder
+ val len = str.length
+ var start = 0
+ var cur = 0
+ var idx = 0
+ def output(ch: Char) = {
+ bldr append str substring (start, cur)
+ bldr append ch
+ start = idx
+ }
+ while (idx < len) {
+ cur = idx
+ if (str(idx) == '\\') {
+ idx += 1
+ if ('0' <= str(idx) && str(idx) <= '7') {
+ val leadch = str(idx)
+ var oct = leadch - '0'
+ idx += 1
+ if ('0' <= str(idx) && str(idx) <= '7') {
+ oct = oct * 8 + str(idx) - '0'
+ idx += 1
+ if (leadch <= '3' && '0' <= str(idx) && str(idx) <= '7') {
+ oct = oct * 8 + str(idx) - '0'
+ idx += 1
+ }
+ }
+ output(oct.toChar)
+ } else {
+ val ch = str(idx)
+ idx += 1
+ output {
+ ch match {
+ case 'b' => '\b'
+ case 't' => '\t'
+ case 'n' => '\n'
+ case 'f' => '\f'
+ case 'r' => '\r'
+ case '\"' => '\"'
+ case '\'' => '\''
+ case '\\' => '\\'
+ case _ => throw new InvalidEscapeException(str, cur)
+ }
+ }
+ }
+ } else {
+ idx += 1
+ }
+ }
+ if (start == 0) str
+ else (bldr append str.substring(start, idx)).toString
+ }
+}
diff --git a/src/library/scala/collection/GenTraversableLike.scala b/src/library/scala/collection/GenTraversableLike.scala
index 122eec2d90..c837775cf9 100644
--- a/src/library/scala/collection/GenTraversableLike.scala
+++ b/src/library/scala/collection/GenTraversableLike.scala
@@ -177,7 +177,28 @@ trait GenTraversableLike[+A, +Repr] extends GenTraversableOnce[A] with Paralleli
def collect[B, That](pf: PartialFunction[A, B])(implicit bf: CanBuildFrom[Repr, B, That]): That
/** Builds a new collection by applying a function to all elements of this $coll
- * and concatenating the results.
+ * and using the elements of the resulting collections. For example:
+ *
+ * {{{
+ * def getWords(lines: Seq[String]): Seq[String] = lines flatMap (line => line split "\\W+")
+ * }}}
+ *
+ * The type of the resulting collection is guided by the static type of $coll. This might
+ * cause unexpected results sometimes. For example:
+ *
+ * {{{
+ * // lettersOf will return a Seq[Char] of likely repeated letters, instead of a Set
+ * def lettersOf(words: Seq[String]) = words flatMap (word => word.toSet)
+ *
+ * // lettersOf will return a Set[Char], not a Seq
+ * def lettersOf(words: Seq[String]) = words.toSet flatMap (word => word.toSeq)
+ *
+ * // xs will be a an Iterable[Int]
+ * val xs = Map("a" -> List(11,111), "b" -> List(22,222)).flatMap(_._2)
+ *
+ * // ys will be a Map[Int, Int]
+ * val ys = Map("a" -> List(1 -> 11,1 -> 111), "b" -> List(2 -> 22,2 -> 222)).flatMap(_._2)
+ * }}}
*
* @param f the function to apply to each element.
* @tparam B the element type of the returned collection.
diff --git a/src/library/scala/collection/GenTraversableOnce.scala b/src/library/scala/collection/GenTraversableOnce.scala
index 3e42e7812b..305f8d768d 100644
--- a/src/library/scala/collection/GenTraversableOnce.scala
+++ b/src/library/scala/collection/GenTraversableOnce.scala
@@ -471,7 +471,7 @@ trait GenTraversableOnce[+A] {
* $willNotTerminateInf
* @return an indexed sequence containing all elements of this $coll.
*/
- def toIndexedSeq[A1 >: A]: immutable.IndexedSeq[A1]
+ def toIndexedSeq: immutable.IndexedSeq[A]
/** Converts this $coll to a stream.
* $willNotTerminateInf
diff --git a/src/library/scala/collection/JavaConverters.scala b/src/library/scala/collection/JavaConverters.scala
index 94f7e9701b..d213e60112 100755
--- a/src/library/scala/collection/JavaConverters.scala
+++ b/src/library/scala/collection/JavaConverters.scala
@@ -48,7 +48,8 @@ package scala.collection
* @author Martin Odersky
* @since 2.8.1
*/
-object JavaConverters {
+
+trait JavaConverters {
import java.{ lang => jl, util => ju }
import java.util.{ concurrent => juc }
import JavaConversions._
@@ -536,3 +537,5 @@ object JavaConverters {
propertiesAsScalaMapConverter(p)
}
+
+object JavaConverters extends JavaConverters \ No newline at end of file
diff --git a/src/library/scala/collection/SeqLike.scala b/src/library/scala/collection/SeqLike.scala
index b6b4bfb96d..6d84b4276b 100644
--- a/src/library/scala/collection/SeqLike.scala
+++ b/src/library/scala/collection/SeqLike.scala
@@ -152,7 +152,7 @@ trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] with GenSeqLike[A, Repr]
if (!hasNext)
Iterator.empty.next
- val result = (self.newBuilder ++= elms).result
+ val result = (self.newBuilder ++= elms.toList).result
var i = idxs.length - 2
while(i >= 0 && idxs(i) >= idxs(i+1))
i -= 1
diff --git a/src/library/scala/collection/TraversableLike.scala b/src/library/scala/collection/TraversableLike.scala
index e2acc0b3e0..36d45c0c8a 100644
--- a/src/library/scala/collection/TraversableLike.scala
+++ b/src/library/scala/collection/TraversableLike.scala
@@ -535,7 +535,7 @@ trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr]
val b = newBuilder
var go = false
for (x <- this) {
- if (!p(x)) go = true
+ if (!go && !p(x)) go = true
if (go) b += x
}
b.result
@@ -709,6 +709,9 @@ trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr]
* outer $coll containing this `WithFilter` instance that satisfy
* predicate `p` and concatenating the results.
*
+ * The type of the resulting collection will be guided by the static type
+ * of the outer $coll.
+ *
* @param f the function to apply to each element.
* @tparam B the element type of the returned collection.
* @tparam That $thatinfo
diff --git a/src/library/scala/collection/TraversableOnce.scala b/src/library/scala/collection/TraversableOnce.scala
index 908c4c808d..5bb2e563f6 100644
--- a/src/library/scala/collection/TraversableOnce.scala
+++ b/src/library/scala/collection/TraversableOnce.scala
@@ -245,7 +245,7 @@ trait TraversableOnce[+A] extends GenTraversableOnce[A] {
def toSeq: Seq[A] = toStream
- def toIndexedSeq[B >: A]: immutable.IndexedSeq[B] = immutable.IndexedSeq() ++ seq
+ def toIndexedSeq: immutable.IndexedSeq[A] = immutable.IndexedSeq() ++ seq
def toBuffer[B >: A]: mutable.Buffer[B] = new ArrayBuffer[B] ++= seq
diff --git a/src/library/scala/collection/TraversableProxyLike.scala b/src/library/scala/collection/TraversableProxyLike.scala
index 15565e57c6..e7e797391e 100644
--- a/src/library/scala/collection/TraversableProxyLike.scala
+++ b/src/library/scala/collection/TraversableProxyLike.scala
@@ -77,7 +77,7 @@ trait TraversableProxyLike[+A, +Repr <: TraversableLike[A, Repr] with Traversabl
override def toList: List[A] = self.toList
override def toIterable: Iterable[A] = self.toIterable
override def toSeq: Seq[A] = self.toSeq
- override def toIndexedSeq[B >: A] = self.toIndexedSeq
+ override def toIndexedSeq: immutable.IndexedSeq[A] = self.toIndexedSeq
override def toBuffer[B >: A] = self.toBuffer
override def toStream: Stream[A] = self.toStream
override def toSet[B >: A]: immutable.Set[B] = self.toSet
diff --git a/src/library/scala/collection/generic/GenericTraversableTemplate.scala b/src/library/scala/collection/generic/GenericTraversableTemplate.scala
index 12c1a75c7a..7333074778 100644
--- a/src/library/scala/collection/generic/GenericTraversableTemplate.scala
+++ b/src/library/scala/collection/generic/GenericTraversableTemplate.scala
@@ -116,7 +116,19 @@ trait GenericTraversableTemplate[+A, +CC[X] <: GenTraversable[X]] extends HasNew
}
/** Converts this $coll of traversable collections into
- * a $coll in which all element collections are concatenated.
+ * a $coll formed by the elements of these traversable
+ * collections.
+ *
+ * The resulting collection's type will be guided by the
+ * static type of $coll. For example:
+ *
+ * {{{
+ * val xs = List(Set(1, 2, 3), Set(1, 2, 3))
+ * // xs == List(1, 2, 3, 1, 2, 3)
+ *
+ * val ys = Set(List(1, 2, 3), List(3, 2, 1))
+ * // ys == Set(1, 2, 3)
+ * }}}
*
* @tparam B the type of the elements of each traversable collection.
* @param asTraversable an implicit conversion which asserts that the element
diff --git a/src/library/scala/collection/generic/MutableSortedSetFactory.scala b/src/library/scala/collection/generic/MutableSortedSetFactory.scala
new file mode 100644
index 0000000000..b235379575
--- /dev/null
+++ b/src/library/scala/collection/generic/MutableSortedSetFactory.scala
@@ -0,0 +1,33 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.collection
+package generic
+
+import scala.collection.mutable.{ Builder, GrowingBuilder }
+
+/**
+ * @define Coll mutable.SortedSet
+ * @define coll mutable sorted
+ *
+ * @author Lucien Pereira
+ *
+ */
+abstract class MutableSortedSetFactory[CC[A] <: mutable.SortedSet[A] with SortedSetLike[A, CC[A]] with mutable.Set[A] with mutable.SetLike[A, CC[A]]] extends SortedSetFactory[CC] {
+
+ /**
+ * mutable.SetBuilder uses '+' which is not a primitive for anything extending mutable.SetLike,
+ * this causes serious perfomances issues since each time 'elems = elems + x'
+ * is evaluated elems is cloned (which is O(n)).
+ *
+ * Fortunately GrowingBuilder comes to rescue.
+ *
+ */
+ override def newBuilder[A](implicit ord: Ordering[A]): Builder[A, CC[A]] = new GrowingBuilder[A, CC[A]](empty)
+
+}
diff --git a/src/library/scala/collection/generic/TraversableForwarder.scala b/src/library/scala/collection/generic/TraversableForwarder.scala
index 6529fe4a79..3d723a1feb 100644
--- a/src/library/scala/collection/generic/TraversableForwarder.scala
+++ b/src/library/scala/collection/generic/TraversableForwarder.scala
@@ -61,7 +61,7 @@ trait TraversableForwarder[+A] extends Traversable[A] {
override def toList: List[A] = underlying.toList
override def toIterable: Iterable[A] = underlying.toIterable
override def toSeq: Seq[A] = underlying.toSeq
- override def toIndexedSeq[B >: A] = underlying.toIndexedSeq
+ override def toIndexedSeq = underlying.toIndexedSeq
override def toBuffer[B >: A] = underlying.toBuffer
override def toStream: Stream[A] = underlying.toStream
override def toSet[B >: A]: immutable.Set[B] = underlying.toSet
diff --git a/src/library/scala/collection/immutable/IndexedSeq.scala b/src/library/scala/collection/immutable/IndexedSeq.scala
index bbbef158af..e3939001d8 100644
--- a/src/library/scala/collection/immutable/IndexedSeq.scala
+++ b/src/library/scala/collection/immutable/IndexedSeq.scala
@@ -22,7 +22,7 @@ trait IndexedSeq[+A] extends Seq[A]
with GenericTraversableTemplate[A, IndexedSeq]
with IndexedSeqLike[A, IndexedSeq[A]] {
override def companion: GenericCompanion[IndexedSeq] = IndexedSeq
- override def toIndexedSeq[B >: A]: IndexedSeq[B] = this
+ override def toIndexedSeq: IndexedSeq[A] = this
override def seq: IndexedSeq[A] = this
}
diff --git a/src/library/scala/collection/immutable/List.scala b/src/library/scala/collection/immutable/List.scala
index c6f056bd81..e9ecc75e0f 100644
--- a/src/library/scala/collection/immutable/List.scala
+++ b/src/library/scala/collection/immutable/List.scala
@@ -316,28 +316,7 @@ final case class ::[B](private var hd: B, private[scala] var tl: List[B]) extend
override def tail : List[B] = tl
override def isEmpty: Boolean = false
- import java.io._
- private def writeObject(out: ObjectOutputStream) {
- var xs: List[B] = this
- while (!xs.isEmpty) { out.writeObject(xs.head); xs = xs.tail }
- out.writeObject(ListSerializeEnd)
- }
-
- private def readObject(in: ObjectInputStream) {
- hd = in.readObject.asInstanceOf[B]
- assert(hd != ListSerializeEnd)
- var current: ::[B] = this
- while (true) in.readObject match {
- case ListSerializeEnd =>
- current.tl = Nil
- return
- case a : Any =>
- val list : ::[B] = new ::(a.asInstanceOf[B], Nil)
- current.tl = list
- current = list
- }
- }
}
/** $factoryInfo
diff --git a/src/library/scala/collection/immutable/Range.scala b/src/library/scala/collection/immutable/Range.scala
index c92c0268b6..7537558f0b 100644
--- a/src/library/scala/collection/immutable/Range.scala
+++ b/src/library/scala/collection/immutable/Range.scala
@@ -286,18 +286,36 @@ extends collection.AbstractSeq[Int]
object Range {
private[immutable] val MAX_PRINT = 512 // some arbitrary value
- /** Counts in "Long arithmetic" so we can recognize overflow.
+ /** Counts the number of range elements.
+ * @pre step != 0
+ * If the size of the range exceeds Int.MaxValue, the
+ * result will be negative.
*/
- def count(start: Int, end: Int, step: Int): Int =
- count(start, end, step, false)
-
def count(start: Int, end: Int, step: Int, isInclusive: Boolean): Int = {
- // faster path for the common counting range
- if (start >= 0 && end > start && end < scala.Int.MaxValue && step == 1)
- (end - start) + ( if (isInclusive) 1 else 0 )
- else
- NumericRange.count[Long](start, end, step, isInclusive)
+ if (step == 0)
+ throw new IllegalArgumentException("step cannot be 0.")
+
+ val isEmpty = (
+ if (start == end) !isInclusive
+ else if (start < end) step < 0
+ else step > 0
+ )
+ if (isEmpty) 0
+ else {
+ // Counts with Longs so we can recognize too-large ranges.
+ val gap: Long = end.toLong - start.toLong
+ val jumps: Long = gap / step
+ // Whether the size of this range is one larger than the
+ // number of full-sized jumps.
+ val hasStub = isInclusive || (gap % step != 0)
+ val result: Long = jumps + ( if (hasStub) 1 else 0 )
+
+ if (result > scala.Int.MaxValue) -1
+ else result.toInt
+ }
}
+ def count(start: Int, end: Int, step: Int): Int =
+ count(start, end, step, false)
class Inclusive(start: Int, end: Int, step: Int) extends Range(start, end, step) {
// override def par = new ParRange(this)
diff --git a/src/library/scala/collection/immutable/Stream.scala b/src/library/scala/collection/immutable/Stream.scala
index e6587f9615..2eb2f8eb09 100644
--- a/src/library/scala/collection/immutable/Stream.scala
+++ b/src/library/scala/collection/immutable/Stream.scala
@@ -929,13 +929,19 @@ self =>
/** A specialized, extra-lazy implementation of a stream iterator, so it can
* iterate as lazily as it traverses the tail.
*/
-final class StreamIterator[+A](self: Stream[A]) extends AbstractIterator[A] with Iterator[A] {
+final class StreamIterator[+A] private() extends AbstractIterator[A] with Iterator[A] {
+ def this(self: Stream[A]) {
+ this()
+ these = new LazyCell(self)
+ }
+
// A call-by-need cell.
class LazyCell(st: => Stream[A]) {
lazy val v = st
}
- private var these = new LazyCell(self)
+ private var these: LazyCell = _
+
def hasNext: Boolean = these.v.nonEmpty
def next(): A =
if (isEmpty) Iterator.empty.next
diff --git a/src/library/scala/collection/interfaces/TraversableOnceMethods.scala b/src/library/scala/collection/interfaces/TraversableOnceMethods.scala
index 5e1325fef6..471e977134 100644
--- a/src/library/scala/collection/interfaces/TraversableOnceMethods.scala
+++ b/src/library/scala/collection/interfaces/TraversableOnceMethods.scala
@@ -48,7 +48,7 @@ trait TraversableOnceMethods[+A] {
// conversions
def toArray[B >: A : ClassManifest]: Array[B]
def toBuffer[B >: A]: mutable.Buffer[B]
- def toIndexedSeq[B >: A]: immutable.IndexedSeq[B]
+ def toIndexedSeq: immutable.IndexedSeq[A]
def toIterable: Iterable[A]
def toIterator: Iterator[A]
def toList: List[A]
diff --git a/src/library/scala/collection/mutable/AVLTree.scala b/src/library/scala/collection/mutable/AVLTree.scala
new file mode 100644
index 0000000000..0cf6cb06e5
--- /dev/null
+++ b/src/library/scala/collection/mutable/AVLTree.scala
@@ -0,0 +1,206 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.collection
+package mutable
+
+import annotation.tailrec
+
+/**
+ * An immutable AVL Tree implementation used by mutable.TreeSet
+ *
+ * @author Lucien Pereira
+ *
+ */
+private[mutable] sealed trait AVLTree[+A] extends Serializable {
+ def balance: Int
+
+ def depth: Int
+
+}
+
+private case class Node[A](val data: A, val left: AVLTree[A], val right: AVLTree[A]) extends AVLTree[A] {
+ override val balance: Int = right.depth - left.depth
+
+ override val depth: Int = math.max(left.depth, right.depth) + 1
+
+}
+
+private case object Leaf extends AVLTree[Nothing] {
+ override val balance: Int = 0
+
+ override val depth: Int = -1
+
+}
+
+private[mutable] object AVLTree {
+
+ /**
+ * Returns a new tree containing the given element.
+ * Thows an IllegalArgumentException if element is already present.
+ *
+ */
+ def insert[A](value: A, tree: AVLTree[A], ordering: Ordering[A]): AVLTree[A] = {
+ @tailrec
+ def insertTC(value: A, tree: AVLTree[A], reassemble: AVLTree[A] => AVLTree[A]): AVLTree[A] = tree match {
+ case Leaf => reassemble(Node(value, Leaf, Leaf))
+
+ case Node(a, left, right) => if (0 == ordering.compare(value, a)) {
+ throw new IllegalArgumentException()
+ } else if (-1 == ordering.compare(value, a)) {
+ insertTC(value, left, x => reassemble(rebalance(Node(a, x, right))))
+ } else {
+ insertTC(value, right, x => reassemble(rebalance(Node(a, left, x))))
+ }
+ }
+
+ insertTC(value, tree, x => rebalance(x))
+ }
+
+ def contains[A](value: A, tree: AVLTree[A], ordering: Ordering[A]): Boolean = tree match {
+ case Leaf => false
+
+ case Node(a, left, right) => if (0 == ordering.compare(value, a)) {
+ true
+ } else if (-1 == ordering.compare(value, a)) {
+ contains(value, left, ordering)
+ } else {
+ contains(value, right, ordering)
+ }
+ }
+
+ /**
+ * Return a new tree which not contains given element.
+ *
+ */
+ def remove[A](value: A, tree: AVLTree[A], ordering: Ordering[A]): AVLTree[A] = tree match {
+ case Leaf => throw new NoSuchElementException()
+
+ case Node(a, Leaf, Leaf) => if (0 == ordering.compare(value, a)) {
+ Leaf
+ } else {
+ throw new NoSuchElementException()
+ }
+
+ case Node(a, left, right@Node(_, _, _)) => if (0 == ordering.compare(value, a)) {
+ val (min, newRight) = removeMin(right)
+ rebalance(Node(min, left, newRight))
+ } else if (-1 == ordering.compare(value, a)) {
+ rebalance(Node(a, remove(value, left, ordering), right))
+ } else {
+ rebalance(Node(a, left, remove(value, right, ordering)))
+ }
+
+ case Node(a, left@Node(_, _, _), right) => if (0 == ordering.compare(value, a)) {
+ val (max, newLeft) = removeMax(left)
+ rebalance(Node(max, newLeft, right))
+ } else if (-1 == ordering.compare(value, a)) {
+ rebalance(Node(a, remove(value, left, ordering), right))
+ } else {
+ rebalance(Node(a, left, remove(value, right, ordering)))
+ }
+ }
+
+ /**
+ * Return a tuple containing the biggest element of the provided tree
+ * and a new tree from which this element has been extracted.
+ *
+ */
+ def removeMax[A](tree: Node[A]): (A, AVLTree[A]) = {
+ @tailrec
+ def removeMaxTC(tree: AVLTree[A], assemble: (A, AVLTree[A]) => (A, AVLTree[A])): (A, AVLTree[A]) = tree match {
+ case Node(a, Leaf, Leaf) => assemble(a, Leaf)
+ case Node(a, left, Leaf) => assemble(a, left)
+ case Node(a, left, right) => removeMaxTC(right,
+ (max: A, avl: AVLTree[A]) => assemble(max, rebalance(Node(a, left, avl))))
+ case Leaf => sys.error("Should not happen.")
+ }
+
+ removeMaxTC(tree, (a, b) => (a, b))
+ }
+
+ /**
+ * Return a tuple containing the smallest element of the provided tree
+ * and a new tree from which this element has been extracted.
+ *
+ */
+ def removeMin[A](tree: Node[A]): (A, AVLTree[A]) = {
+ @tailrec
+ def removeMinTC(tree: AVLTree[A], assemble: (A, AVLTree[A]) => (A, AVLTree[A])): (A, AVLTree[A]) = tree match {
+ case Node(a, Leaf, Leaf) => assemble(a, Leaf)
+ case Node(a, Leaf, right) => assemble(a, right)
+ case Node(a, left, right) => removeMinTC(left,
+ (min: A, avl: AVLTree[A]) => assemble(min, rebalance(Node(a, avl, right))))
+ case Leaf => sys.error("Should not happen.")
+ }
+
+ removeMinTC(tree, (a, b) => (a, b))
+ }
+
+ /**
+ * Returns a bounded stream of elements in the tree.
+ *
+ */
+ def toStream[A](tree: AVLTree[A], isLeftAcceptable: A => Boolean, isRightAcceptable: A => Boolean): Stream[A] = tree match {
+ case Leaf => Stream.empty
+
+ case Node(a, left, right) => if (isLeftAcceptable(a)) {
+ if (isRightAcceptable(a)) {
+ toStream(left, isLeftAcceptable, isRightAcceptable) ++ Stream(a) ++ toStream(right, isLeftAcceptable, isRightAcceptable)
+ } else {
+ toStream(left, isLeftAcceptable, isRightAcceptable)
+ }
+ } else if (isRightAcceptable(a)) {
+ toStream(right, isLeftAcceptable, isRightAcceptable)
+ } else {
+ Stream.empty
+ }
+ }
+
+ /**
+ * Returns a bounded iterator of elements in the tree.
+ *
+ */
+ def iterator[A](tree: AVLTree[A], isLeftAcceptable: A => Boolean, isRightAcceptable: A => Boolean): Iterator[A] =
+ toStream(tree, isLeftAcceptable, isRightAcceptable).iterator
+
+ def rebalance[A](tree: AVLTree[A]): AVLTree[A] = (tree, tree.balance) match {
+ case (node@Node(_, left, _), -2) => left.balance match {
+ case 1 => doubleRightRotation(node)
+ case _ => rightRotation(node)
+ }
+
+ case (node@Node(_, _, right), 2) => right.balance match {
+ case -1 => doubleLeftRotation(node)
+ case _ => leftRotation(node)
+ }
+
+ case _ => tree
+ }
+
+ def leftRotation[A](tree: Node[A]): AVLTree[A] = tree.right match {
+ case Node(b, left, right) => Node(b, Node(tree.data, tree.left, left), right)
+ case _ => sys.error("Should not happen.")
+ }
+
+ def rightRotation[A](tree: Node[A]): AVLTree[A] = tree.left match {
+ case Node(b, left, right) => Node(b, left, Node(tree.data, right, tree.right))
+ case _ => sys.error("Should not happen.")
+ }
+
+ def doubleLeftRotation[A](tree: Node[A]): AVLTree[A] = tree.right match {
+ case right@Node(b, l, r) => leftRotation(Node(tree.data, tree.left, rightRotation(right)))
+ case _ => sys.error("Should not happen.")
+ }
+
+ def doubleRightRotation[A](tree: Node[A]): AVLTree[A] = tree.left match {
+ case left@Node(b, l, r) => rightRotation(Node(tree.data, leftRotation(left), tree.right))
+ case _ => sys.error("Should not happen.")
+ }
+
+}
diff --git a/src/library/scala/collection/mutable/ListBuffer.scala b/src/library/scala/collection/mutable/ListBuffer.scala
index 131cdd0005..eb871135df 100644
--- a/src/library/scala/collection/mutable/ListBuffer.scala
+++ b/src/library/scala/collection/mutable/ListBuffer.scala
@@ -13,6 +13,7 @@ package mutable
import generic._
import immutable.{List, Nil, ::}
+import java.io._
/** A `Buffer` implementation back up by a list. It provides constant time
* prepend and append. Most other operations are linear.
@@ -53,6 +54,7 @@ final class ListBuffer[A]
override def companion: GenericCompanion[ListBuffer] = ListBuffer
import scala.collection.Traversable
+ import scala.collection.immutable.ListSerializeEnd
private var start: List[A] = Nil
private var last0: ::[A] = _
@@ -60,7 +62,49 @@ final class ListBuffer[A]
private var len = 0
protected def underlying: immutable.Seq[A] = start
-
+
+ private def writeObject(out: ObjectOutputStream) {
+ // write start
+ var xs: List[A] = start
+ while (!xs.isEmpty) { out.writeObject(xs.head); xs = xs.tail }
+ out.writeObject(ListSerializeEnd)
+
+ // no need to write last0
+
+ // write if exported
+ out.writeBoolean(exported)
+
+ // write the length
+ out.writeInt(len)
+ }
+
+ private def readObject(in: ObjectInputStream) {
+ // read start, set last0 appropriately
+ var elem: A = in.readObject.asInstanceOf[A]
+ if (elem == ListSerializeEnd) {
+ start = Nil
+ last0 = null
+ } else {
+ var current = new ::(elem, Nil)
+ start = current
+ elem = in.readObject.asInstanceOf[A]
+ while (elem != ListSerializeEnd) {
+ val list = new ::(elem, Nil)
+ current.tl = list
+ current = list
+ elem = in.readObject.asInstanceOf[A]
+ }
+ last0 = current
+ start
+ }
+
+ // read if exported
+ exported = in.readBoolean()
+
+ // read the length
+ len = in.readInt()
+ }
+
/** The current length of the buffer.
*
* This operation takes constant time.
diff --git a/src/library/scala/collection/mutable/SortedSet.scala b/src/library/scala/collection/mutable/SortedSet.scala
new file mode 100644
index 0000000000..d87fc0b4a2
--- /dev/null
+++ b/src/library/scala/collection/mutable/SortedSet.scala
@@ -0,0 +1,49 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.collection
+package mutable
+
+import generic._
+
+/**
+ * Base trait for mutable sorted set.
+ *
+ * @define Coll mutable.SortedSet
+ * @define coll mutable sorted set
+ *
+ * @author Lucien Pereira
+ *
+ */
+trait SortedSet[A] extends collection.SortedSet[A] with collection.SortedSetLike[A,SortedSet[A]]
+ with mutable.Set[A] with mutable.SetLike[A, SortedSet[A]] {
+
+ /** Needs to be overridden in subclasses. */
+ override def empty: SortedSet[A] = SortedSet.empty[A]
+
+}
+
+/**
+ * A template for mutable sorted set companion objects.
+ *
+ * @define Coll mutable.SortedSet
+ * @define coll mutable sorted set
+ * @define factoryInfo
+ * This object provides a set of operations needed to create sorted sets of type mutable.SortedSet.
+ * @define sortedSetCanBuildFromInfo
+ * Standard `CanBuildFrom` instance for sorted sets.
+ *
+ * @author Lucien Pereira
+ *
+ */
+object SortedSet extends MutableSortedSetFactory[SortedSet] {
+ implicit def canBuildFrom[A](implicit ord: Ordering[A]): CanBuildFrom[Coll, A, SortedSet[A]] = new SortedSetCanBuildFrom[A]
+
+ def empty[A](implicit ord: Ordering[A]): SortedSet[A] = TreeSet.empty[A]
+
+}
diff --git a/src/library/scala/collection/mutable/TreeSet.scala b/src/library/scala/collection/mutable/TreeSet.scala
new file mode 100644
index 0000000000..38fa0c953f
--- /dev/null
+++ b/src/library/scala/collection/mutable/TreeSet.scala
@@ -0,0 +1,123 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.collection
+package mutable
+
+import generic._
+
+/**
+ * @define Coll mutable.TreeSet
+ * @define coll mutable tree set
+ * @factoryInfo
+ * Companion object of TreeSet providing factory related utilities.
+ *
+ * @author Lucien Pereira
+ *
+ */
+object TreeSet extends MutableSortedSetFactory[TreeSet] {
+ /**
+ * The empty set of this type
+ */
+ def empty[A](implicit ordering: Ordering[A]) = new TreeSet[A]()
+
+}
+
+/**
+ * A mutable SortedSet using an immutable AVL Tree as underlying data structure.
+ *
+ * @author Lucien Pereira
+ *
+ */
+class TreeSet[A](implicit val ordering: Ordering[A]) extends SortedSet[A] with SetLike[A, TreeSet[A]]
+ with SortedSetLike[A, TreeSet[A]] with Set[A] with Serializable {
+
+ // Projection constructor
+ private def this(base: Option[TreeSet[A]], from: Option[A], until: Option[A])(implicit ordering: Ordering[A]) {
+ this();
+ this.base = base
+ this.from = from
+ this.until = until
+ }
+
+ private var base: Option[TreeSet[A]] = None
+
+ private var from: Option[A] = None
+
+ private var until: Option[A] = None
+
+ private var avl: AVLTree[A] = Leaf
+
+ private var cardinality: Int = 0
+
+ def resolve: TreeSet[A] = base.getOrElse(this)
+
+ private def isLeftAcceptable(from: Option[A], ordering: Ordering[A])(a: A): Boolean =
+ from.map(x => ordering.gteq(a, x)).getOrElse(true)
+
+ private def isRightAcceptable(until: Option[A], ordering: Ordering[A])(a: A): Boolean =
+ until.map(x => ordering.lt(a, x)).getOrElse(true)
+
+ /**
+ * Cardinality store the set size, unfortunately a
+ * set view (given by rangeImpl)
+ * cannot take advantage of this optimisation
+ *
+ */
+ override def size: Int = base.map(_ => super.size).getOrElse(cardinality)
+
+ override def stringPrefix = "TreeSet"
+
+ override def empty: TreeSet[A] = TreeSet.empty
+
+ override def rangeImpl(from: Option[A], until: Option[A]): TreeSet[A] = new TreeSet(Some(this), from, until)
+
+ override def -=(elem: A): this.type = {
+ try {
+ resolve.avl = AVLTree.remove(elem, resolve.avl, ordering)
+ resolve.cardinality = resolve.cardinality - 1
+ } catch {
+ case e: NoSuchElementException => ()
+ }
+ this
+ }
+
+ override def +=(elem: A): this.type = {
+ try {
+ resolve.avl = AVLTree.insert(elem, resolve.avl, ordering)
+ resolve.cardinality = resolve.cardinality + 1
+ } catch {
+ case e: IllegalArgumentException => ()
+ }
+ this
+ }
+
+ /**
+ * Thanks to the nature immutable of the
+ * underlying AVL Tree, we can share it with
+ * the clone. So clone complexity in time is O(1).
+ *
+ */
+ override def clone: TreeSet[A] = {
+ val clone = new TreeSet[A](base, from, until)
+ clone.avl = resolve.avl
+ clone.cardinality = resolve.cardinality
+ clone
+ }
+
+ override def contains(elem: A): Boolean = {
+ isLeftAcceptable(from, ordering)(elem) &&
+ isRightAcceptable(until, ordering)(elem) &&
+ AVLTree.contains(elem, resolve.avl, ordering)
+ }
+
+ override def iterator: Iterator[A] =
+ AVLTree.iterator(resolve.avl,
+ isLeftAcceptable(from, ordering),
+ isRightAcceptable(until, ordering))
+}
diff --git a/src/library/scala/collection/parallel/ParIterableLike.scala b/src/library/scala/collection/parallel/ParIterableLike.scala
index f0d79ada9d..90b64c17f9 100644
--- a/src/library/scala/collection/parallel/ParIterableLike.scala
+++ b/src/library/scala/collection/parallel/ParIterableLike.scala
@@ -801,7 +801,7 @@ self: ParIterableLike[T, Repr, Sequential] =>
override def toList: List[T] = seq.toList
- override def toIndexedSeq[U >: T]: collection.immutable.IndexedSeq[U] = seq.toIndexedSeq[U]
+ override def toIndexedSeq: collection.immutable.IndexedSeq[T] = seq.toIndexedSeq
override def toStream: Stream[T] = seq.toStream
diff --git a/src/library/scala/io/Codec.scala b/src/library/scala/io/Codec.scala
index 1a27df1c10..d9cef0edb1 100644
--- a/src/library/scala/io/Codec.scala
+++ b/src/library/scala/io/Codec.scala
@@ -38,6 +38,9 @@ class Codec(val charSet: Charset) {
private[this] var _decodingReplacement: String = null
private[this] var _onCodingException: Handler = e => throw e
+ /** The name of the Codec. */
+ override def toString = name
+
// these methods can be chained to configure the variables above
def onMalformedInput(newAction: Action): this.type = { _onMalformedInput = newAction ; this }
def onUnmappableCharacter(newAction: Action): this.type = { _onUnmappableCharacter = newAction ; this }
diff --git a/src/library/scala/reflect/Manifest.scala b/src/library/scala/reflect/Manifest.scala
index be08409636..8bd45c0e33 100644
--- a/src/library/scala/reflect/Manifest.scala
+++ b/src/library/scala/reflect/Manifest.scala
@@ -60,7 +60,7 @@ trait Manifest[T] extends ClassManifest[T] with Equals {
override def hashCode = this.erasure.##
}
-sealed abstract class AnyValManifest[T <: AnyVal](override val toString: String) extends Manifest[T] with Equals {
+abstract class AnyValManifest[T <: AnyVal](override val toString: String) extends Manifest[T] with Equals {
override def <:<(that: ClassManifest[_]): Boolean =
(that eq this) || (that eq Manifest.Any) || (that eq Manifest.AnyVal)
override def canEqual(other: Any) = other match {
diff --git a/src/library/scala/reflect/ReflectionUtils.scala b/src/library/scala/reflect/ReflectionUtils.scala
index b63a8645de..dfadfb4976 100644
--- a/src/library/scala/reflect/ReflectionUtils.scala
+++ b/src/library/scala/reflect/ReflectionUtils.scala
@@ -27,11 +27,15 @@ object ReflectionUtils {
case ex if pf isDefinedAt unwrapThrowable(ex) => pf(unwrapThrowable(ex))
}
- // Retrieves the MODULE$ field for the given class name.
- def singletonInstance(className: String, cl: ClassLoader = getClass.getClassLoader): Option[AnyRef] = {
+ def singletonInstance(className: String, cl: ClassLoader = getClass.getClassLoader): AnyRef = {
val name = if (className endsWith "$") className else className + "$"
+ val clazz = java.lang.Class.forName(name, true, cl)
+ val singleton = clazz getField "MODULE$" get null
+ singleton
+ }
- try Some(java.lang.Class.forName(name, true, cl) getField "MODULE$" get null)
+ // Retrieves the MODULE$ field for the given class name.
+ def singletonInstanceOpt(className: String, cl: ClassLoader = getClass.getClassLoader): Option[AnyRef] =
+ try Some(singletonInstance(className, cl))
catch { case _: ClassNotFoundException => None }
- }
}
diff --git a/src/library/scala/reflect/api/Mirror.scala b/src/library/scala/reflect/api/Mirror.scala
index 53ac84f8cb..136f52b05f 100644
--- a/src/library/scala/reflect/api/Mirror.scala
+++ b/src/library/scala/reflect/api/Mirror.scala
@@ -13,7 +13,11 @@ trait Mirror extends Universe with RuntimeTypes with TreeBuildUtil {
* to do: throws anything else?
*/
def classWithName(name: String): Symbol
-
+
+ /** Return a reference to the companion object of this class symbol
+ */
+ def getCompanionObject(clazz: Symbol): AnyRef
+
/** The Scala class symbol corresponding to the runtime class of given object
* @param The object from which the class is returned
* @throws ?
diff --git a/src/library/scala/reflect/api/Symbols.scala b/src/library/scala/reflect/api/Symbols.scala
index 31bcdebe7e..8b4b170847 100755
--- a/src/library/scala/reflect/api/Symbols.scala
+++ b/src/library/scala/reflect/api/Symbols.scala
@@ -150,10 +150,10 @@ trait Symbols { self: Universe =>
*/
def asTypeIn(site: Type): Type
- /** A fresh symbol with given position `pos` and name `name` that has
+ /** A fresh symbol with given name `name`, position `pos` and flags `flags` that has
* the current symbol as its owner.
*/
- def newNestedSymbol(pos: Position, name: Name): Symbol // needed by LiftCode
+ def newNestedSymbol(name: Name, pos: Position, flags: Long): Symbol // needed by LiftCode
/** Low-level operation to set the symbol's flags
* @return the symbol itself
diff --git a/src/library/scala/reflect/api/TreePrinters.scala b/src/library/scala/reflect/api/TreePrinters.scala
index 15fba0e418..88ef450ed9 100644
--- a/src/library/scala/reflect/api/TreePrinters.scala
+++ b/src/library/scala/reflect/api/TreePrinters.scala
@@ -28,7 +28,21 @@ trait TreePrinters { self: Universe =>
*/
def newTreePrinter(out: PrintWriter): TreePrinter
+ // emits more or less verbatim representation of the provided tree
+ // todo. when LiftCode becomes a macro, throw this code away and use that macro
class RawTreePrinter(out: PrintWriter) extends TreePrinter {
+ import scala.reflect.api.Modifier
+ import scala.reflect.api.Modifier._
+
+ def copypasteModifier(mod: Modifier.Value): String = mod match {
+ case mod @ (
+ `protected` | `private` | `override` |
+ `abstract` | `final` | `sealed` |
+ `implicit` | `lazy` | `macro` |
+ `case` | `trait`) => "`" + mod.toString + "`"
+ case mod => mod.toString
+ }
+
def print(args: Any*): Unit = args foreach {
case EmptyTree =>
print("EmptyTree")
@@ -48,10 +62,35 @@ trait TreePrinters { self: Universe =>
case arg =>
print(arg)
}
- print(if (it.hasNext) ", " else ")")
+ print(if (it.hasNext) ", " else "")
}
+ print(")")
if (typesPrinted)
print(".setType(", tree.tpe, ")")
+ case list: List[_] =>
+ print("List(")
+ val it = list.iterator
+ while (it.hasNext) {
+ print(it.next())
+ print(if (it.hasNext) ", " else "")
+ }
+ print(")")
+ case mods: Modifiers =>
+ val parts = collection.mutable.ListBuffer[String]()
+ parts += "Set(" + mods.allModifiers.map{copypasteModifier}.mkString(", ") + ")"
+ parts += "newTypeName(\"" + mods.privateWithin.toString + "\")"
+ parts += "List(" + mods.annotations.map{showRaw}.mkString(", ") + ")"
+
+ var keep = 3
+ if (keep == 3 && mods.annotations.isEmpty) keep -= 1
+ if (keep == 2 && mods.privateWithin == EmptyTypeName) keep -= 1
+ if (keep == 1 && mods.allModifiers.isEmpty) keep -= 1
+
+ print("Modifiers(", parts.take(keep).mkString(", "), ")")
+ case name: Name =>
+ if (name.isTermName) print("newTermName(\"") else print("newTypeName(\"")
+ print(name.toString)
+ print("\")")
case arg =>
out.print(arg)
}
diff --git a/src/library/scala/reflect/api/MacroContext.scala b/src/library/scala/reflect/macro/Context.scala
index e23357d26e..d0a2787fdf 100644
--- a/src/library/scala/reflect/api/MacroContext.scala
+++ b/src/library/scala/reflect/macro/Context.scala
@@ -1,7 +1,7 @@
package scala.reflect
-package api
+package macro
-trait MacroContext extends Universe {
+trait Context extends api.Universe {
/** Mark a variable as captured; i.e. force boxing in a *Ref type.
*/
@@ -12,4 +12,4 @@ trait MacroContext extends Universe {
*/
def referenceCapturedVariable(id: Ident): Tree
-} \ No newline at end of file
+}
diff --git a/src/library/scala/reflect/package.scala b/src/library/scala/reflect/package.scala
index 62592baa27..1c3e618520 100644
--- a/src/library/scala/reflect/package.scala
+++ b/src/library/scala/reflect/package.scala
@@ -8,7 +8,7 @@ package object reflect {
// initialization, but in response to a doomed attempt to utilize it.
lazy val mirror: api.Mirror = {
// we use (Java) reflection here so that we can keep reflect.runtime and reflect.internals in a seperate jar
- ReflectionUtils.singletonInstance("scala.reflect.runtime.Mirror") collect { case x: api.Mirror => x } getOrElse {
+ ReflectionUtils.singletonInstanceOpt("scala.reflect.runtime.Mirror") collect { case x: api.Mirror => x } getOrElse {
throw new UnsupportedOperationException("Scala reflection not available on this platform")
}
}
diff --git a/src/library/scala/xml/include/sax/Main.scala b/src/library/scala/xml/include/sax/Main.scala
index 6b6f6c1593..f58097bcb9 100644
--- a/src/library/scala/xml/include/sax/Main.scala
+++ b/src/library/scala/xml/include/sax/Main.scala
@@ -10,11 +10,11 @@
package scala.xml
package include.sax
-import scala.xml.include._
import scala.util.control.Exception.{ catching, ignoring }
import org.xml.sax.XMLReader
import org.xml.sax.helpers.XMLReaderFactory
+@deprecated("Code example will be moved to documentation.", "2.10.0")
object Main {
private val namespacePrefixes = "http://xml.org/sax/features/namespace-prefixes"
private val lexicalHandler = "http://xml.org/sax/properties/lexical-handler"