diff options
Diffstat (limited to 'src')
24 files changed, 315 insertions, 318 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala index 82aa3c65aa..b4d645d4bb 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala @@ -641,8 +641,8 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { } argsSize match { case 1 => bc newarray elemKind - case _ => - val descr = ('[' * argsSize) + elemKind.descriptor // denotes the same as: arrayN(elemKind, argsSize).descriptor + case _ => // this is currently dead code is Scalac, unlike in Dotty + val descr = ("[" * argsSize) + elemKind.descriptor // denotes the same as: arrayN(elemKind, argsSize).descriptor mnode.visitMultiANewArrayInsn(descr, argsSize) } diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/BytecodeUtils.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/BytecodeUtils.scala index 9a90c53d3e..f48f60a438 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/BytecodeUtils.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/BytecodeUtils.scala @@ -88,6 +88,11 @@ object BytecodeUtils { def isLoadOrStore(instruction: AbstractInsnNode): Boolean = isLoad(instruction) || isStore(instruction) + def isNonVirtualCall(instruction: AbstractInsnNode): Boolean = { + val op = instruction.getOpcode + op == INVOKESPECIAL || op == INVOKESTATIC + } + def isExecutable(instruction: AbstractInsnNode): Boolean = instruction.getOpcode >= 0 def isConstructor(methodNode: MethodNode): Boolean = { diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala index 6dd74bad84..3267b9b5df 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala @@ -132,7 +132,7 @@ class CallGraph[BT <: BTypes](val btypes: BT) { (declarationClassNode, source) <- byteCodeRepository.classNodeAndSource(declarationClass): Either[OptimizerWarning, (ClassNode, Source)] } yield { val declarationClassBType = classBTypeFromClassNode(declarationClassNode) - val CallsiteInfo(safeToInline, safeToRewrite, canInlineFromSource, annotatedInline, annotatedNoInline, samParamTypes, warning) = analyzeCallsite(method, declarationClassBType, call.owner, source) + val CallsiteInfo(safeToInline, safeToRewrite, canInlineFromSource, annotatedInline, annotatedNoInline, samParamTypes, warning) = analyzeCallsite(method, declarationClassBType, call, source) Callee( callee = method, calleeDeclarationClass = declarationClassBType, @@ -264,7 +264,7 @@ class CallGraph[BT <: BTypes](val btypes: BT) { /** * Analyze a callsite and gather meta-data that can be used for inlining decisions. */ - private def analyzeCallsite(calleeMethodNode: MethodNode, calleeDeclarationClassBType: ClassBType, receiverTypeInternalName: InternalName, calleeSource: Source): CallsiteInfo = { + private def analyzeCallsite(calleeMethodNode: MethodNode, calleeDeclarationClassBType: ClassBType, call: MethodInsnNode, calleeSource: Source): CallsiteInfo = { val methodSignature = calleeMethodNode.name + calleeMethodNode.desc try { @@ -277,7 +277,7 @@ class CallGraph[BT <: BTypes](val btypes: BT) { val isAbstract = BytecodeUtils.isAbstractMethod(calleeMethodNode) - val receiverType = classBTypeFromParsedClassfile(receiverTypeInternalName) + val receiverType = classBTypeFromParsedClassfile(call.owner) // (1) A non-final method can be safe to inline if the receiver type is a final subclass. Example: // class A { @inline def f = 1 }; object B extends A; B.f // can be inlined // @@ -295,6 +295,7 @@ class CallGraph[BT <: BTypes](val btypes: BT) { // TODO: type analysis can render more calls statically resolved. Example: // new A.f // can be inlined, the receiver type is known to be exactly A. val isStaticallyResolved: Boolean = { + isNonVirtualCall(call) || // SD-86: super calls (invokespecial) can be inlined methodInlineInfo.effectivelyFinal || receiverType.info.orThrow.inlineInfo.isEffectivelyFinal // (1) } diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index 2f6d6511b2..58d43f8666 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -188,13 +188,7 @@ object Predef extends LowPriorityImplicits with DeprecatedPredef { /** @group utilities */ @inline def locally[T](x: T): T = x // to communicate intent and avoid unmoored statements - // errors and asserts ------------------------------------------------- - - // !!! Remove this when possible - ideally for 2.11. - // We are stuck with it a while longer because sbt's compiler interface - // still calls it as of 0.12.2. - @deprecated("Use `sys.error(message)` instead", "2.9.0") - def error(message: String): Nothing = sys.error(message) + // assertions --------------------------------------------------------- /** Tests an expression, throwing an `AssertionError` if false. * Calls to this method will not be generated if `-Xelide-below` diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala index 518bba6b6d..1426278954 100644 --- a/src/library/scala/collection/Iterator.scala +++ b/src/library/scala/collection/Iterator.scala @@ -11,6 +11,7 @@ package collection import mutable.ArrayBuffer import scala.annotation.{tailrec, migration} +import scala.annotation.unchecked.{uncheckedVariance => uV} import immutable.Stream /** The `Iterator` object provides various functions for creating specialized iterators. @@ -160,30 +161,49 @@ object Iterator { def next = elem } - /** Avoid stack overflows when applying ++ to lots of iterators by - * flattening the unevaluated iterators out into a vector of closures. + /** Creates an iterator to which other iterators can be appended efficiently. + * Nested ConcatIterators are merged to avoid blowing the stack. */ - private[scala] final class ConcatIterator[+A](private[this] var current: Iterator[A], initial: Vector[() => Iterator[A]]) extends Iterator[A] { - @deprecated def this(initial: Vector[() => Iterator[A]]) = this(Iterator.empty, initial) // for binary compatibility - private[this] var queue: Vector[() => Iterator[A]] = initial - private[this] var currentHasNextChecked = false + private final class ConcatIterator[+A](private var current: Iterator[A @uV]) extends Iterator[A] { + private var tail: ConcatIteratorCell[A @uV] = null + private var last: ConcatIteratorCell[A @uV] = null + private var currentHasNextChecked = false + // Advance current to the next non-empty iterator // current is set to null when all iterators are exhausted @tailrec private[this] def advance(): Boolean = { - if (queue.isEmpty) { + if (tail eq null) { current = null + last = null false } else { - current = queue.head() - queue = queue.tail - if (current.hasNext) { + current = tail.headIterator + tail = tail.tail + merge() + if (currentHasNextChecked) true + else if (current.hasNext) { currentHasNextChecked = true true } else advance() } } + + // If the current iterator is a ConcatIterator, merge it into this one + @tailrec + private[this] def merge(): Unit = + if (current.isInstanceOf[ConcatIterator[_]]) { + val c = current.asInstanceOf[ConcatIterator[A]] + current = c.current + currentHasNextChecked = c.currentHasNextChecked + if (c.tail ne null) { + c.last.tail = tail + tail = c.tail + } + merge() + } + def hasNext = if (currentHasNextChecked) true else if (current eq null) false @@ -191,47 +211,29 @@ object Iterator { currentHasNextChecked = true true } else advance() + def next() = if (hasNext) { currentHasNextChecked = false current.next() } else Iterator.empty.next() - override def ++[B >: A](that: => GenTraversableOnce[B]): Iterator[B] = - new ConcatIterator(current, queue :+ (() => that.toIterator)) - } - - private[scala] final class JoinIterator[+A](lhs: Iterator[A], that: => GenTraversableOnce[A]) extends Iterator[A] { - private[this] var state = 0 // 0: lhs not checked, 1: lhs has next, 2: switched to rhs - private[this] lazy val rhs: Iterator[A] = that.toIterator - def hasNext = state match { - case 0 => - if (lhs.hasNext) { - state = 1 - true - } else { - state = 2 - rhs.hasNext - } - case 1 => true - case _ => rhs.hasNext - } - def next() = state match { - case 0 => - if (lhs.hasNext) lhs.next() - else { - state = 2 - rhs.next() - } - case 1 => - state = 0 - lhs.next() - case _ => - rhs.next() + override def ++[B >: A](that: => GenTraversableOnce[B]): Iterator[B] = { + val c = new ConcatIteratorCell[B](that, null).asInstanceOf[ConcatIteratorCell[A]] + if(tail eq null) { + tail = c + last = c + } else { + last.tail = c + last = c + } + if(current eq null) current = Iterator.empty + this } + } - override def ++[B >: A](that: => GenTraversableOnce[B]) = - new ConcatIterator(this, Vector(() => that.toIterator)) + private[this] final class ConcatIteratorCell[A](head: => GenTraversableOnce[A], var tail: ConcatIteratorCell[A]) { + def headIterator: Iterator[A] = head.toIterator } /** Creates a delegating iterator capped by a limit count. Negative limit means unbounded. @@ -456,7 +458,7 @@ trait Iterator[+A] extends TraversableOnce[A] { * @usecase def ++(that: => Iterator[A]): Iterator[A] * @inheritdoc */ - def ++[B >: A](that: => GenTraversableOnce[B]): Iterator[B] = new Iterator.JoinIterator(self, that) + def ++[B >: A](that: => GenTraversableOnce[B]): Iterator[B] = new Iterator.ConcatIterator(self) ++ that /** Creates a new iterator by applying a function to all values produced by this iterator * and concatenating the results. diff --git a/src/library/scala/collection/immutable/HashMap.scala b/src/library/scala/collection/immutable/HashMap.scala index 3c41e1ba11..eac9c14f3f 100644 --- a/src/library/scala/collection/immutable/HashMap.scala +++ b/src/library/scala/collection/immutable/HashMap.scala @@ -33,8 +33,7 @@ import parallel.immutable.ParHashMap * @define willNotTerminateInf */ @SerialVersionUID(2L) -@deprecatedInheritance("The implementation details of immutable hash maps make inheriting from them unwise.", "2.11.0") -class HashMap[A, +B] extends AbstractMap[A, B] +sealed class HashMap[A, +B] extends AbstractMap[A, B] with Map[A, B] with MapLike[A, B, HashMap[A, B]] with Serializable diff --git a/src/library/scala/collection/immutable/HashSet.scala b/src/library/scala/collection/immutable/HashSet.scala index 2d8cc0b386..fc937e3a22 100644 --- a/src/library/scala/collection/immutable/HashSet.scala +++ b/src/library/scala/collection/immutable/HashSet.scala @@ -31,8 +31,7 @@ import scala.annotation.tailrec * @define coll immutable hash set */ @SerialVersionUID(2L) -@deprecatedInheritance("The implementation details of immutable hash sets make inheriting from them unwise.", "2.11.0") -class HashSet[A] extends AbstractSet[A] +sealed class HashSet[A] extends AbstractSet[A] with Set[A] with GenericSetTemplate[A, HashSet] with SetLike[A, HashSet[A]] diff --git a/src/library/scala/collection/immutable/ListMap.scala b/src/library/scala/collection/immutable/ListMap.scala index 5bbcf44201..e1bcc0711c 100644 --- a/src/library/scala/collection/immutable/ListMap.scala +++ b/src/library/scala/collection/immutable/ListMap.scala @@ -58,8 +58,7 @@ object ListMap extends ImmutableMapFactory[ListMap] { * @define willNotTerminateInf */ @SerialVersionUID(301002838095710379L) -@deprecatedInheritance("The semantics of immutable collections makes inheriting from ListMap error-prone.", "2.11.0") -class ListMap[A, +B] +sealed class ListMap[A, +B] extends AbstractMap[A, B] with Map[A, B] with MapLike[A, B, ListMap[A, B]] diff --git a/src/library/scala/collection/immutable/ListSet.scala b/src/library/scala/collection/immutable/ListSet.scala index 98b91f7c84..d20e7bc6d2 100644 --- a/src/library/scala/collection/immutable/ListSet.scala +++ b/src/library/scala/collection/immutable/ListSet.scala @@ -67,8 +67,7 @@ object ListSet extends ImmutableSetFactory[ListSet] { * @define mayNotTerminateInf * @define willNotTerminateInf */ -@deprecatedInheritance("The semantics of immutable collections makes inheriting from ListSet error-prone.", "2.11.0") -class ListSet[A] extends AbstractSet[A] +sealed class ListSet[A] extends AbstractSet[A] with Set[A] with GenericSetTemplate[A, ListSet] with SetLike[A, ListSet[A]] diff --git a/src/library/scala/collection/immutable/Queue.scala b/src/library/scala/collection/immutable/Queue.scala index 70b51f8251..3ad6656636 100644 --- a/src/library/scala/collection/immutable/Queue.scala +++ b/src/library/scala/collection/immutable/Queue.scala @@ -37,8 +37,7 @@ import mutable.{ Builder, ListBuffer } */ @SerialVersionUID(-7622936493364270175L) -@deprecatedInheritance("The implementation details of immutable queues make inheriting from them unwise.", "2.11.0") -class Queue[+A] protected(protected val in: List[A], protected val out: List[A]) +sealed class Queue[+A] protected(protected val in: List[A], protected val out: List[A]) extends AbstractSeq[A] with LinearSeq[A] with GenericTraversableTemplate[A, Queue] diff --git a/src/library/scala/collection/immutable/Range.scala b/src/library/scala/collection/immutable/Range.scala index fb7dd4cfbf..d3fe367e50 100644 --- a/src/library/scala/collection/immutable/Range.scala +++ b/src/library/scala/collection/immutable/Range.scala @@ -57,8 +57,7 @@ import scala.collection.parallel.immutable.ParRange * and its complexity is O(1). */ @SerialVersionUID(7618862778670199309L) -@deprecatedInheritance("The implementation details of Range makes inheriting from it unwise.", "2.11.0") -class Range(val start: Int, val end: Int, val step: Int) +sealed class Range(val start: Int, val end: Int, val step: Int) extends scala.collection.AbstractSeq[Int] with IndexedSeq[Int] with scala.collection.CustomParallelizable[Int, ParRange] diff --git a/src/library/scala/collection/immutable/Stream.scala b/src/library/scala/collection/immutable/Stream.scala index d92b159f3b..d3d5af7678 100644 --- a/src/library/scala/collection/immutable/Stream.scala +++ b/src/library/scala/collection/immutable/Stream.scala @@ -198,8 +198,7 @@ import scala.language.implicitConversions * @define orderDependentFold * @define willTerminateInf Note: lazily evaluated; will terminate for infinite-sized collections. */ -@deprecatedInheritance("This class will be sealed.", "2.11.0") -abstract class Stream[+A] extends AbstractSeq[A] +sealed abstract class Stream[+A] extends AbstractSeq[A] with LinearSeq[A] with GenericTraversableTemplate[A, Stream] with LinearSeqOptimized[A, Stream[A]] diff --git a/src/library/scala/collection/immutable/TreeMap.scala b/src/library/scala/collection/immutable/TreeMap.scala index b845b76026..2d1bf0f6b1 100644 --- a/src/library/scala/collection/immutable/TreeMap.scala +++ b/src/library/scala/collection/immutable/TreeMap.scala @@ -44,8 +44,7 @@ object TreeMap extends ImmutableSortedMapFactory[TreeMap] { * @define mayNotTerminateInf * @define willNotTerminateInf */ -@deprecatedInheritance("The implementation details of immutable tree maps make inheriting from them unwise.", "2.11.0") -class TreeMap[A, +B] private (tree: RB.Tree[A, B])(implicit val ordering: Ordering[A]) +final class TreeMap[A, +B] private (tree: RB.Tree[A, B])(implicit val ordering: Ordering[A]) extends SortedMap[A, B] with SortedMapLike[A, B, TreeMap[A, B]] with MapLike[A, B, TreeMap[A, B]] diff --git a/src/library/scala/collection/immutable/TreeSet.scala b/src/library/scala/collection/immutable/TreeSet.scala index 2800030d67..2cdf3b3521 100644 --- a/src/library/scala/collection/immutable/TreeSet.scala +++ b/src/library/scala/collection/immutable/TreeSet.scala @@ -49,8 +49,7 @@ object TreeSet extends ImmutableSortedSetFactory[TreeSet] { * @define willNotTerminateInf */ @SerialVersionUID(-5685982407650748405L) -@deprecatedInheritance("The implementation details of immutable tree sets make inheriting from them unwise.", "2.11.0") -class TreeSet[A] private (tree: RB.Tree[A, Unit])(implicit val ordering: Ordering[A]) +final class TreeSet[A] private (tree: RB.Tree[A, Unit])(implicit val ordering: Ordering[A]) extends SortedSet[A] with SortedSetLike[A, TreeSet[A]] with Serializable { if (ordering eq null) diff --git a/src/library/scala/collection/immutable/WrappedString.scala b/src/library/scala/collection/immutable/WrappedString.scala index 7592316650..8726bd2ed9 100644 --- a/src/library/scala/collection/immutable/WrappedString.scala +++ b/src/library/scala/collection/immutable/WrappedString.scala @@ -29,8 +29,7 @@ import mutable.{Builder, StringBuilder} * @define Coll `WrappedString` * @define coll wrapped string */ -@deprecatedInheritance("Inherit from StringLike instead of WrappedString.", "2.11.0") -class WrappedString(val self: String) extends AbstractSeq[Char] with IndexedSeq[Char] with StringLike[WrappedString] { +final class WrappedString(val self: String) extends AbstractSeq[Char] with IndexedSeq[Char] with StringLike[WrappedString] { override protected[this] def thisCollection: WrappedString = this override protected[this] def toCollection(repr: WrappedString): WrappedString = repr diff --git a/src/library/scala/collection/mutable/ArrayBuilder.scala b/src/library/scala/collection/mutable/ArrayBuilder.scala index 549ffef565..d023110c1b 100644 --- a/src/library/scala/collection/mutable/ArrayBuilder.scala +++ b/src/library/scala/collection/mutable/ArrayBuilder.scala @@ -53,8 +53,7 @@ object ArrayBuilder { * * @tparam T type of elements for the array builder, subtype of `AnyRef` with a `ClassTag` context bound. */ - @deprecatedInheritance("ArrayBuilder.ofRef is an internal implementation not intended for subclassing.", "2.11.0") - class ofRef[T <: AnyRef : ClassTag] extends ArrayBuilder[T] { + final class ofRef[T <: AnyRef : ClassTag] extends ArrayBuilder[T] { private var elems: Array[T] = _ private var capacity: Int = 0 @@ -119,8 +118,7 @@ object ArrayBuilder { } /** A class for array builders for arrays of `byte`s. It can be reused. */ - @deprecatedInheritance("ArrayBuilder.ofByte is an internal implementation not intended for subclassing.", "2.11.0") - class ofByte extends ArrayBuilder[Byte] { + final class ofByte extends ArrayBuilder[Byte] { private var elems: Array[Byte] = _ private var capacity: Int = 0 @@ -185,8 +183,7 @@ object ArrayBuilder { } /** A class for array builders for arrays of `short`s. It can be reused. */ - @deprecatedInheritance("ArrayBuilder.ofShort is an internal implementation not intended for subclassing.", "2.11.0") - class ofShort extends ArrayBuilder[Short] { + final class ofShort extends ArrayBuilder[Short] { private var elems: Array[Short] = _ private var capacity: Int = 0 @@ -251,8 +248,7 @@ object ArrayBuilder { } /** A class for array builders for arrays of `char`s. It can be reused. */ - @deprecatedInheritance("ArrayBuilder.ofChar is an internal implementation not intended for subclassing.", "2.11.0") - class ofChar extends ArrayBuilder[Char] { + final class ofChar extends ArrayBuilder[Char] { private var elems: Array[Char] = _ private var capacity: Int = 0 @@ -317,8 +313,7 @@ object ArrayBuilder { } /** A class for array builders for arrays of `int`s. It can be reused. */ - @deprecatedInheritance("ArrayBuilder.ofInt is an internal implementation not intended for subclassing.", "2.11.0") - class ofInt extends ArrayBuilder[Int] { + final class ofInt extends ArrayBuilder[Int] { private var elems: Array[Int] = _ private var capacity: Int = 0 @@ -383,8 +378,7 @@ object ArrayBuilder { } /** A class for array builders for arrays of `long`s. It can be reused. */ - @deprecatedInheritance("ArrayBuilder.ofLong is an internal implementation not intended for subclassing.", "2.11.0") - class ofLong extends ArrayBuilder[Long] { + final class ofLong extends ArrayBuilder[Long] { private var elems: Array[Long] = _ private var capacity: Int = 0 @@ -449,8 +443,7 @@ object ArrayBuilder { } /** A class for array builders for arrays of `float`s. It can be reused. */ - @deprecatedInheritance("ArrayBuilder.ofFloat is an internal implementation not intended for subclassing.", "2.11.0") - class ofFloat extends ArrayBuilder[Float] { + final class ofFloat extends ArrayBuilder[Float] { private var elems: Array[Float] = _ private var capacity: Int = 0 @@ -515,8 +508,7 @@ object ArrayBuilder { } /** A class for array builders for arrays of `double`s. It can be reused. */ - @deprecatedInheritance("ArrayBuilder.ofDouble is an internal implementation not intended for subclassing.", "2.11.0") - class ofDouble extends ArrayBuilder[Double] { + final class ofDouble extends ArrayBuilder[Double] { private var elems: Array[Double] = _ private var capacity: Int = 0 @@ -646,8 +638,7 @@ object ArrayBuilder { } /** A class for array builders for arrays of `Unit` type. It can be reused. */ - @deprecatedInheritance("ArrayBuilder.ofUnit is an internal implementation not intended for subclassing.", "2.11.0") - class ofUnit extends ArrayBuilder[Unit] { + final class ofUnit extends ArrayBuilder[Unit] { private var size: Int = 0 diff --git a/src/library/scala/collection/mutable/ArrayOps.scala b/src/library/scala/collection/mutable/ArrayOps.scala index 5144db7de3..b7682c5ab9 100644 --- a/src/library/scala/collection/mutable/ArrayOps.scala +++ b/src/library/scala/collection/mutable/ArrayOps.scala @@ -32,8 +32,7 @@ import parallel.mutable.ParArray * @define mayNotTerminateInf * @define willNotTerminateInf */ -@deprecatedInheritance("ArrayOps will be sealed to facilitate greater flexibility with array/collections integration in future releases.", "2.11.0") -trait ArrayOps[T] extends Any with ArrayLike[T, Array[T]] with CustomParallelizable[T, ParArray[T]] { +sealed trait ArrayOps[T] extends Any with ArrayLike[T, Array[T]] with CustomParallelizable[T, ParArray[T]] { private def elementClass: Class[_] = arrayElementClass(repr.getClass) diff --git a/src/library/scala/collection/mutable/PriorityQueue.scala b/src/library/scala/collection/mutable/PriorityQueue.scala index e6889da3b5..b4112c03dd 100644 --- a/src/library/scala/collection/mutable/PriorityQueue.scala +++ b/src/library/scala/collection/mutable/PriorityQueue.scala @@ -46,8 +46,7 @@ import generic._ * @define mayNotTerminateInf * @define willNotTerminateInf */ -@deprecatedInheritance("PriorityQueue is not intended to be subclassed due to extensive private implementation details.", "2.11.0") -class PriorityQueue[A](implicit val ord: Ordering[A]) +sealed class PriorityQueue[A](implicit val ord: Ordering[A]) extends AbstractIterable[A] with Iterable[A] with GenericOrderedTraversableTemplate[A, PriorityQueue] @@ -266,3 +265,176 @@ object PriorityQueue extends OrderedTraversableFactory[PriorityQueue] { implicit def canBuildFrom[A](implicit ord: Ordering[A]): CanBuildFrom[Coll, A, PriorityQueue[A]] = new GenericCanBuildFrom[A] } + +/** This class servers as a proxy for priority queues. The + * elements of the queue have to be ordered in terms of the + * `Ordered[T]` class. + * + * @author Matthias Zenger + * @version 1.0, 03/05/2004 + * @since 1 + */ +@deprecated("Proxying is deprecated due to lack of use and compiler-level support.", "2.11.0") +sealed abstract class PriorityQueueProxy[A](implicit ord: Ordering[A]) extends PriorityQueue[A] + with Proxy +{ + def self: PriorityQueue[A] + + /** Creates a new iterator over all elements contained in this + * object. + * + * @return the new iterator + */ + override def iterator: Iterator[A] = self.iterator + + /** Returns the length of this priority queue. + */ + override def length: Int = self.length + + /** Checks if the queue is empty. + * + * @return true, iff there is no element in the queue. + */ + override def isEmpty: Boolean = self.isEmpty + + /** Inserts a single element into the priority queue. + * + * @param elem the element to insert + */ + override def +=(elem: A): this.type = { self += elem; this } + + /** Adds all elements provided by an iterator into the priority queue. + * + * @param it an iterator + */ + override def ++=(it: TraversableOnce[A]): this.type = { + self ++= it + this + } + + /** Adds all elements to the queue. + * + * @param elems the elements to add. + */ + override def enqueue(elems: A*): Unit = self ++= elems + + /** Returns the element with the highest priority in the queue, + * and removes this element from the queue. + * + * @return the element with the highest priority. + */ + override def dequeue(): A = self.dequeue() + + /** Returns the element with the highest priority in the queue, + * or throws an error if there is no element contained in the queue. + * + * @return the element with the highest priority. + */ + override def head: A = self.head + + /** Removes all elements from the queue. After this operation is completed, + * the queue will be empty. + */ + override def clear(): Unit = self.clear() + + /** Returns a regular queue containing the same elements. + */ + override def toQueue: Queue[A] = self.toQueue + + /** This method clones the priority queue. + * + * @return a priority queue with the same elements. + */ + override def clone(): PriorityQueue[A] = new PriorityQueueProxy[A] { + def self = PriorityQueueProxy.this.self.clone() + } +} + + +/** This class implements synchronized priority queues using a binary heap. + * The elements of the queue have to be ordered in terms of the `Ordered[T]` class. + * + * @tparam A type of the elements contained in this synchronized priority queue + * @param ord implicit ordering used to compared elements of type `A` + * + * @author Matthias Zenger + * @version 1.0, 03/05/2004 + * @since 1 + * @define Coll `SynchronizedPriorityQueue` + * @define coll synchronized priority queue + */ +@deprecated("Comprehensive synchronization via selective overriding of methods is inherently unreliable. Consider java.util.concurrent.ConcurrentSkipListSet as an alternative.", "2.11.0") +sealed class SynchronizedPriorityQueue[A](implicit ord: Ordering[A]) extends PriorityQueue[A] { + + /** Checks if the queue is empty. + * + * @return true, iff there is no element in the queue. + */ + override def isEmpty: Boolean = synchronized { super.isEmpty } + + /** Inserts a single element into the priority queue. + * + * @param elem the element to insert + */ + override def +=(elem: A): this.type = { + synchronized { + super.+=(elem) + } + this + } + + /** Adds all elements of a traversable object into the priority queue. + * + * @param xs a traversable object + */ + override def ++=(xs: TraversableOnce[A]): this.type = { + synchronized { + super.++=(xs) + } + this + } + + /** Adds all elements to the queue. + * + * @param elems the elements to add. + */ + override def enqueue(elems: A*): Unit = synchronized { super.++=(elems) } + + /** Returns the element with the highest priority in the queue, + * and removes this element from the queue. + * + * @return the element with the highest priority. + */ + override def dequeue(): A = synchronized { super.dequeue() } + + /** Returns the element with the highest priority in the queue, + * or throws an error if there is no element contained in the queue. + * + * @return the element with the highest priority. + */ + override def head: A = synchronized { super.head } + + /** Removes all elements from the queue. After this operation is completed, + * the queue will be empty. + */ + override def clear(): Unit = synchronized { super.clear() } + + /** Returns an iterator which yield all the elements of the priority + * queue in descending priority order. + * + * @return an iterator over all elements sorted in descending order. + */ + override def iterator: Iterator[A] = synchronized { super.iterator } + + /** Checks if two queues are structurally identical. + * + * @return true, iff both queues contain the same sequence of elements. + */ + override def equals(that: Any): Boolean = synchronized { super.equals(that) } + + /** Returns a textual representation of a queue as a string. + * + * @return the string representation of this queue. + */ + override def toString(): String = synchronized { super.toString() } +} diff --git a/src/library/scala/collection/mutable/PriorityQueueProxy.scala b/src/library/scala/collection/mutable/PriorityQueueProxy.scala deleted file mode 100644 index b24551a6b7..0000000000 --- a/src/library/scala/collection/mutable/PriorityQueueProxy.scala +++ /dev/null @@ -1,96 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - -package scala -package collection -package mutable - -/** This class servers as a proxy for priority queues. The - * elements of the queue have to be ordered in terms of the - * `Ordered[T]` class. - * - * @author Matthias Zenger - * @version 1.0, 03/05/2004 - * @since 1 - */ -@deprecated("Proxying is deprecated due to lack of use and compiler-level support.", "2.11.0") -abstract class PriorityQueueProxy[A](implicit ord: Ordering[A]) extends PriorityQueue[A] - with Proxy -{ - def self: PriorityQueue[A] - - /** Creates a new iterator over all elements contained in this - * object. - * - * @return the new iterator - */ - override def iterator: Iterator[A] = self.iterator - - /** Returns the length of this priority queue. - */ - override def length: Int = self.length - - /** Checks if the queue is empty. - * - * @return true, iff there is no element in the queue. - */ - override def isEmpty: Boolean = self.isEmpty - - /** Inserts a single element into the priority queue. - * - * @param elem the element to insert - */ - override def +=(elem: A): this.type = { self += elem; this } - - /** Adds all elements provided by an iterator into the priority queue. - * - * @param it an iterator - */ - override def ++=(it: TraversableOnce[A]): this.type = { - self ++= it - this - } - - /** Adds all elements to the queue. - * - * @param elems the elements to add. - */ - override def enqueue(elems: A*): Unit = self ++= elems - - /** Returns the element with the highest priority in the queue, - * and removes this element from the queue. - * - * @return the element with the highest priority. - */ - override def dequeue(): A = self.dequeue() - - /** Returns the element with the highest priority in the queue, - * or throws an error if there is no element contained in the queue. - * - * @return the element with the highest priority. - */ - override def head: A = self.head - - /** Removes all elements from the queue. After this operation is completed, - * the queue will be empty. - */ - override def clear(): Unit = self.clear() - - /** Returns a regular queue containing the same elements. - */ - override def toQueue: Queue[A] = self.toQueue - - /** This method clones the priority queue. - * - * @return a priority queue with the same elements. - */ - override def clone(): PriorityQueue[A] = new PriorityQueueProxy[A] { - def self = PriorityQueueProxy.this.self.clone() - } -} diff --git a/src/library/scala/collection/mutable/SynchronizedPriorityQueue.scala b/src/library/scala/collection/mutable/SynchronizedPriorityQueue.scala deleted file mode 100644 index d3c0b85f69..0000000000 --- a/src/library/scala/collection/mutable/SynchronizedPriorityQueue.scala +++ /dev/null @@ -1,101 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala -package collection -package mutable - -/** This class implements synchronized priority queues using a binary heap. - * The elements of the queue have to be ordered in terms of the `Ordered[T]` class. - * - * @tparam A type of the elements contained in this synchronized priority queue - * @param ord implicit ordering used to compared elements of type `A` - * - * @author Matthias Zenger - * @version 1.0, 03/05/2004 - * @since 1 - * @define Coll `SynchronizedPriorityQueue` - * @define coll synchronized priority queue - */ -@deprecated("Comprehensive synchronization via selective overriding of methods is inherently unreliable. Consider java.util.concurrent.ConcurrentSkipListSet as an alternative.", "2.11.0") -class SynchronizedPriorityQueue[A](implicit ord: Ordering[A]) extends PriorityQueue[A] { - - /** Checks if the queue is empty. - * - * @return true, iff there is no element in the queue. - */ - override def isEmpty: Boolean = synchronized { super.isEmpty } - - /** Inserts a single element into the priority queue. - * - * @param elem the element to insert - */ - override def +=(elem: A): this.type = { - synchronized { - super.+=(elem) - } - this - } - - /** Adds all elements of a traversable object into the priority queue. - * - * @param xs a traversable object - */ - override def ++=(xs: TraversableOnce[A]): this.type = { - synchronized { - super.++=(xs) - } - this - } - - /** Adds all elements to the queue. - * - * @param elems the elements to add. - */ - override def enqueue(elems: A*): Unit = synchronized { super.++=(elems) } - - /** Returns the element with the highest priority in the queue, - * and removes this element from the queue. - * - * @return the element with the highest priority. - */ - override def dequeue(): A = synchronized { super.dequeue() } - - /** Returns the element with the highest priority in the queue, - * or throws an error if there is no element contained in the queue. - * - * @return the element with the highest priority. - */ - override def head: A = synchronized { super.head } - - /** Removes all elements from the queue. After this operation is completed, - * the queue will be empty. - */ - override def clear(): Unit = synchronized { super.clear() } - - /** Returns an iterator which yield all the elements of the priority - * queue in descending priority order. - * - * @return an iterator over all elements sorted in descending order. - */ - override def iterator: Iterator[A] = synchronized { super.iterator } - - /** Checks if two queues are structurally identical. - * - * @return true, iff both queues contain the same sequence of elements. - */ - override def equals(that: Any): Boolean = synchronized { super.equals(that) } - - /** Returns a textual representation of a queue as a string. - * - * @return the string representation of this queue. - */ - override def toString(): String = synchronized { super.toString() } -} diff --git a/src/library/scala/collection/mutable/UnrolledBuffer.scala b/src/library/scala/collection/mutable/UnrolledBuffer.scala index 2212486bcf..b49d009a17 100644 --- a/src/library/scala/collection/mutable/UnrolledBuffer.scala +++ b/src/library/scala/collection/mutable/UnrolledBuffer.scala @@ -43,8 +43,7 @@ import scala.reflect.ClassTag * */ @SerialVersionUID(1L) -@deprecatedInheritance("UnrolledBuffer is not designed to enable meaningful subclassing.", "2.11.0") -class UnrolledBuffer[T](implicit val tag: ClassTag[T]) +sealed class UnrolledBuffer[T](implicit val tag: ClassTag[T]) extends scala.collection.mutable.AbstractBuffer[T] with scala.collection.mutable.Buffer[T] with scala.collection.mutable.BufferLike[T, UnrolledBuffer[T]] @@ -350,3 +349,11 @@ object UnrolledBuffer extends ClassTagTraversableFactory[UnrolledBuffer] { } } + + +// This is used by scala.collection.parallel.mutable.UnrolledParArrayCombiner: +// Todo -- revisit whether inheritance is the best way to achieve this functionality +private[collection] class DoublingUnrolledBuffer[T](implicit t: ClassTag[T]) extends UnrolledBuffer[T]()(t) { + override def calcNextLength(sz: Int) = if (sz < 10000) sz * 2 else sz + protected override def newUnrolled = new UnrolledBuffer.Unrolled[T](0, new Array[T](4), null, this) +} diff --git a/src/library/scala/collection/parallel/mutable/UnrolledParArrayCombiner.scala b/src/library/scala/collection/parallel/mutable/UnrolledParArrayCombiner.scala index 5e4572da60..d53b56d484 100644 --- a/src/library/scala/collection/parallel/mutable/UnrolledParArrayCombiner.scala +++ b/src/library/scala/collection/parallel/mutable/UnrolledParArrayCombiner.scala @@ -10,18 +10,12 @@ package scala package collection.parallel.mutable import scala.collection.mutable.ArraySeq -import scala.collection.mutable.UnrolledBuffer +import scala.collection.mutable.DoublingUnrolledBuffer import scala.collection.mutable.UnrolledBuffer.Unrolled import scala.collection.parallel.Combiner import scala.collection.parallel.Task import scala.reflect.ClassTag -// Todo -- revisit whether inheritance is the best way to achieve this functionality -private[mutable] class DoublingUnrolledBuffer[T](implicit t: ClassTag[T]) extends UnrolledBuffer[T]()(t) { - override def calcNextLength(sz: Int) = if (sz < 10000) sz * 2 else sz - protected override def newUnrolled = new Unrolled[T](0, new Array[T](4), null, this) -} - /** An array combiner that uses doubling unrolled buffers to store elements. */ trait UnrolledParArrayCombiner[T] diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala index dd242e6b3b..6b24c0f568 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala @@ -30,17 +30,26 @@ class IndexScript(universe: doc.Universe) extends Page { case (pack, templates) => { val merged = mergeByQualifiedName(templates) - val ary = merged.keys.toList.sortBy(_.toLowerCase).map(key => { + val ary = merged.keys.toList.sortBy(_.toLowerCase).map { key => + /** One pair is generated for the class/trait and one for the + * companion object, both will have the same {"name": key} + * + * As such, we need to distinguish between the members that are + * generated by the object, and the members generated by the + * class/trait instance. Otherwise one of the member objects will be + * overwritten. + */ val pairs = merged(key).flatMap { t: DocTemplateEntity => + val kind = kindToString(t) Seq( - kindToString(t) -> relativeLinkTo(t), - "kind" -> kindToString(t), - "members" -> membersToJSON(t.members.filter(!_.isShadowedOrAmbiguousImplicit)), + kind -> relativeLinkTo(t), + "kind" -> kind, + s"members_$kind" -> membersToJSON(t.members.filter(!_.isShadowedOrAmbiguousImplicit), t), "shortDescription" -> shortDesc(t)) } JSONObject(Map(pairs : _*) + ("name" -> key)) - }) + } pack.qualifiedName -> JSONArray(ary) } @@ -83,10 +92,10 @@ class IndexScript(universe: doc.Universe) extends Page { } /** Returns the json representation of the supplied members */ - def membersToJSON(entities: List[MemberEntity]): JSONType = - JSONArray(entities map memberToJSON) + def membersToJSON(entities: List[MemberEntity], parent: DocTemplateEntity): JSONType = + JSONArray(entities map (memberToJSON(_, parent))) - private def memberToJSON(mbr: MemberEntity): JSONObject = { + private def memberToJSON(mbr: MemberEntity, parent: DocTemplateEntity): JSONObject = { /** This function takes a member and gets eventual parameters and the * return type. For example, the definition: * {{{ def get(key: A): Option[B] }}} @@ -100,6 +109,7 @@ class IndexScript(universe: doc.Universe) extends Page { } .mkString("(", ")(", "): " + d.resultType.name) case v: Val => ": " + v.resultType.name + case _ => "" } /** This function takes a member entity and return all modifiers in a @@ -119,15 +129,15 @@ class IndexScript(universe: doc.Universe) extends Page { */ def jsonObject(m: MemberEntity): JSONObject = JSONObject(Map( - "label" -> m.definitionName.replaceAll(".*#", ""), // member name + "label" -> "[^\\.]*\\.([^#]+#)?".r.replaceAllIn(m.definitionName, ""), // member name "member" -> m.definitionName.replaceFirst("#", "."), // full member name "tail" -> memberTail(m), - "kind" -> memberKindToString(m), // modifiers i.e. "abstract def" - "link" -> memberToUrl(m))) // permalink to the member + "kind" -> memberKindToString(m), // modifiers i.e. "abstract def" + "link" -> memberToUrl(m))) // permalink to the member mbr match { - case d: Def => jsonObject(d) - case v: Val => jsonObject(v) + case x @ (_: Def | _: Val | _: Object | _: AliasType) => jsonObject(x) + case e @ (_: Class | _: Trait) if parent.isRootPackage || !parent.isPackage => jsonObject(e) case m: MemberEntity => JSONObject(Map("member" -> m.definitionName, "error" -> "unsupported entity")) } diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.js b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.js index 55224eae52..5d72b9bf71 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.js +++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.js @@ -21,6 +21,20 @@ var Index = {}; } })(Index); +/** Find query string from URL */ +var QueryString = function(key) { + if (QueryString.map === undefined) { // only calc once + QueryString.map = {}; + var keyVals = window.location.search.split("?").pop().split("&"); + keyVals.forEach(function(elem) { + var pair = elem.split("="); + if (pair.length == 2) QueryString.map[pair[0]] = pair[1]; + }); + } + + return QueryString.map[key]; +}; + $(document).ready(function() { // Clicking #doc-title returns the user to the root package $("#doc-title").click(function() { document.location = toRoot + "index.html" }); @@ -39,6 +53,11 @@ $(document).ready(function() { else $("#textfilter > .input > .clear").hide(); }); + + if (QueryString("search") !== undefined) { + $("#index-input").val(QueryString("search")); + searchAll(); + } }); /* Handles all key presses while scrolling around with keyboard shortcuts in search results */ @@ -412,7 +431,12 @@ function handleSearchedPackage(res, regExp) { */ function searchEntity(entity, ul, regExp) { return new Promise(function(resolve, reject) { - var matchingMembers = $.grep(entity.members, function(member, i) { + var allMembers = + (entity.members_trait || []) + .concat(entity.members_class || []) + .concat(entity.members_object || []) + + var matchingMembers = $.grep(allMembers, function(member, i) { return regExp.test(member.label); }); @@ -510,6 +534,11 @@ function searchAll() { return; } + // Replace ?search=X with current search string if not hosted locally on Chrome + try { + window.history.replaceState({}, "", "?search=" + searchStr); + } catch(e) {} + $("div#results-content > span.search-text").remove(); var memberResults = document.getElementById("member-results"); |