diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/library/scala/collection/immutable/List.scala | 101 | ||||
-rw-r--r-- | src/library/scala/collection/mutable/BufferLike.scala | 6 | ||||
-rw-r--r-- | src/library/scala/collection/mutable/ListBuffer.scala | 5 | ||||
-rw-r--r-- | src/library/scala/collection/mutable/Map.scala | 12 | ||||
-rw-r--r-- | src/reflect/scala/reflect/api/Liftables.scala | 55 | ||||
-rw-r--r-- | src/reflect/scala/reflect/api/Quasiquotes.scala | 10 |
6 files changed, 157 insertions, 32 deletions
diff --git a/src/library/scala/collection/immutable/List.scala b/src/library/scala/collection/immutable/List.scala index c3728fa02a..930e13a9d3 100644 --- a/src/library/scala/collection/immutable/List.scala +++ b/src/library/scala/collection/immutable/List.scala @@ -203,17 +203,19 @@ sealed abstract class List[+A] extends AbstractSeq[A] override def toList: List[A] = this - override def take(n: Int): List[A] = { - val b = new ListBuffer[A] - var i = 0 - var these = this - while (!these.isEmpty && i < n) { + override def take(n: Int): List[A] = if (isEmpty || n <= 0) Nil else { + val h = new ::(head, Nil) + var t = h + var rest = tail + var i = 1 + while ({if (rest.isEmpty) return this; i < n}) { i += 1 - b += these.head - these = these.tail + val nx = new ::(rest.head, Nil) + t.tl = nx + t = nx + rest = rest.tail } - if (these.isEmpty) this - else b.toList + h } override def drop(n: Int): List[A] = { @@ -264,6 +266,85 @@ sealed abstract class List[+A] extends AbstractSeq[A] } (b.toList, these) } + + @noinline // TODO - fix optimizer bug that requires noinline (see SI-8334) + final override def map[B, That](f: A => B)(implicit bf: CanBuildFrom[List[A], B, That]): That = { + if (bf eq List.ReusableCBF) { + if (this eq Nil) Nil.asInstanceOf[That] else { + val h = new ::[B](f(head), Nil) + var t: ::[B] = h + var rest = tail + while (rest ne Nil) { + val nx = new ::(f(rest.head), Nil) + t.tl = nx + t = nx + rest = rest.tail + } + h.asInstanceOf[That] + } + } + else super.map(f) + } + + @noinline // TODO - fix optimizer bug that requires noinline for map; applied here to be safe (see SI-8334) + final override def collect[B, That](pf: PartialFunction[A, B])(implicit bf: CanBuildFrom[List[A], B, That]): That = { + if (bf eq List.ReusableCBF) { + if (this eq Nil) Nil.asInstanceOf[That] else { + var rest = this + var h: ::[B] = null + var x: A = null.asInstanceOf[A] + // Special case for first element + do { + val x: Any = pf.applyOrElse(rest.head, List.partialNotApplied) + if (x.asInstanceOf[AnyRef] ne List.partialNotApplied) h = new ::(x.asInstanceOf[B], Nil) + rest = rest.tail + if (rest eq Nil) return (if (h eq null ) Nil else h).asInstanceOf[That] + } while (h eq null) + var t = h + // Remaining elements + do { + val x: Any = pf.applyOrElse(rest.head, List.partialNotApplied) + if (x.asInstanceOf[AnyRef] ne List.partialNotApplied) { + val nx = new ::(x.asInstanceOf[B], Nil) + t.tl = nx + t = nx + } + rest = rest.tail + } while (rest ne Nil) + h.asInstanceOf[That] + } + } + else super.collect(pf) + } + + @noinline // TODO - fix optimizer bug that requires noinline for map; applied here to be safe (see SI-8334) + final override def flatMap[B, That](f: A => GenTraversableOnce[B])(implicit bf: CanBuildFrom[List[A], B, That]): That = { + if (bf eq List.ReusableCBF) { + if (this eq Nil) Nil.asInstanceOf[That] else { + var rest = this + var found = false + var h: ::[B] = null + var t: ::[B] = null + while (rest ne Nil) { + f(rest.head).foreach{ b => + if (!found) { + h = new ::(b, Nil) + t = h + found = true + } + else { + val nx = new ::(b, Nil) + t.tl = nx + t = nx + } + } + rest = rest.tail + } + (if (!found) Nil else h).asInstanceOf[That] + } + } + else super.flatMap(f) + } @inline final override def takeWhile(p: A => Boolean): List[A] = { val b = new ListBuffer[A] @@ -375,6 +456,8 @@ object List extends SeqFactory[List] { override def empty[A]: List[A] = Nil override def apply[A](xs: A*): List[A] = xs.toList + + private[collection] val partialNotApplied = new Function1[Any, Any] { def apply(x: Any): Any = this } @SerialVersionUID(1L) private class SerializationProxy[A](@transient private var orig: List[A]) extends Serializable { diff --git a/src/library/scala/collection/mutable/BufferLike.scala b/src/library/scala/collection/mutable/BufferLike.scala index 7ba0b27ce5..3c57387c03 100644 --- a/src/library/scala/collection/mutable/BufferLike.scala +++ b/src/library/scala/collection/mutable/BufferLike.scala @@ -211,9 +211,11 @@ trait BufferLike[A, +This <: BufferLike[A, This] with Buffer[A]] */ override def stringPrefix: String = "Buffer" - /** Provide a read-only view of this buffer as a sequence - * @return A sequence which refers to this buffer for all its operations. + /** Returns the current evolving(!) state of this buffer as a read-only sequence. + * + * @return A sequence that forwards to this buffer for all its operations. */ + @deprecated("The returned sequence changes as this buffer is mutated. For an immutable copy, use, e.g., toList.", "2.11.0") def readOnly: scala.collection.Seq[A] = toSeq /** Creates a new collection containing both the elements of this collection and the provided diff --git a/src/library/scala/collection/mutable/ListBuffer.scala b/src/library/scala/collection/mutable/ListBuffer.scala index e76825cea9..5e838d0d88 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._ +import scala.annotation.migration /** A `Buffer` implementation back up by a list. It provides constant time * prepend and append. Most other operations are linear. @@ -262,7 +263,7 @@ final class ListBuffer[A] * @param n the index which refers to the first element to remove. * @param count the number of elements to remove. */ - @scala.annotation.migration("Invalid input values will be rejected in future releases.", "2.11") + @migration("Invalid input values will be rejected in future releases.", "2.11") override def remove(n: Int, count: Int) { if (n >= len) return @@ -407,7 +408,7 @@ final class ListBuffer[A] } } - /** expose the underlying list but do not mark it as exported */ + @deprecated("The result of this method will change along with this buffer, which is often not what's expected.", "2.11.0") override def readOnly: List[A] = start // Private methods diff --git a/src/library/scala/collection/mutable/Map.scala b/src/library/scala/collection/mutable/Map.scala index fe29ce4221..2ac3cb65b5 100644 --- a/src/library/scala/collection/mutable/Map.scala +++ b/src/library/scala/collection/mutable/Map.scala @@ -47,18 +47,6 @@ trait Map[A, B] * @return a wrapper of the map with a default value */ def withDefaultValue(d: B): mutable.Map[A, B] = new Map.WithDefault[A, B](this, x => d) - - /* Return a read-only projection of this map. !!! or just use an (immutable) MapProxy? - def readOnly : scala.collection.Map[A, B] = new scala.collection.Map[A, B] { - override def size = self.size - override def update(key: A, value: B) = self.update(key, value) - override def - (elem: A) = self - elem - override def iterator = self.iterator - override def foreach[U](f: ((A, B)) => U) = self.foreach(f) - override def empty[C] = self.empty[C] - def get(key: A) = self.get(key) - } - */ } /** $factoryInfo diff --git a/src/reflect/scala/reflect/api/Liftables.scala b/src/reflect/scala/reflect/api/Liftables.scala index 6ac5557caa..ec9d85b69e 100644 --- a/src/reflect/scala/reflect/api/Liftables.scala +++ b/src/reflect/scala/reflect/api/Liftables.scala @@ -2,27 +2,72 @@ package scala package reflect package api -// TODO: needs a Scaladoc trait Liftables { self: Universe => - // TODO: needs a Scaladoc + /** A type class that defines a representation of `T` as a `Tree`. + * + * @see [[http://docs.scala-lang.org/overviews/macros/quasiquotes.html#lifting]] + */ trait Liftable[T] { def apply(value: T): Tree } - // TODO: needs a Scaladoc + /** Companion to `Liftable` type class that contains standard instances + * and provides a helper `apply` method to simplify creation of new ones. + */ object Liftable extends StandardLiftableInstances { + /** A helper method that simplifies creation of `Liftable` instances. + * Takes a type and a function that maps that type to a tree representation. + * + * For example to write Liftable for object one might use it like: + * + * {{{ + * scala> object O + * + * scala> val Oref = symbolOf[O.type].asClass.module + * + * scala> implicit val liftO = Liftable[O.type] { _ => q"$Oref" } + * + * scala> val lifted = q"$O" + * lifted: universe.Tree = O + * }}} + * + * @see [[http://docs.scala-lang.org/overviews/macros/quasiquotes.html#lifting]] + */ def apply[T](f: T => Tree): Liftable[T] = new Liftable[T] { def apply(value: T): Tree = f(value) } } - // TODO: needs a Scaladoc + /** A type class that defines a way to extract instance of `T` from a `Tree`. + * + * @see [[http://docs.scala-lang.org/overviews/macros/quasiquotes.html#unlifting]] + */ trait Unliftable[T] { def unapply(tree: Tree): Option[T] } - // TODO: needs a Scaladoc + /** Companion to `Unliftable` type class that contains standard instances + * and provides a helper `apply` method to simplify creation of new ones. + */ object Unliftable extends StandardUnliftableInstances { + /** A helper method that simplifies creation of `Unliftable` instances. + * Takes a partial function which is defined on correct representations of `T` + * and returns corresponing instances. + * + * For example to extract a reference to an object as object itself: + * + * {{{ + * scala> object O + * + * scala> val Oref = symbolOf[O.type].asClass.module + * + * scala> implicit val unliftO = Unliftable[O.type] { case t if t.symbol == Oref => O } + * + * scala> val q"${_: O.type}" = q"$Oref" + * }}} + * + * @see [[http://docs.scala-lang.org/overviews/macros/quasiquotes.html#unlifting]] + */ def apply[T](pf: PartialFunction[Tree, T]): Unliftable[T] = new Unliftable[T] { def unapply(value: Tree): Option[T] = pf.lift(value) } diff --git a/src/reflect/scala/reflect/api/Quasiquotes.scala b/src/reflect/scala/reflect/api/Quasiquotes.scala index c939eee164..0065926e3b 100644 --- a/src/reflect/scala/reflect/api/Quasiquotes.scala +++ b/src/reflect/scala/reflect/api/Quasiquotes.scala @@ -3,10 +3,16 @@ package api trait Quasiquotes { self: Universe => - // implementation is hardwired to `dispatch` method of `scala.tools.reflect.quasiquotes.Quasiquotes` - // using the mechanism implemented in `scala.tools.reflect.FastTrack` + /** Implicit class that introduces `q`, `tq`, `cq,` `p` and `fq` string interpolators + * that are also known as quasiquotes. With their help you can easily manipulate + * Scala reflection ASTs. + * + * @see [[http://docs.scala-lang.org/overviews/macros/quasiquotes.html]] + */ implicit class Quasiquote(ctx: StringContext) { protected trait api { + // implementation is hardwired to `dispatch` method of `scala.tools.reflect.quasiquotes.Quasiquotes` + // using the mechanism implemented in `scala.tools.reflect.FastTrack` def apply[T](args: T*): Tree = macro ??? def unapply(scrutinee: Any): Any = macro ??? } |