diff options
author | Vojin Jovanovic <vojin.jovanovic@epfl.ch> | 2012-01-25 15:24:18 +0100 |
---|---|---|
committer | Vojin Jovanovic <vojin.jovanovic@epfl.ch> | 2012-01-25 15:24:18 +0100 |
commit | f814d40ea917592f78d2e8ca4c78f34ce4b5f297 (patch) | |
tree | cafac6a0d757419132fd75ab788f8163a619780b /src/library | |
parent | 85daadef89a9ed5c3901a5822221366ee6746d49 (diff) | |
parent | de2b0c68785afc0f801fbe8d2750366e90c9fa70 (diff) | |
download | scala-f814d40ea917592f78d2e8ca4c78f34ce4b5f297.tar.gz scala-f814d40ea917592f78d2e8ca4c78f34ce4b5f297.tar.bz2 scala-f814d40ea917592f78d2e8ca4c78f34ce4b5f297.zip |
Merge branch 'master' into execution-context
Diffstat (limited to 'src/library')
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" |