summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/library/scala/collection/immutable/List.scala101
-rw-r--r--src/library/scala/collection/mutable/BufferLike.scala6
-rw-r--r--src/library/scala/collection/mutable/ListBuffer.scala5
-rw-r--r--src/library/scala/collection/mutable/Map.scala12
-rw-r--r--src/reflect/scala/reflect/api/Liftables.scala55
-rw-r--r--src/reflect/scala/reflect/api/Quasiquotes.scala10
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 ???
}