diff options
Diffstat (limited to 'src/library')
88 files changed, 641 insertions, 311 deletions
diff --git a/src/library/scala/Array.scala b/src/library/scala/Array.scala index 7f3200b90a..5d1c25732c 100644 --- a/src/library/scala/Array.scala +++ b/src/library/scala/Array.scala @@ -11,7 +11,6 @@ package scala import scala.collection.generic._ import scala.collection.{ mutable, immutable } import mutable.{ ArrayBuilder, ArraySeq } -import scala.compat.Platform.arraycopy import scala.reflect.ClassTag import scala.runtime.ScalaRunTime.{ array_apply, array_update } @@ -102,7 +101,7 @@ object Array extends FallbackArrayBuilding { def copy(src: AnyRef, srcPos: Int, dest: AnyRef, destPos: Int, length: Int) { val srcClass = src.getClass if (srcClass.isArray && dest.getClass.isAssignableFrom(srcClass)) - arraycopy(src, srcPos, dest, destPos, length) + java.lang.System.arraycopy(src, srcPos, dest, destPos, length) else slowcopy(src, srcPos, dest, destPos, length) } @@ -496,16 +495,6 @@ object Array extends FallbackArrayBuilding { * @hideImplicitConversion scala.Predef.refArrayOps * @hideImplicitConversion scala.Predef.shortArrayOps * @hideImplicitConversion scala.Predef.unitArrayOps - * @hideImplicitConversion scala.Predef._booleanArrayOps - * @hideImplicitConversion scala.Predef._byteArrayOps - * @hideImplicitConversion scala.Predef._charArrayOps - * @hideImplicitConversion scala.Predef._doubleArrayOps - * @hideImplicitConversion scala.Predef._floatArrayOps - * @hideImplicitConversion scala.Predef._intArrayOps - * @hideImplicitConversion scala.Predef._longArrayOps - * @hideImplicitConversion scala.Predef._refArrayOps - * @hideImplicitConversion scala.Predef._shortArrayOps - * @hideImplicitConversion scala.Predef._unitArrayOps * @hideImplicitConversion scala.LowPriorityImplicits.wrapRefArray * @hideImplicitConversion scala.LowPriorityImplicits.wrapIntArray * @hideImplicitConversion scala.LowPriorityImplicits.wrapDoubleArray diff --git a/src/library/scala/Immutable.scala b/src/library/scala/Immutable.scala index fead590ef6..c7e96a46a0 100644 --- a/src/library/scala/Immutable.scala +++ b/src/library/scala/Immutable.scala @@ -10,7 +10,7 @@ package scala -/** A marker trait for all immutable datastructures such as immutable +/** A marker trait for all immutable data structures such as immutable * collections. * * @since 2.8 diff --git a/src/library/scala/Int.scala b/src/library/scala/Int.scala index b605af5e37..491094cfde 100644 --- a/src/library/scala/Int.scala +++ b/src/library/scala/Int.scala @@ -439,10 +439,10 @@ final abstract class Int private extends AnyVal { } object Int extends AnyValCompanion { - /** The smallest value representable as a Int. */ + /** The smallest value representable as an Int. */ final val MinValue = java.lang.Integer.MIN_VALUE - /** The largest value representable as a Int. */ + /** The largest value representable as an Int. */ final val MaxValue = java.lang.Integer.MAX_VALUE /** Transform a value type into a boxed reference type. diff --git a/src/library/scala/Option.scala b/src/library/scala/Option.scala index 39c583e63b..c7894a45b8 100644 --- a/src/library/scala/Option.scala +++ b/src/library/scala/Option.scala @@ -107,7 +107,7 @@ sealed abstract class Option[+A] extends Product with Serializable { def isDefined: Boolean = !isEmpty /** Returns the option's value. - * @note The option must be nonEmpty. + * @note The option must be nonempty. * @throws java.util.NoSuchElementException if the option is empty. */ def get: A diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index 8de9754b50..b79fa9d732 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -337,8 +337,16 @@ object Predef extends LowPriorityImplicits with DeprecatedPredef { @deprecated("use Throwable#getStackTrace", "2.11.0") def getStackTraceString = self.getStackTrace().mkString("", EOL, EOL) } + // Sadly we have to do `@deprecatedName(null, "2.12.0")` because + // `@deprecatedName(since="2.12.0")` incurs a warning about + // Usage of named or default arguments transformed this annotation constructor call into a block. + // The corresponding AnnotationInfo will contain references to local values and default getters + // instead of the actual argument trees + // and `@deprecatedName(Symbol("<none>"), "2.12.0")` crashes scalac with + // scala.reflect.internal.Symbols$CyclicReference: illegal cyclic reference involving object Symbol + // in run/repl-no-imports-no-predef-power.scala. /** @group implicit-classes-char */ - implicit final class SeqCharSequence(val __sequenceOfChars: scala.collection.IndexedSeq[Char]) extends CharSequence { + implicit final class SeqCharSequence(@deprecated("will be made private", "2.12.0") @deprecatedName(null, "2.12.0") val __sequenceOfChars: scala.collection.IndexedSeq[Char]) extends CharSequence { def length: Int = __sequenceOfChars.length def charAt(index: Int): Char = __sequenceOfChars(index) def subSequence(start: Int, end: Int): CharSequence = new SeqCharSequence(__sequenceOfChars.slice(start, end)) @@ -346,7 +354,7 @@ object Predef extends LowPriorityImplicits with DeprecatedPredef { } /** @group implicit-classes-char */ - implicit final class ArrayCharSequence(val __arrayOfChars: Array[Char]) extends CharSequence { + implicit final class ArrayCharSequence(@deprecated("will be made private", "2.12.0") @deprecatedName(null, "2.12.0") val __arrayOfChars: Array[Char]) extends CharSequence { def length: Int = __arrayOfChars.length def charAt(index: Int): Char = __arrayOfChars(index) def subSequence(start: Int, end: Int): CharSequence = new runtime.ArrayCharSequence(__arrayOfChars, start, end) @@ -420,28 +428,16 @@ object Predef extends LowPriorityImplicits with DeprecatedPredef { case null => null }).asInstanceOf[ArrayOps[T]] - // TODO: when we remove, these should we drop the underscores from the new generation below? (For source compatibility in case someone was shadowing these.) - @deprecated("For binary compatibility only. Release new partest and remove in M3.", "2.12.0-M2") def booleanArrayOps(xs: Array[Boolean]): ArrayOps[Boolean] = new ArrayOps.ofBoolean(xs) - @deprecated("For binary compatibility only. Release new partest and remove in M3.", "2.12.0-M2") def byteArrayOps(xs: Array[Byte]): ArrayOps[Byte] = new ArrayOps.ofByte(xs) - @deprecated("For binary compatibility only. Release new partest and remove in M3.", "2.12.0-M2") def charArrayOps(xs: Array[Char]): ArrayOps[Char] = new ArrayOps.ofChar(xs) - @deprecated("For binary compatibility only. Release new partest and remove in M3.", "2.12.0-M2") def doubleArrayOps(xs: Array[Double]): ArrayOps[Double] = new ArrayOps.ofDouble(xs) - @deprecated("For binary compatibility only. Release new partest and remove in M3.", "2.12.0-M2") def floatArrayOps(xs: Array[Float]): ArrayOps[Float] = new ArrayOps.ofFloat(xs) - @deprecated("For binary compatibility only. Release new partest and remove in M3.", "2.12.0-M2") def intArrayOps(xs: Array[Int]): ArrayOps[Int] = new ArrayOps.ofInt(xs) - @deprecated("For binary compatibility only. Release new partest and remove in M3.", "2.12.0-M2") def longArrayOps(xs: Array[Long]): ArrayOps[Long] = new ArrayOps.ofLong(xs) - @deprecated("For binary compatibility only. Release new partest and remove in M3.", "2.12.0-M2") def refArrayOps[T <: AnyRef](xs: Array[T]): ArrayOps[T] = new ArrayOps.ofRef[T](xs) - @deprecated("For binary compatibility only. Release new partest and remove in M3.", "2.12.0-M2") def shortArrayOps(xs: Array[Short]): ArrayOps[Short] = new ArrayOps.ofShort(xs) - @deprecated("For binary compatibility only. Release new partest and remove in M3.", "2.12.0-M2") def unitArrayOps(xs: Array[Unit]): ArrayOps[Unit] = new ArrayOps.ofUnit(xs) - - implicit def _booleanArrayOps(xs: Array[Boolean]): ArrayOps.ofBoolean = new ArrayOps.ofBoolean(xs) - implicit def _byteArrayOps(xs: Array[Byte]): ArrayOps.ofByte = new ArrayOps.ofByte(xs) - implicit def _charArrayOps(xs: Array[Char]): ArrayOps.ofChar = new ArrayOps.ofChar(xs) - implicit def _doubleArrayOps(xs: Array[Double]): ArrayOps.ofDouble = new ArrayOps.ofDouble(xs) - implicit def _floatArrayOps(xs: Array[Float]): ArrayOps.ofFloat = new ArrayOps.ofFloat(xs) - implicit def _intArrayOps(xs: Array[Int]): ArrayOps.ofInt = new ArrayOps.ofInt(xs) - implicit def _longArrayOps(xs: Array[Long]): ArrayOps.ofLong = new ArrayOps.ofLong(xs) - implicit def _refArrayOps[T <: AnyRef](xs: Array[T]): ArrayOps.ofRef[T] = new ArrayOps.ofRef[T](xs) - implicit def _shortArrayOps(xs: Array[Short]): ArrayOps.ofShort = new ArrayOps.ofShort(xs) - implicit def _unitArrayOps(xs: Array[Unit]): ArrayOps.ofUnit = new ArrayOps.ofUnit(xs) + implicit def booleanArrayOps(xs: Array[Boolean]): ArrayOps.ofBoolean = new ArrayOps.ofBoolean(xs) + implicit def byteArrayOps(xs: Array[Byte]): ArrayOps.ofByte = new ArrayOps.ofByte(xs) + implicit def charArrayOps(xs: Array[Char]): ArrayOps.ofChar = new ArrayOps.ofChar(xs) + implicit def doubleArrayOps(xs: Array[Double]): ArrayOps.ofDouble = new ArrayOps.ofDouble(xs) + implicit def floatArrayOps(xs: Array[Float]): ArrayOps.ofFloat = new ArrayOps.ofFloat(xs) + implicit def intArrayOps(xs: Array[Int]): ArrayOps.ofInt = new ArrayOps.ofInt(xs) + implicit def longArrayOps(xs: Array[Long]): ArrayOps.ofLong = new ArrayOps.ofLong(xs) + implicit def refArrayOps[T <: AnyRef](xs: Array[T]): ArrayOps.ofRef[T] = new ArrayOps.ofRef[T](xs) + implicit def shortArrayOps(xs: Array[Short]): ArrayOps.ofShort = new ArrayOps.ofShort(xs) + implicit def unitArrayOps(xs: Array[Unit]): ArrayOps.ofUnit = new ArrayOps.ofUnit(xs) // "Autoboxing" and "Autounboxing" --------------------------------------------------- diff --git a/src/library/scala/Product1.scala b/src/library/scala/Product1.scala index e82300adf6..3b0194e41f 100644 --- a/src/library/scala/Product1.scala +++ b/src/library/scala/Product1.scala @@ -14,7 +14,7 @@ object Product1 { Some(x) } -/** Product1 is a cartesian product of 1 component. +/** Product1 is a Cartesian product of 1 component. * @since 2.3 */ trait Product1[@specialized(Int, Long, Double) +T1] extends Any with Product { diff --git a/src/library/scala/Product10.scala b/src/library/scala/Product10.scala index 5fc4874048..8826d95007 100644 --- a/src/library/scala/Product10.scala +++ b/src/library/scala/Product10.scala @@ -14,7 +14,7 @@ object Product10 { Some(x) } -/** Product10 is a cartesian product of 10 components. +/** Product10 is a Cartesian product of 10 components. * @since 2.3 */ trait Product10[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10] extends Any with Product { diff --git a/src/library/scala/Product11.scala b/src/library/scala/Product11.scala index dcebc90e3e..2a846fff4e 100644 --- a/src/library/scala/Product11.scala +++ b/src/library/scala/Product11.scala @@ -14,7 +14,7 @@ object Product11 { Some(x) } -/** Product11 is a cartesian product of 11 components. +/** Product11 is a Cartesian product of 11 components. * @since 2.3 */ trait Product11[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11] extends Any with Product { diff --git a/src/library/scala/Product12.scala b/src/library/scala/Product12.scala index 2221170452..87419048d6 100644 --- a/src/library/scala/Product12.scala +++ b/src/library/scala/Product12.scala @@ -14,7 +14,7 @@ object Product12 { Some(x) } -/** Product12 is a cartesian product of 12 components. +/** Product12 is a Cartesian product of 12 components. * @since 2.3 */ trait Product12[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12] extends Any with Product { diff --git a/src/library/scala/Product13.scala b/src/library/scala/Product13.scala index e76f326766..a944279a2e 100644 --- a/src/library/scala/Product13.scala +++ b/src/library/scala/Product13.scala @@ -14,7 +14,7 @@ object Product13 { Some(x) } -/** Product13 is a cartesian product of 13 components. +/** Product13 is a Cartesian product of 13 components. * @since 2.3 */ trait Product13[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13] extends Any with Product { diff --git a/src/library/scala/Product14.scala b/src/library/scala/Product14.scala index a076e2cc7a..098721f216 100644 --- a/src/library/scala/Product14.scala +++ b/src/library/scala/Product14.scala @@ -14,7 +14,7 @@ object Product14 { Some(x) } -/** Product14 is a cartesian product of 14 components. +/** Product14 is a Cartesian product of 14 components. * @since 2.3 */ trait Product14[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14] extends Any with Product { diff --git a/src/library/scala/Product15.scala b/src/library/scala/Product15.scala index 4568aff1fe..ef550c80d2 100644 --- a/src/library/scala/Product15.scala +++ b/src/library/scala/Product15.scala @@ -14,7 +14,7 @@ object Product15 { Some(x) } -/** Product15 is a cartesian product of 15 components. +/** Product15 is a Cartesian product of 15 components. * @since 2.3 */ trait Product15[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15] extends Any with Product { diff --git a/src/library/scala/Product16.scala b/src/library/scala/Product16.scala index 84dccb0ac8..dd32e2f637 100644 --- a/src/library/scala/Product16.scala +++ b/src/library/scala/Product16.scala @@ -14,7 +14,7 @@ object Product16 { Some(x) } -/** Product16 is a cartesian product of 16 components. +/** Product16 is a Cartesian product of 16 components. * @since 2.3 */ trait Product16[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16] extends Any with Product { diff --git a/src/library/scala/Product17.scala b/src/library/scala/Product17.scala index 0d50898bf4..e97cc5189e 100644 --- a/src/library/scala/Product17.scala +++ b/src/library/scala/Product17.scala @@ -14,7 +14,7 @@ object Product17 { Some(x) } -/** Product17 is a cartesian product of 17 components. +/** Product17 is a Cartesian product of 17 components. * @since 2.3 */ trait Product17[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17] extends Any with Product { diff --git a/src/library/scala/Product18.scala b/src/library/scala/Product18.scala index 9b32265d71..1266b77a9f 100644 --- a/src/library/scala/Product18.scala +++ b/src/library/scala/Product18.scala @@ -14,7 +14,7 @@ object Product18 { Some(x) } -/** Product18 is a cartesian product of 18 components. +/** Product18 is a Cartesian product of 18 components. * @since 2.3 */ trait Product18[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18] extends Any with Product { diff --git a/src/library/scala/Product19.scala b/src/library/scala/Product19.scala index fe6b95669b..4bf5dcf23e 100644 --- a/src/library/scala/Product19.scala +++ b/src/library/scala/Product19.scala @@ -14,7 +14,7 @@ object Product19 { Some(x) } -/** Product19 is a cartesian product of 19 components. +/** Product19 is a Cartesian product of 19 components. * @since 2.3 */ trait Product19[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19] extends Any with Product { diff --git a/src/library/scala/Product2.scala b/src/library/scala/Product2.scala index 091bcc89de..93144abeb3 100644 --- a/src/library/scala/Product2.scala +++ b/src/library/scala/Product2.scala @@ -14,7 +14,7 @@ object Product2 { Some(x) } -/** Product2 is a cartesian product of 2 components. +/** Product2 is a Cartesian product of 2 components. * @since 2.3 */ trait Product2[@specialized(Int, Long, Double) +T1, @specialized(Int, Long, Double) +T2] extends Any with Product { diff --git a/src/library/scala/Product20.scala b/src/library/scala/Product20.scala index 81315e3558..a1dfd469ad 100644 --- a/src/library/scala/Product20.scala +++ b/src/library/scala/Product20.scala @@ -14,7 +14,7 @@ object Product20 { Some(x) } -/** Product20 is a cartesian product of 20 components. +/** Product20 is a Cartesian product of 20 components. * @since 2.3 */ trait Product20[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19, +T20] extends Any with Product { diff --git a/src/library/scala/Product21.scala b/src/library/scala/Product21.scala index b5967c06e1..4f01277ad3 100644 --- a/src/library/scala/Product21.scala +++ b/src/library/scala/Product21.scala @@ -14,7 +14,7 @@ object Product21 { Some(x) } -/** Product21 is a cartesian product of 21 components. +/** Product21 is a Cartesian product of 21 components. * @since 2.3 */ trait Product21[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19, +T20, +T21] extends Any with Product { diff --git a/src/library/scala/Product22.scala b/src/library/scala/Product22.scala index c7b9da5ce8..cef8d30402 100644 --- a/src/library/scala/Product22.scala +++ b/src/library/scala/Product22.scala @@ -14,7 +14,7 @@ object Product22 { Some(x) } -/** Product22 is a cartesian product of 22 components. +/** Product22 is a Cartesian product of 22 components. * @since 2.3 */ trait Product22[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19, +T20, +T21, +T22] extends Any with Product { diff --git a/src/library/scala/Product3.scala b/src/library/scala/Product3.scala index 7154bf5bdf..7da324106d 100644 --- a/src/library/scala/Product3.scala +++ b/src/library/scala/Product3.scala @@ -14,7 +14,7 @@ object Product3 { Some(x) } -/** Product3 is a cartesian product of 3 components. +/** Product3 is a Cartesian product of 3 components. * @since 2.3 */ trait Product3[+T1, +T2, +T3] extends Any with Product { diff --git a/src/library/scala/Product4.scala b/src/library/scala/Product4.scala index 046f8c7a7c..88e5dea9d3 100644 --- a/src/library/scala/Product4.scala +++ b/src/library/scala/Product4.scala @@ -14,7 +14,7 @@ object Product4 { Some(x) } -/** Product4 is a cartesian product of 4 components. +/** Product4 is a Cartesian product of 4 components. * @since 2.3 */ trait Product4[+T1, +T2, +T3, +T4] extends Any with Product { diff --git a/src/library/scala/Product5.scala b/src/library/scala/Product5.scala index 3e952c8c55..d8c3ffc190 100644 --- a/src/library/scala/Product5.scala +++ b/src/library/scala/Product5.scala @@ -14,7 +14,7 @@ object Product5 { Some(x) } -/** Product5 is a cartesian product of 5 components. +/** Product5 is a Cartesian product of 5 components. * @since 2.3 */ trait Product5[+T1, +T2, +T3, +T4, +T5] extends Any with Product { diff --git a/src/library/scala/Product6.scala b/src/library/scala/Product6.scala index 010c68711a..ab50d678fc 100644 --- a/src/library/scala/Product6.scala +++ b/src/library/scala/Product6.scala @@ -14,7 +14,7 @@ object Product6 { Some(x) } -/** Product6 is a cartesian product of 6 components. +/** Product6 is a Cartesian product of 6 components. * @since 2.3 */ trait Product6[+T1, +T2, +T3, +T4, +T5, +T6] extends Any with Product { diff --git a/src/library/scala/Product7.scala b/src/library/scala/Product7.scala index 24e5a5c05a..efdeb142d1 100644 --- a/src/library/scala/Product7.scala +++ b/src/library/scala/Product7.scala @@ -14,7 +14,7 @@ object Product7 { Some(x) } -/** Product7 is a cartesian product of 7 components. +/** Product7 is a Cartesian product of 7 components. * @since 2.3 */ trait Product7[+T1, +T2, +T3, +T4, +T5, +T6, +T7] extends Any with Product { diff --git a/src/library/scala/Product8.scala b/src/library/scala/Product8.scala index 4a9f65b00e..743c0ac485 100644 --- a/src/library/scala/Product8.scala +++ b/src/library/scala/Product8.scala @@ -14,7 +14,7 @@ object Product8 { Some(x) } -/** Product8 is a cartesian product of 8 components. +/** Product8 is a Cartesian product of 8 components. * @since 2.3 */ trait Product8[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8] extends Any with Product { diff --git a/src/library/scala/Product9.scala b/src/library/scala/Product9.scala index 9af11f709a..8d04213cd9 100644 --- a/src/library/scala/Product9.scala +++ b/src/library/scala/Product9.scala @@ -14,7 +14,7 @@ object Product9 { Some(x) } -/** Product9 is a cartesian product of 9 components. +/** Product9 is a Cartesian product of 9 components. * @since 2.3 */ trait Product9[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9] extends Any with Product { diff --git a/src/library/scala/collection/GenTraversableLike.scala b/src/library/scala/collection/GenTraversableLike.scala index d730996be2..1cd126f94f 100644 --- a/src/library/scala/collection/GenTraversableLike.scala +++ b/src/library/scala/collection/GenTraversableLike.scala @@ -24,7 +24,7 @@ import scala.annotation.migration * is found. * @define bfinfo an implicit value of class `CanBuildFrom` which determines * the result class `That` from the current representation type `Repr` and - * and the new element type `B`. + * the new element type `B`. * @define orderDependent * * Note: might return different results for different runs, unless the diff --git a/src/library/scala/collection/GenTraversableOnce.scala b/src/library/scala/collection/GenTraversableOnce.scala index 4af2ca23be..f87f7654bc 100644 --- a/src/library/scala/collection/GenTraversableOnce.scala +++ b/src/library/scala/collection/GenTraversableOnce.scala @@ -96,6 +96,12 @@ trait GenTraversableOnce[+A] extends Any { */ def size: Int + /** The size of this $coll, if it can be cheaply computed + * + * @return the number of elements in this $coll, or -1 if the size cannot be determined cheaply + */ + protected[collection] def sizeHintIfCheap: Int = -1 + /** Tests whether the $coll is empty. * * Note: Implementations in subclasses that are not repeatedly traversable must take diff --git a/src/library/scala/collection/IndexedSeqLike.scala b/src/library/scala/collection/IndexedSeqLike.scala index f4bf58ffe3..f0cede224d 100644 --- a/src/library/scala/collection/IndexedSeqLike.scala +++ b/src/library/scala/collection/IndexedSeqLike.scala @@ -92,4 +92,6 @@ trait IndexedSeqLike[+A, +Repr] extends Any with SeqLike[A, Repr] { copyToBuffer(result) result } + + override protected[collection] def sizeHintIfCheap: Int = size } diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala index 1426278954..d000d22f72 100644 --- a/src/library/scala/collection/Iterator.scala +++ b/src/library/scala/collection/Iterator.scala @@ -686,15 +686,15 @@ trait Iterator[+A] extends TraversableOnce[A] { * handling of structural calls. It's not what's intended here. */ class Leading extends AbstractIterator[A] { - var lookahead: mutable.Queue[A] = null - var hd: A = _ + private[this] var lookahead: mutable.Queue[A] = null + private[this] var hd: A = _ /* Status is kept with magic numbers * 1 means next element is in hd and we're still reading into this iterator * 0 means we're still reading but haven't found a next element * -1 means we are done reading into the iterator, so we must rely on lookahead * -2 means we are done but have saved hd for the other iterator to use as its first element */ - var status = 0 + private[this] var status = 0 private def store(a: A) { if (lookahead == null) lookahead = new mutable.Queue[A] lookahead += a @@ -718,34 +718,31 @@ trait Iterator[+A] extends TraversableOnce[A] { } else empty.next() } - def finish(): Boolean = { - if (status == -1) false - else if (status == -2) { + def finish(): Boolean = status match { + case -2 => status = -1 ; true + case -1 => false + case 1 => store(hd) ; status = 0 ; finish() + case 0 => status = -1 - true - } - else { - if (status == 1) store(hd) while (self.hasNext) { val a = self.next() if (p(a)) store(a) else { hd = a - status = -1 return true } } false - } } + def trailer: A = hd } val leading = new Leading val trailing = new AbstractIterator[A] { private[this] var myLeading = leading - /* Status flags meanings: - * -1 not yet accesssed + /* Status flag meanings: + * -1 not yet accessed * 0 single element waiting in leading * 1 defer to self */ @@ -770,7 +767,7 @@ trait Iterator[+A] extends TraversableOnce[A] { if (status > 0) self.next() else { status = 1 - val ans = myLeading.hd + val ans = myLeading.trailer myLeading = null ans } diff --git a/src/library/scala/collection/JavaConversions.scala b/src/library/scala/collection/JavaConversions.scala index 960e452cdf..93994d80bf 100644 --- a/src/library/scala/collection/JavaConversions.scala +++ b/src/library/scala/collection/JavaConversions.scala @@ -56,5 +56,5 @@ import convert._ * @author Martin Odersky * @since 2.8 */ -@deprecated("Use JavaConverters", since="2.12") +@deprecated("use JavaConverters", since="2.12.0") object JavaConversions extends WrapAsScala with WrapAsJava diff --git a/src/library/scala/collection/Parallelizable.scala b/src/library/scala/collection/Parallelizable.scala index b737752458..c131556388 100644 --- a/src/library/scala/collection/Parallelizable.scala +++ b/src/library/scala/collection/Parallelizable.scala @@ -12,7 +12,7 @@ package collection import parallel.Combiner /** This trait describes collections which can be turned into parallel collections - * by invoking the method `par`. Parallelizable collections may be parametrized with + * by invoking the method `par`. Parallelizable collections may be parameterized with * a target type different than their own. * * @tparam A the type of the elements in the collection diff --git a/src/library/scala/collection/SeqLike.scala b/src/library/scala/collection/SeqLike.scala index a26765027c..2d662257e5 100644 --- a/src/library/scala/collection/SeqLike.scala +++ b/src/library/scala/collection/SeqLike.scala @@ -113,7 +113,7 @@ trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[ } def indexWhere(p: A => Boolean, from: Int): Int = { - var i = from + var i = from max 0 val it = iterator.drop(from) while (it.hasNext) { if (p(it.next())) return i diff --git a/src/library/scala/collection/SetLike.scala b/src/library/scala/collection/SetLike.scala index 9143c40870..440452ce99 100644 --- a/src/library/scala/collection/SetLike.scala +++ b/src/library/scala/collection/SetLike.scala @@ -213,9 +213,9 @@ self => } } - /** An Iterator include all subsets containing exactly len elements. + /** An Iterator including all subsets containing exactly len elements. * If the elements in 'This' type is ordered, then the subsets will also be in the same order. - * ListSet(1,2,3).subsets => {1},{2},{3},{1,2},{1,3},{2,3},{1,2,3}} + * ListSet(1,2,3).subsets => {{1},{2},{3},{1,2},{1,3},{2,3},{1,2,3}} * * @author Eastsun * @date 2010.12.6 diff --git a/src/library/scala/collection/SortedSet.scala b/src/library/scala/collection/SortedSet.scala index 43189d2e8c..0fa5ce0966 100644 --- a/src/library/scala/collection/SortedSet.scala +++ b/src/library/scala/collection/SortedSet.scala @@ -29,6 +29,6 @@ trait SortedSet[A] extends Set[A] with SortedSetLike[A, SortedSet[A]] { object SortedSet extends SortedSetFactory[SortedSet] { def empty[A](implicit ord: Ordering[A]): immutable.SortedSet[A] = immutable.SortedSet.empty[A](ord) def canBuildFrom[A](implicit ord: Ordering[A]): CanBuildFrom[Coll, A, SortedSet[A]] = newCanBuildFrom[A] - // Force a declaration here so that BitSet's (which does not inherit from SortedSetFactory) can be more specific + // Force a declaration here so that BitSet (which does not inherit from SortedSetFactory) can be more specific override implicit def newCanBuildFrom[A](implicit ord : Ordering[A]) : CanBuildFrom[Coll, A, SortedSet[A]] = super.newCanBuildFrom } diff --git a/src/library/scala/collection/TraversableLike.scala b/src/library/scala/collection/TraversableLike.scala index d914f2e0ff..c9482fe0a2 100644 --- a/src/library/scala/collection/TraversableLike.scala +++ b/src/library/scala/collection/TraversableLike.scala @@ -605,13 +605,69 @@ trait TraversableLike[+A, +Repr] extends Any * applied to this $coll. By default the string prefix is the * simple name of the collection class $coll. */ - def stringPrefix : String = { - var string = repr.getClass.getName - val idx1 = string.lastIndexOf('.' : Int) - if (idx1 != -1) string = string.substring(idx1 + 1) - val idx2 = string.indexOf('$') - if (idx2 != -1) string = string.substring(0, idx2) - string + def stringPrefix: String = { + /* This method is written in a style that avoids calling `String.split()` + * as well as methods of java.lang.Character that require the Unicode + * database information. This is mostly important for Scala.js, so that + * using the collection library does automatically bring java.util.regex.* + * and the Unicode database in the generated code. + * + * This algorithm has the additional benefit that it won't allocate + * anything except the result String in the common case, where the class + * is not an inner class (i.e., when the result contains no '.'). + */ + val fqn = repr.getClass.getName + var pos: Int = fqn.length - 1 + + // Skip trailing $'s + while (pos != -1 && fqn.charAt(pos) == '$') { + pos -= 1 + } + if (pos == -1 || fqn.charAt(pos) == '.') { + return "" + } + + var result: String = "" + while (true) { + // Invariant: if we enter the loop, there is a non-empty part + + // Look for the beginning of the part, remembering where was the last non-digit + val partEnd = pos + 1 + while (pos != -1 && fqn.charAt(pos) <= '9' && fqn.charAt(pos) >= '0') { + pos -= 1 + } + val lastNonDigit = pos + while (pos != -1 && fqn.charAt(pos) != '$' && fqn.charAt(pos) != '.') { + pos -= 1 + } + val partStart = pos + 1 + + // A non-last part which contains only digits marks a method-local part -> drop the prefix + if (pos == lastNonDigit && partEnd != fqn.length) { + return result + } + + // Skip to the next part, and determine whether we are the end + while (pos != -1 && fqn.charAt(pos) == '$') { + pos -= 1 + } + val atEnd = pos == -1 || fqn.charAt(pos) == '.' + + // Handle the actual content of the part (we ignore parts that are likely synthetic) + def isPartLikelySynthetic = { + val firstChar = fqn.charAt(partStart) + (firstChar > 'Z' && firstChar < 0x7f) || (firstChar < 'A') + } + if (atEnd || !isPartLikelySynthetic) { + val part = fqn.substring(partStart, partEnd) + result = if (result.isEmpty) part else part + '.' + result + if (atEnd) + return result + } + } + + // dead code + result } /** Creates a non-strict view of this $coll. diff --git a/src/library/scala/collection/convert/WrapAsJava.scala b/src/library/scala/collection/convert/WrapAsJava.scala index e45c1666a5..e3a064b79d 100644 --- a/src/library/scala/collection/convert/WrapAsJava.scala +++ b/src/library/scala/collection/convert/WrapAsJava.scala @@ -13,7 +13,7 @@ package convert import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc } import scala.language.implicitConversions -@deprecated("Use JavaConverters or consider ToJavaImplicits", since="2.12") +@deprecated("use JavaConverters or consider ToJavaImplicits", since="2.12.0") trait WrapAsJava extends LowPriorityWrapAsJava { // provide higher-priority implicits with names that don't exist in JavaConverters for the case // when importing both JavaConverters._ and JavaConversions._. otherwise implicit conversions @@ -286,5 +286,5 @@ private[convert] trait LowPriorityWrapAsJava { } } -@deprecated("Use JavaConverters or consider ImplicitConversionsToJava", since="2.12") +@deprecated("use JavaConverters or consider ImplicitConversionsToJava", since="2.12.0") object WrapAsJava extends WrapAsJava diff --git a/src/library/scala/collection/convert/WrapAsScala.scala b/src/library/scala/collection/convert/WrapAsScala.scala index 514490e348..fbaafde798 100644 --- a/src/library/scala/collection/convert/WrapAsScala.scala +++ b/src/library/scala/collection/convert/WrapAsScala.scala @@ -13,7 +13,7 @@ package convert import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc } import scala.language.implicitConversions -@deprecated("Use JavaConverters or consider ToScalaImplicits", since="2.12") +@deprecated("use JavaConverters or consider ToScalaImplicits", since="2.12.0") trait WrapAsScala extends LowPriorityWrapAsScala { // provide higher-priority implicits with names that don't exist in JavaConverters for the case // when importing both JavaConverters._ and JavaConversions._. otherwise implicit conversions @@ -225,5 +225,5 @@ private[convert] trait LowPriorityWrapAsScala { } } -@deprecated("Use JavaConverters or consider ImplicitConversionsToScala", since="2.12") +@deprecated("use JavaConverters or consider ImplicitConversionsToScala", since="2.12.0") object WrapAsScala extends WrapAsScala diff --git a/src/library/scala/collection/convert/Wrappers.scala b/src/library/scala/collection/convert/Wrappers.scala index 6d745bc6b0..9f7e3e8174 100644 --- a/src/library/scala/collection/convert/Wrappers.scala +++ b/src/library/scala/collection/convert/Wrappers.scala @@ -28,7 +28,7 @@ private[collection] trait Wrappers { def next() = underlying.next() def hasMoreElements = underlying.hasNext def nextElement() = underlying.next() - def remove() = throw new UnsupportedOperationException + override def remove() = throw new UnsupportedOperationException } class ToIteratorWrapper[A](underlying : Iterator[A]) { @@ -113,7 +113,7 @@ private[collection] trait Wrappers { var prev: Option[A] = None def hasNext = ui.hasNext def next = { val e = ui.next(); prev = Some(e); e } - def remove = prev match { + override def remove() = prev match { case Some(e) => underlying match { case ms: mutable.Set[a] => @@ -200,7 +200,7 @@ private[collection] trait Wrappers { } } - def remove() { + override def remove() { prev match { case Some(k) => underlying match { @@ -293,24 +293,24 @@ private[collection] trait Wrappers { class ConcurrentMapWrapper[A, B](override val underlying: concurrent.Map[A, B]) extends MutableMapWrapper[A, B](underlying) with juc.ConcurrentMap[A, B] { - def putIfAbsent(k: A, v: B) = underlying.putIfAbsent(k, v) match { + override def putIfAbsent(k: A, v: B) = underlying.putIfAbsent(k, v) match { case Some(v) => v case None => null.asInstanceOf[B] } - def remove(k: AnyRef, v: AnyRef) = try { + override def remove(k: AnyRef, v: AnyRef) = try { underlying.remove(k.asInstanceOf[A], v.asInstanceOf[B]) } catch { case ex: ClassCastException => false } - def replace(k: A, v: B): B = underlying.replace(k, v) match { + override def replace(k: A, v: B): B = underlying.replace(k, v) match { case Some(v) => v case None => null.asInstanceOf[B] } - def replace(k: A, oldval: B, newval: B) = underlying.replace(k, oldval, newval) + override def replace(k: A, oldval: B, newval: B) = underlying.replace(k, oldval, newval) } /** Wraps a concurrent Java map as a Scala one. Single-element concurrent diff --git a/src/library/scala/collection/convert/package.scala b/src/library/scala/collection/convert/package.scala index fe1951b6cf..810d112cd5 100644 --- a/src/library/scala/collection/convert/package.scala +++ b/src/library/scala/collection/convert/package.scala @@ -10,17 +10,17 @@ package scala package collection package object convert { - @deprecated("use JavaConverters", since="2.12") + @deprecated("use JavaConverters", since="2.12.0") val decorateAsJava = new DecorateAsJava { } - @deprecated("use JavaConverters", since="2.12") + @deprecated("use JavaConverters", since="2.12.0") val decorateAsScala = new DecorateAsScala { } - @deprecated("use JavaConverters", since="2.12") + @deprecated("use JavaConverters", since="2.12.0") val decorateAll = JavaConverters - @deprecated("use JavaConverters or consider ImplicitConversionsToJava", since="2.12") + @deprecated("use JavaConverters or consider ImplicitConversionsToJava", since="2.12.0") val wrapAsJava = new WrapAsJava { } - @deprecated("use JavaConverters or consider ImplicitConversionsToScala", since="2.12") + @deprecated("use JavaConverters or consider ImplicitConversionsToScala", since="2.12.0") val wrapAsScala = new WrapAsScala { } - @deprecated("use JavaConverters or consider ImplicitConversions", since="2.12") + @deprecated("use JavaConverters or consider ImplicitConversions", since="2.12.0") val wrapAll = new WrapAsJava with WrapAsScala { } } diff --git a/src/library/scala/collection/generic/GenSetFactory.scala b/src/library/scala/collection/generic/GenSetFactory.scala index 800f66eb53..65404a4991 100644 --- a/src/library/scala/collection/generic/GenSetFactory.scala +++ b/src/library/scala/collection/generic/GenSetFactory.scala @@ -40,7 +40,11 @@ abstract class GenSetFactory[CC[X] <: GenSet[X] with GenSetLike[X, CC[X]]] /** $setCanBuildFromInfo */ def setCanBuildFrom[A] = new CanBuildFrom[CC[_], A, CC[A]] { - def apply(from: CC[_]) = newBuilder[A] + def apply(from: CC[_]) = from match { + // When building from an existing Set, try to preserve its type: + case from: Set[_] => from.genericBuilder.asInstanceOf[Builder[A, CC[A]]] + case _ => newBuilder[A] + } def apply() = newBuilder[A] } } diff --git a/src/library/scala/collection/generic/GenTraversableFactory.scala b/src/library/scala/collection/generic/GenTraversableFactory.scala index 2092c0c5f5..7c2aa5615c 100644 --- a/src/library/scala/collection/generic/GenTraversableFactory.scala +++ b/src/library/scala/collection/generic/GenTraversableFactory.scala @@ -229,7 +229,7 @@ extends GenericCompanion[CC] { /** Produces a $coll containing repeated applications of a function to a start value. * * @param start the start value of the $coll - * @param len the number of elements contained inthe $coll + * @param len the number of elements contained in the $coll * @param f the function that's repeatedly applied * @return a $coll with `len` values in the sequence `start, f(start), f(f(start)), ...` */ diff --git a/src/library/scala/collection/immutable/List.scala b/src/library/scala/collection/immutable/List.scala index c09328cae6..e5444533a8 100644 --- a/src/library/scala/collection/immutable/List.scala +++ b/src/library/scala/collection/immutable/List.scala @@ -25,6 +25,8 @@ import java.io.{ObjectOutputStream, ObjectInputStream} * This class is optimal for last-in-first-out (LIFO), stack-like access patterns. If you need another access * pattern, for example, random access or FIFO, consider using a collection more suited to this than `List`. * + * $usesMutableState + * * ==Performance== * '''Time:''' `List` has `O(1)` prepend and head/tail access. Most other operations are `O(n)` on the number of elements in the list. * This includes the index-based lookup of elements, `length`, `append` and `reverse`. @@ -398,7 +400,7 @@ sealed abstract class List[+A] extends AbstractSeq[A] else new Stream.Cons(head, tail.toStream) // Create a proxy for Java serialization that allows us to avoid mutation - // during de-serialization. This is the Serialization Proxy Pattern. + // during deserialization. This is the Serialization Proxy Pattern. protected final def writeReplace(): AnyRef = new List.SerializationProxy(this) } @@ -466,7 +468,7 @@ object List extends SeqFactory[List] { out.writeObject(ListSerializeEnd) } - // Java serialization calls this before readResolve during de-serialization. + // Java serialization calls this before readResolve during deserialization. // Read the whole list and store it in `orig`. private def readObject(in: ObjectInputStream) { in.defaultReadObject() diff --git a/src/library/scala/collection/immutable/Set.scala b/src/library/scala/collection/immutable/Set.scala index 3a8ee8b0be..047ea736bd 100644 --- a/src/library/scala/collection/immutable/Set.scala +++ b/src/library/scala/collection/immutable/Set.scala @@ -65,6 +65,7 @@ object Set extends ImmutableSetFactory[Set] { implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, Set[A]] = setCanBuildFrom[A] /** An optimized representation for immutable empty sets */ + @SerialVersionUID(-2443710944435909512L) private object EmptySet extends AbstractSet[Any] with Set[Any] with Serializable { override def size: Int = 0 def contains(elem: Any): Boolean = false diff --git a/src/library/scala/collection/immutable/SetProxy.scala b/src/library/scala/collection/immutable/SetProxy.scala index e1cf3620a2..b421b48597 100644 --- a/src/library/scala/collection/immutable/SetProxy.scala +++ b/src/library/scala/collection/immutable/SetProxy.scala @@ -12,8 +12,7 @@ package scala package collection package immutable -/** This is a simple wrapper class for <a href="Set.html" - * target="contentFrame">`scala.collection.immutable.Set`</a>. +/** This is a simple wrapper class for [[scala.collection.immutable.Set]]. * * It is most useful for assembling customized set abstractions * dynamically using object composition and forwarding. diff --git a/src/library/scala/collection/immutable/SortedSet.scala b/src/library/scala/collection/immutable/SortedSet.scala index 107f77f287..75b2b1f4dc 100644 --- a/src/library/scala/collection/immutable/SortedSet.scala +++ b/src/library/scala/collection/immutable/SortedSet.scala @@ -37,6 +37,6 @@ object SortedSet extends ImmutableSortedSetFactory[SortedSet] { /** $sortedSetCanBuildFromInfo */ def canBuildFrom[A](implicit ord: Ordering[A]): CanBuildFrom[Coll, A, SortedSet[A]] = newCanBuildFrom[A] def empty[A](implicit ord: Ordering[A]): SortedSet[A] = TreeSet.empty[A] - // Force a declaration here so that BitSet's (which does not inherit from SortedSetFactory) can be more specific + // Force a declaration here so that BitSet (which does not inherit from SortedSetFactory) can be more specific override implicit def newCanBuildFrom[A](implicit ord : Ordering[A]) : CanBuildFrom[Coll, A, SortedSet[A]] = super.newCanBuildFrom } diff --git a/src/library/scala/collection/immutable/Stream.scala b/src/library/scala/collection/immutable/Stream.scala index d135bb29a8..3d4e32971c 100644 --- a/src/library/scala/collection/immutable/Stream.scala +++ b/src/library/scala/collection/immutable/Stream.scala @@ -23,7 +23,7 @@ import scala.language.implicitConversions * import scala.math.BigInt * object Main extends App { * - * val fibs: Stream[BigInt] = BigInt(0) #:: BigInt(1) #:: fibs.zip(fibs.tail).map { n => n._1 + n._2 } + * lazy val fibs: Stream[BigInt] = BigInt(0) #:: BigInt(1) #:: fibs.zip(fibs.tail).map { n => n._1 + n._2 } * * fibs take 5 foreach println * } @@ -46,7 +46,7 @@ import scala.language.implicitConversions * import scala.math.BigInt * object Main extends App { * - * val fibs: Stream[BigInt] = BigInt(0) #:: BigInt(1) #:: fibs.zip( + * lazy val fibs: Stream[BigInt] = BigInt(0) #:: BigInt(1) #:: fibs.zip( * fibs.tail).map(n => { * println("Adding %d and %d".format(n._1, n._2)) * n._1 + n._2 @@ -162,7 +162,7 @@ import scala.language.implicitConversions * // The first time we try to access the tail we're going to need more * // information which will require us to recurse, which will require us to * // recurse, which... - * val sov: Stream[Vector[Int]] = Vector(0) #:: sov.zip(sov.tail).map { n => n._1 ++ n._2 } + * lazy val sov: Stream[Vector[Int]] = Vector(0) #:: sov.zip(sov.tail).map { n => n._1 ++ n._2 } * }}} * * The definition of `fibs` above creates a larger number of objects than @@ -1029,6 +1029,8 @@ sealed abstract class Stream[+A] extends AbstractSeq[A] */ override def stringPrefix = "Stream" + override def equals(that: Any): Boolean = + if (this eq that.asInstanceOf[AnyRef]) true else super.equals(that) } /** A specialized, extra-lazy implementation of a stream iterator, so it can @@ -1171,6 +1173,27 @@ object Stream extends SeqFactory[Stream] { tlVal } + + override /*LinearSeqOptimized*/ + def sameElements[B >: A](that: GenIterable[B]): Boolean = { + @tailrec def consEq(a: Cons[_], b: Cons[_]): Boolean = { + if (a.head != b.head) false + else { + a.tail match { + case at: Cons[_] => + b.tail match { + case bt: Cons[_] => (at eq bt) || consEq(at, bt) + case _ => false + } + case _ => b.tail.isEmpty + } + } + } + that match { + case that: Cons[_] => consEq(this, that) + case _ => super.sameElements(that) + } + } } /** An infinite stream that repeatedly applies a given function to a start value. diff --git a/src/library/scala/collection/immutable/StringLike.scala b/src/library/scala/collection/immutable/StringLike.scala index 155d25d933..af8703293f 100644 --- a/src/library/scala/collection/immutable/StringLike.scala +++ b/src/library/scala/collection/immutable/StringLike.scala @@ -139,6 +139,7 @@ self => /** Returns this string with first character converted to upper case. * If the first character of the string is capitalized, it is returned unchanged. + * This method does not convert characters outside the Basic Multilingual Plane (BMP). */ def capitalize: String = if (toString == null) null diff --git a/src/library/scala/collection/immutable/Traversable.scala b/src/library/scala/collection/immutable/Traversable.scala index 5fc0607a00..3d4ba95a16 100644 --- a/src/library/scala/collection/immutable/Traversable.scala +++ b/src/library/scala/collection/immutable/Traversable.scala @@ -18,6 +18,17 @@ import mutable.Builder /** A trait for traversable collections that are guaranteed immutable. * $traversableInfo * @define mutability immutable + * + * @define usesMutableState + * + * Note: Despite being an immutable collection, the implementation uses mutable state internally during + * construction. These state changes are invisible in single-threaded code but can lead to race conditions + * in some multi-threaded scenarios. The state of a new collection instance may not have been "published" + * (in the sense of the Java Memory Model specification), so that an unsynchronized non-volatile read from + * another thread may observe the object in an invalid state (see + * [[https://issues.scala-lang.org/browse/SI-7838 SI-7838]] for details). Note that such a read is not + * guaranteed to ''ever'' see the written object at all, and should therefore not be used, regardless + * of this issue. The easiest workaround is to exchange values between threads through a volatile var. */ trait Traversable[+A] extends scala.collection.Traversable[A] // with GenTraversable[A] diff --git a/src/library/scala/collection/immutable/Vector.scala b/src/library/scala/collection/immutable/Vector.scala index 539ae9c387..d9d925705f 100644 --- a/src/library/scala/collection/immutable/Vector.scala +++ b/src/library/scala/collection/immutable/Vector.scala @@ -11,7 +11,6 @@ package collection package immutable import scala.annotation.unchecked.uncheckedVariance -import scala.compat.Platform import scala.collection.generic._ import scala.collection.mutable.{Builder, ReusableBuilder} import scala.collection.parallel.immutable.ParVector @@ -40,6 +39,8 @@ object Vector extends IndexedSeqFactory[Vector] { * endian bit-mapped vector trie with a branching factor of 32. Locality is very good, but not * contiguous, which is good for very large sequences. * + * $usesMutableState + * * @see [[http://docs.scala-lang.org/overviews/collections/concrete-immutable-collection-classes.html#vectors "Scala's Collection Library overview"]] * section on `Vectors` for more information. * @@ -59,6 +60,7 @@ object Vector extends IndexedSeqFactory[Vector] { * @define mayNotTerminateInf * @define willNotTerminateInf */ +@SerialVersionUID(-1334388273712300479L) final class Vector[+A] private[immutable] (private[collection] val startIndex: Int, private[collection] val endIndex: Int, focus: Int) extends AbstractSeq[A] with IndexedSeq[A] @@ -475,12 +477,12 @@ override def companion: GenericCompanion[Vector] = Vector // if (array eq null) // println("OUCH!!! " + right + "/" + depth + "/"+startIndex + "/" + endIndex + "/" + focus) val a2 = new Array[AnyRef](array.length) - Platform.arraycopy(array, 0, a2, 0, right) + java.lang.System.arraycopy(array, 0, a2, 0, right) a2 } private def copyRight(array: Array[AnyRef], left: Int): Array[AnyRef] = { val a2 = new Array[AnyRef](array.length) - Platform.arraycopy(array, left, a2, left, a2.length - left) + java.lang.System.arraycopy(array, left, a2, left, a2.length - left) a2 } @@ -952,7 +954,7 @@ private[immutable] trait VectorPointer[T] { private[immutable] final def copyOf(a: Array[AnyRef]) = { val b = new Array[AnyRef](a.length) - Platform.arraycopy(a, 0, b, 0, a.length) + java.lang.System.arraycopy(a, 0, b, 0, a.length) b } @@ -1116,7 +1118,7 @@ private[immutable] trait VectorPointer[T] { private[immutable] final def copyRange(array: Array[AnyRef], oldLeft: Int, newLeft: Int) = { val elems = new Array[AnyRef](32) - Platform.arraycopy(array, oldLeft, elems, newLeft, 32 - math.max(newLeft,oldLeft)) + java.lang.System.arraycopy(array, oldLeft, elems, newLeft, 32 - math.max(newLeft,oldLeft)) elems } diff --git a/src/library/scala/collection/mutable/ArrayBuffer.scala b/src/library/scala/collection/mutable/ArrayBuffer.scala index 167e04ccbd..23d386f729 100644 --- a/src/library/scala/collection/mutable/ArrayBuffer.scala +++ b/src/library/scala/collection/mutable/ArrayBuffer.scala @@ -67,7 +67,7 @@ class ArrayBuffer[A](override protected val initialSize: Int) override def sizeHint(len: Int) { if (len > size && len >= 1) { val newarray = new Array[AnyRef](len) - scala.compat.Platform.arraycopy(array, 0, newarray, 0, size0) + java.lang.System.arraycopy(array, 0, newarray, 0, size0) array = newarray } } diff --git a/src/library/scala/collection/mutable/BitSet.scala b/src/library/scala/collection/mutable/BitSet.scala index feef694e01..e74ee65dda 100644 --- a/src/library/scala/collection/mutable/BitSet.scala +++ b/src/library/scala/collection/mutable/BitSet.scala @@ -164,7 +164,7 @@ class BitSet(protected final var elems: Array[Long]) extends AbstractSet[Int] */ @deprecated("If this BitSet contains a value that is 128 or greater, the result of this method is an 'immutable' " + "BitSet that shares state with this mutable BitSet. Thus, if the mutable BitSet is modified, it will violate the " + - "immutability of the result.", "2.11.6") + "immutability of the result.", "2.12.0") def toImmutable = immutable.BitSet.fromBitMaskNoCopy(elems) override def clone(): BitSet = { diff --git a/src/library/scala/collection/mutable/Builder.scala b/src/library/scala/collection/mutable/Builder.scala index 8d6a0ec69d..528f78bd98 100644 --- a/src/library/scala/collection/mutable/Builder.scala +++ b/src/library/scala/collection/mutable/Builder.scala @@ -65,18 +65,18 @@ trait Builder[-Elem, +To] extends Growable[Elem] { /** Gives a hint that one expects the `result` of this builder * to have the same size as the given collection, plus some delta. This will * provide a hint only if the collection is known to have a cheap - * `size` method. Currently this is assumed to be the case if and only if - * the collection is of type `IndexedSeqLike`. - * Some builder classes - * will optimize their representation based on the hint. However, + * `size` method, which is determined by calling `sizeHint`. + * + * Some builder classes will optimize their representation based on the hint. However, * builder implementations are still required to work correctly even if the hint is * wrong, i.e. a different number of elements is added. * * @param coll the collection which serves as a hint for the result's size. */ def sizeHint(coll: TraversableLike[_, _]) { - if (coll.isInstanceOf[collection.IndexedSeqLike[_,_]]) { - sizeHint(coll.size) + coll.sizeHintIfCheap match { + case -1 => + case n => sizeHint(n) } } @@ -94,8 +94,9 @@ trait Builder[-Elem, +To] extends Growable[Elem] { * @param delta a correction to add to the `coll.size` to produce the size hint. */ def sizeHint(coll: TraversableLike[_, _], delta: Int) { - if (coll.isInstanceOf[collection.IndexedSeqLike[_,_]]) { - sizeHint(coll.size + delta) + coll.sizeHintIfCheap match { + case -1 => + case n => sizeHint(n + delta) } } @@ -112,8 +113,10 @@ trait Builder[-Elem, +To] extends Growable[Elem] { * than collection's size are reduced. */ def sizeHintBounded(size: Int, boundingColl: TraversableLike[_, _]) { - if (boundingColl.isInstanceOf[collection.IndexedSeqLike[_,_]]) - sizeHint(size min boundingColl.size) + boundingColl.sizeHintIfCheap match { + case -1 => + case n => sizeHint(size min n) + } } /** Creates a new builder by applying a transformation function to diff --git a/src/library/scala/collection/mutable/HashTable.scala b/src/library/scala/collection/mutable/HashTable.scala index bb15788bdf..a6a6e1e432 100644 --- a/src/library/scala/collection/mutable/HashTable.scala +++ b/src/library/scala/collection/mutable/HashTable.scala @@ -396,7 +396,7 @@ private[collection] object HashTable { /** The load factor for the hash table (in 0.001 step). */ private[collection] final def defaultLoadFactor: Int = 750 // corresponds to 75% - private[collection] final def loadFactorDenum = 1000 + private[collection] final def loadFactorDenum = 1000 // should be loadFactorDenom, but changing that isn't binary compatible private[collection] final def newThreshold(_loadFactor: Int, size: Int) = ((size.toLong * _loadFactor) / loadFactorDenum).toInt diff --git a/src/library/scala/collection/mutable/History.scala b/src/library/scala/collection/mutable/History.scala index 19148c0ac2..13e2f32225 100644 --- a/src/library/scala/collection/mutable/History.scala +++ b/src/library/scala/collection/mutable/History.scala @@ -1,6 +1,6 @@ /* __ *\ ** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/tPFL ** +** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** ** /____/\___/_/ |_/____/_/ | | ** ** |/ ** diff --git a/src/library/scala/collection/mutable/ListBuffer.scala b/src/library/scala/collection/mutable/ListBuffer.scala index 02fcced3ac..3bb7004184 100644 --- a/src/library/scala/collection/mutable/ListBuffer.scala +++ b/src/library/scala/collection/mutable/ListBuffer.scala @@ -386,6 +386,25 @@ final class ListBuffer[A] this } + /** Selects the last element. + * + * Runs in constant time. + * + * @return the last element of this buffer. + * @throws NoSuchElementException if this buffer is empty. + */ + override def last: A = + if (last0 eq null) throw new NoSuchElementException("last of empty ListBuffer") + else last0.head + + /** Optionally selects the last element. + * + * Runs in constant time. + * + * @return `Some` of the last element of this buffer if the buffer is nonempty, `None` if it is empty. + */ + override def lastOption: Option[A] = if (last0 eq null) None else Some(last0.head) + /** Returns an iterator over this `ListBuffer`. The iterator will reflect * changes made to the underlying `ListBuffer` beyond the next element; * the next element's value is cached so that `hasNext` and `next` are diff --git a/src/library/scala/collection/mutable/PriorityQueue.scala b/src/library/scala/collection/mutable/PriorityQueue.scala index 107a2bfa0e..ed43ef6db9 100644 --- a/src/library/scala/collection/mutable/PriorityQueue.scala +++ b/src/library/scala/collection/mutable/PriorityQueue.scala @@ -331,8 +331,8 @@ sealed class PriorityQueue[A](implicit val ord: Ordering[A]) val pq = new PriorityQueue[A] val n = resarr.p_size0 pq.resarr.p_ensureSize(n) + java.lang.System.arraycopy(resarr.p_array, 1, pq.resarr.p_array, 1, n-1) pq.resarr.p_size0 = n - scala.compat.Platform.arraycopy(resarr.p_array, 1, pq.resarr.p_array, 1, n-1) pq } } diff --git a/src/library/scala/collection/mutable/ResizableArray.scala b/src/library/scala/collection/mutable/ResizableArray.scala index 85a299216e..50d3513784 100644 --- a/src/library/scala/collection/mutable/ResizableArray.scala +++ b/src/library/scala/collection/mutable/ResizableArray.scala @@ -101,7 +101,7 @@ trait ResizableArray[A] extends IndexedSeq[A] if (newSize > Int.MaxValue) newSize = Int.MaxValue val newArray: Array[AnyRef] = new Array(newSize.toInt) - scala.compat.Platform.arraycopy(array, 0, newArray, 0, size0) + java.lang.System.arraycopy(array, 0, newArray, 0, size0) array = newArray } } diff --git a/src/library/scala/collection/mutable/ReusableBuilder.scala b/src/library/scala/collection/mutable/ReusableBuilder.scala index 83a4fcfc29..dee2cd6393 100644 --- a/src/library/scala/collection/mutable/ReusableBuilder.scala +++ b/src/library/scala/collection/mutable/ReusableBuilder.scala @@ -35,7 +35,7 @@ trait ReusableBuilder[-Elem, +To] extends Builder[Elem, To] { * If executed immediately after a call to `result`, this allows a new * instance of the same type of collection to be built. */ - override def clear(): Unit // Note: overriding for scaladoc only! + override def clear(): Unit // Note: overriding for Scaladoc only! /** Produces a collection from the added elements. * @@ -45,5 +45,5 @@ trait ReusableBuilder[-Elem, +To] extends Builder[Elem, To] { * * @return a collection containing the elements added to this builder. */ - override def result(): To // Note: overriding for scaladoc only! + override def result(): To // Note: overriding for Scaladoc only! } diff --git a/src/library/scala/collection/mutable/Stack.scala b/src/library/scala/collection/mutable/Stack.scala index 1a92f23b7b..28d50af1f9 100644 --- a/src/library/scala/collection/mutable/Stack.scala +++ b/src/library/scala/collection/mutable/Stack.scala @@ -54,6 +54,7 @@ object Stack extends SeqFactory[Stack] { * @define mayNotTerminateInf * @define willNotTerminateInf */ +@deprecated("Stack is an inelegant and potentially poorly-performing wrapper around List. Use a List assigned to a var instead.", "2.12.0") class Stack[A] private (var elems: List[A]) extends AbstractSeq[A] with Seq[A] diff --git a/src/library/scala/collection/parallel/TaskSupport.scala b/src/library/scala/collection/parallel/TaskSupport.scala index 728605af7b..4d633253ce 100644 --- a/src/library/scala/collection/parallel/TaskSupport.scala +++ b/src/library/scala/collection/parallel/TaskSupport.scala @@ -16,7 +16,7 @@ import scala.concurrent.ExecutionContext /** A trait implementing the scheduling of a parallel collection operation. * * Parallel collections are modular in the way operations are scheduled. Each - * parallel collection is parametrized with a task support object which is + * parallel collection is parameterized with a task support object which is * responsible for scheduling and load-balancing tasks to processors. * * A task support object can be changed in a parallel collection after it has @@ -71,7 +71,7 @@ extends TaskSupport with AdaptiveWorkStealingThreadPoolTasks * forkjoin based task support or a thread pool executor one, depending on * what the execution context uses. * - * By default, parallel collections are parametrized with this task support + * By default, parallel collections are parameterized with this task support * object, so parallel collections share the same execution context backend * as the rest of the `scala.concurrent` package. * diff --git a/src/library/scala/collection/parallel/immutable/ParRange.scala b/src/library/scala/collection/parallel/immutable/ParRange.scala index 8fd5382ce9..de2b53a6c0 100644 --- a/src/library/scala/collection/parallel/immutable/ParRange.scala +++ b/src/library/scala/collection/parallel/immutable/ParRange.scala @@ -107,6 +107,7 @@ self => } } + override def toString = s"Par$range" } object ParRange { diff --git a/src/library/scala/concurrent/Future.scala b/src/library/scala/concurrent/Future.scala index c0398605a6..6c1c9a0c80 100644 --- a/src/library/scala/concurrent/Future.scala +++ b/src/library/scala/concurrent/Future.scala @@ -116,7 +116,7 @@ trait Future[+T] extends Awaitable[T] { @deprecated("use `foreach` or `onComplete` instead (keep in mind that they take total rather than partial functions)", "2.12.0") def onSuccess[U](pf: PartialFunction[T, U])(implicit executor: ExecutionContext): Unit = onComplete { case Success(v) => - pf.applyOrElse[T, Any](v, Predef.conforms[T]) // Exploiting the cached function to avoid MatchError + pf.applyOrElse[T, Any](v, Predef.identity[T]) // Exploiting the cached function to avoid MatchError case _ => } @@ -141,7 +141,7 @@ trait Future[+T] extends Awaitable[T] { @deprecated("use `onComplete` or `failed.foreach` instead (keep in mind that they take total rather than partial functions)", "2.12.0") def onFailure[U](@deprecatedName('callback) pf: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Unit = onComplete { case Failure(t) => - pf.applyOrElse[Throwable, Any](t, Predef.conforms[Throwable]) // Exploiting the cached function to avoid MatchError + pf.applyOrElse[Throwable, Any](t, Predef.identity[Throwable]) // Exploiting the cached function to avoid MatchError case _ => } @@ -528,7 +528,7 @@ trait Future[+T] extends Awaitable[T] { def andThen[U](pf: PartialFunction[Try[T], U])(implicit executor: ExecutionContext): Future[T] = transform { result => - try pf.applyOrElse[Try[T], Any](result, Predef.conforms[Try[T]]) + try pf.applyOrElse[Try[T], Any](result, Predef.identity[Try[T]]) catch { case NonFatal(t) => executor reportFailure t } result diff --git a/src/library/scala/concurrent/duration/Duration.scala b/src/library/scala/concurrent/duration/Duration.scala index f69030bd3d..d912f614c2 100644 --- a/src/library/scala/concurrent/duration/Duration.scala +++ b/src/library/scala/concurrent/duration/Duration.scala @@ -47,7 +47,7 @@ object Duration { * whitespace is allowed before, between and after the parts. Infinities are * designated by `"Inf"`, `"PlusInf"`, `"+Inf"` and `"-Inf"` or `"MinusInf"`. * - * @throws NumberFormatException if format is not parseable + * @throws NumberFormatException if format is not parsable */ def apply(s: String): Duration = { val s1: String = s filterNot (_.isWhitespace) @@ -120,7 +120,7 @@ object Duration { def fromNanos(nanos: Double): Duration = { if (nanos.isInfinite) if (nanos > 0) Inf else MinusInf - else if (nanos.isNaN) + else if (JDouble.isNaN(nanos)) Undefined else if (nanos > Long.MaxValue || nanos < Long.MinValue) throw new IllegalArgumentException("trying to construct too large duration with " + nanos + "ns") @@ -196,11 +196,11 @@ object Duration { } def *(factor: Double): Duration = - if (factor == 0d || factor.isNaN) Undefined + if (factor == 0d || JDouble.isNaN(factor)) Undefined else if (factor < 0d) -this else this def /(divisor: Double): Duration = - if (divisor.isNaN || divisor.isInfinite) Undefined + if (JDouble.isNaN(divisor) || divisor.isInfinite) Undefined else if ((divisor compare 0d) < 0) -this else this def /(divisor: Duration): Double = divisor match { @@ -285,7 +285,7 @@ object Duration { * whitespace is allowed before, between and after the parts. Infinities are * designated by `"Inf"`, `"PlusInf"`, `"+Inf"` and `"-Inf"` or `"MinusInf"`. * - * @throws NumberFormatException if format is not parseable + * @throws NumberFormatException if format is not parsable */ def create(s: String): Duration = apply(s) @@ -627,13 +627,13 @@ final class FiniteDuration(val length: Long, val unit: TimeUnit) extends Duratio def *(factor: Double) = if (!factor.isInfinite) fromNanos(toNanos * factor) - else if (factor.isNaN) Undefined + else if (JDouble.isNaN(factor)) Undefined else if ((factor > 0) ^ (this < Zero)) Inf else MinusInf def /(divisor: Double) = if (!divisor.isInfinite) fromNanos(toNanos / divisor) - else if (divisor.isNaN) Undefined + else if (JDouble.isNaN(divisor)) Undefined else Zero // if this is made a constant, then scalac will elide the conditional and always return +0.0, SI-6331 diff --git a/src/library/scala/concurrent/impl/ExecutionContextImpl.scala b/src/library/scala/concurrent/impl/ExecutionContextImpl.scala index 7bf5cc5729..19233d7531 100644 --- a/src/library/scala/concurrent/impl/ExecutionContextImpl.scala +++ b/src/library/scala/concurrent/impl/ExecutionContextImpl.scala @@ -100,7 +100,7 @@ private[concurrent] object ExecutionContextImpl { val numThreads = getInt("scala.concurrent.context.numThreads", "x1") // The hard limit on the number of active threads that the thread factory will produce // SI-8955 Deadlocks can happen if maxNoOfThreads is too low, although we're currently not sure - // about what the exact threshhold is. numThreads + 256 is conservatively high. + // about what the exact threshold is. numThreads + 256 is conservatively high. val maxNoOfThreads = getInt("scala.concurrent.context.maxThreads", "x1") val desiredParallelism = range( diff --git a/src/library/scala/concurrent/impl/Promise.scala b/src/library/scala/concurrent/impl/Promise.scala index 626540425f..7fcc8c9f2d 100644 --- a/src/library/scala/concurrent/impl/Promise.scala +++ b/src/library/scala/concurrent/impl/Promise.scala @@ -384,7 +384,7 @@ private[concurrent] object Promise { private[this] final def thisAs[S]: Future[S] = future.asInstanceOf[Future[S]] override def onSuccess[U](pf: PartialFunction[T, U])(implicit executor: ExecutionContext): Unit = () - override def failed: Future[Throwable] = thisAs[Throwable] + override def failed: Future[Throwable] = KeptPromise(Success(result.exception)).future override def foreach[U](f: T => U)(implicit executor: ExecutionContext): Unit = () override def map[S](f: T => S)(implicit executor: ExecutionContext): Future[S] = thisAs[S] override def flatMap[S](f: T => Future[S])(implicit executor: ExecutionContext): Future[S] = thisAs[S] diff --git a/src/library/scala/deprecated.scala b/src/library/scala/deprecated.scala index 7338dffb8d..60f0857550 100644 --- a/src/library/scala/deprecated.scala +++ b/src/library/scala/deprecated.scala @@ -29,26 +29,30 @@ import scala.annotation.meta._ * {{{ * oldMethod(1) * oldMethod(2) - * aDeprecatedMethodFromBarLibrary(3, 4) + * aDeprecatedMethodFromLibraryBar(3, 4) * - * // warning: there were two deprecation warnings (since FooLib 12.0) * // warning: there was one deprecation warning (since BarLib 3.2) + * // warning: there were two deprecation warnings (since FooLib 12.0) * // warning: there were three deprecation warnings in total; re-run with -deprecation for details * }}} * + * '''`@deprecated` in the Scala language and its standard library'''<br/> + * * A deprecated element of the Scala language or a definition in the Scala standard library will * be preserved or at least another major version. * - * This means that an element deprecated since 2.12 will be preserved in 2.13 and will very likely - * not be part of 2.14, though sometimes a deprecated element might be kept for more than a major + * This means that an element deprecated since 2.12 will be preserved in 2.13, but will very likely + * not be part of 2.14. Sometimes a deprecated element might be kept for more than a major * release to ease migration and upgrades from older Scala versions.<br/> * Developers should not rely on this. * - * @note The Scala team has decided to enact a special deprecation policy for the 2.12 release:<br/> + * '''Special deprecation policy for Scala 2.12'''<br> + * The Scala team has decided to enact a special deprecation policy for the 2.12 release:<br/> * - * As an upgrade from Scala 2.11 to Scala 2.12 also requires upgrading from Java 6 to Java 8, - * no deprecated elements will be removed in this release to ease migration and upgrades - * from older Scala versions. + * As an upgrade from Scala 2.11 to Scala 2.12 also requires upgrading from Java 6 to Java 8, + * no deprecated elements will be removed in this release to ease migration and upgrades + * from older Scala versions. This means that elements deprecated since 2.11 (or earlier) + * will not be removed in Scala 2.12. * * @see The official documentation on [[http://www.scala-lang.org/news/2.11.0/#binary-compatibility binary compatibility]]. * @param message the message to print during compilation if the definition is accessed diff --git a/src/library/scala/deprecatedInheritance.scala b/src/library/scala/deprecatedInheritance.scala index b85d07b0bd..994eac9ed8 100644 --- a/src/library/scala/deprecatedInheritance.scala +++ b/src/library/scala/deprecatedInheritance.scala @@ -8,6 +8,8 @@ package scala +import scala.annotation.meta._ + /** An annotation that designates that inheriting from a class is deprecated. * * This is usually done to warn about a non-final class being made final in a future version. @@ -15,15 +17,21 @@ package scala * * No warnings are generated if the subclass is in the same compilation unit. * + * Library authors should state the library's deprecation policy in their documentation to give + * developers guidance on when a type annotated with `@deprecatedInheritance` will be `final`ized. + * + * Library authors should prepend the name of their library to the version number to help + * developers distinguish deprecations coming from different libraries: + * * {{{ - * @deprecatedInheritance("this class will be made final", "2.12") + * @deprecatedInheritance("this class will be made final", "FooLib 12.0") * class Foo * }}} * * {{{ * val foo = new Foo // no deprecation warning * class Bar extends Foo - * // warning: inheritance from class Foo is deprecated (since 2.12): this class will be made final + * // warning: inheritance from class Foo is deprecated (since FooLib 12.0): this class will be made final * // class Bar extends Foo * // ^ * }}} @@ -35,4 +43,5 @@ package scala * @see [[scala.deprecatedOverriding]] * @see [[scala.deprecatedName]] */ +@getter @setter @beanGetter @beanSetter class deprecatedInheritance(message: String = "", since: String = "") extends scala.annotation.StaticAnnotation diff --git a/src/library/scala/deprecatedName.scala b/src/library/scala/deprecatedName.scala index e2322f0363..f8c6bd32ad 100644 --- a/src/library/scala/deprecatedName.scala +++ b/src/library/scala/deprecatedName.scala @@ -15,14 +15,19 @@ import scala.annotation.meta._ * * Using this name in a named argument generates a deprecation warning. * - * For instance, evaluating the code below in the Scala interpreter (with `-deprecation`) + * Library authors should state the library's deprecation policy in their documentation to give + * developers guidance on how long a deprecated name will be preserved. + * + * Library authors should prepend the name of their library to the version number to help + * developers distinguish deprecations coming from different libraries: + * * {{{ - * def inc(x: Int, @deprecatedName('y, "2.12") n: Int): Int = x + n + * def inc(x: Int, @deprecatedName('y, "FooLib 12.0") n: Int): Int = x + n * inc(1, y = 2) * }}} * will produce the following warning: * {{{ - * warning: the parameter name y is deprecated (since 2.12): use n instead + * warning: the parameter name y is deprecated (since FooLib 12.0): use n instead * inc(1, y = 2) * ^ * }}} diff --git a/src/library/scala/deprecatedOverriding.scala b/src/library/scala/deprecatedOverriding.scala index ee887db220..5be6830b27 100644 --- a/src/library/scala/deprecatedOverriding.scala +++ b/src/library/scala/deprecatedOverriding.scala @@ -8,13 +8,21 @@ package scala +import scala.annotation.meta._ + /** An annotation that designates that overriding a member is deprecated. * * Overriding such a member in a sub-class then generates a warning. * + * Library authors should state the library's deprecation policy in their documentation to give + * developers guidance on when a method annotated with `@deprecatedOverriding` will be `final`ized. + * + * Library authors should prepend the name of their library to the version number to help + * developers distinguish deprecations coming from different libraries: + * * {{{ * class Foo { - * @deprecatedOverriding("this method will be made final", "2.12") + * @deprecatedOverriding("this method will be made final", "FooLib 12.0") * def add(x: Int, y: Int) = x + y * } * }}} @@ -24,7 +32,7 @@ package scala * class Baz extends Foo { * override def add(x: Int, y: Int) = x - y * } - * // warning: overriding method add in class Foo is deprecated (since 2.12): this method will be made final + * // warning: overriding method add in class Foo is deprecated (since FooLib 12.0): this method will be made final * // override def add(x: Int, y: Int) = x - y * // ^ * }}} @@ -36,4 +44,5 @@ package scala * @see [[scala.deprecatedInheritance]] * @see [[scala.deprecatedName]] */ +@getter @setter @beanGetter @beanSetter class deprecatedOverriding(message: String = "", since: String = "") extends scala.annotation.StaticAnnotation diff --git a/src/library/scala/inline.scala b/src/library/scala/inline.scala index dc55af301c..f6d7c7569e 100644 --- a/src/library/scala/inline.scala +++ b/src/library/scala/inline.scala @@ -29,7 +29,7 @@ package scala * } * }}} * - * Note: parentheses are required when annotating a callsite withing a larger expression. + * Note: parentheses are required when annotating a callsite within a larger expression. * * {{{ * def t1 = f1(1) + f1(1): @noinline // equivalent to (f1(1) + f1(1)): @noinline diff --git a/src/library/scala/io/Source.scala b/src/library/scala/io/Source.scala index 7513b423a1..b4f542a252 100644 --- a/src/library/scala/io/Source.scala +++ b/src/library/scala/io/Source.scala @@ -59,7 +59,7 @@ object Source { def fromFile(name: String, enc: String): BufferedSource = fromFile(name)(Codec(enc)) - /** creates `ource` from file with given file `URI`. + /** creates `source` from file with given file `URI`. */ def fromFile(uri: URI)(implicit codec: Codec): BufferedSource = fromFile(new JFile(uri))(codec) diff --git a/src/library/scala/math/BigInt.scala b/src/library/scala/math/BigInt.scala index 3ae3b9bf6c..707a5c0769 100644 --- a/src/library/scala/math/BigInt.scala +++ b/src/library/scala/math/BigInt.scala @@ -160,8 +160,8 @@ final class BigInt(val bigInteger: BigInteger) } ) && !bitLengthOverflow } - /** Some implementations of java.math.BigInteger allow huge values with bit length greater than Int.MaxValue . - * The BigInteger.bitLength method returns truncated bit length in this case . + /** Some implementations of java.math.BigInteger allow huge values with bit length greater than Int.MaxValue. + * The BigInteger.bitLength method returns truncated bit length in this case. * This method tests if result of bitLength is valid. * This method will become unnecessary if BigInt constructors reject huge BigIntegers. */ diff --git a/src/library/scala/noinline.scala b/src/library/scala/noinline.scala index a427e170f4..0cd5ef9f64 100644 --- a/src/library/scala/noinline.scala +++ b/src/library/scala/noinline.scala @@ -29,7 +29,7 @@ package scala * } * }}} * - * Note: parentheses are required when annotating a callsite withing a larger expression. + * Note: parentheses are required when annotating a callsite within a larger expression. * * {{{ * def t1 = f1(1) + f1(1): @noinline // equivalent to (f1(1) + f1(1)): @noinline diff --git a/src/library/scala/reflect/ClassManifestDeprecatedApis.scala b/src/library/scala/reflect/ClassManifestDeprecatedApis.scala index 30a99340cc..d2ae10747d 100644 --- a/src/library/scala/reflect/ClassManifestDeprecatedApis.scala +++ b/src/library/scala/reflect/ClassManifestDeprecatedApis.scala @@ -143,8 +143,8 @@ trait ClassManifestDeprecatedApis[T] extends OptManifest[T] { * This is done to prevent avalanches of deprecation warnings in the code that calls methods with manifests. * * In a perfect world, we would just remove the @deprecated annotation from `ClassManifest` the object - * and then delete it in 2.11. After all, that object is explicitly marked as internal, so noone should use it. - * However a lot of existing libraries disregarded the scaladoc that comes with `ClassManifest`, + * and then delete it in 2.11. After all, that object is explicitly marked as internal, so no one should use it. + * However a lot of existing libraries disregarded the Scaladoc that comes with `ClassManifest`, * so we need to somehow nudge them into migrating prior to removing stuff out of the blue. * Hence we've introduced this design decision as the lesser of two evils. */ @@ -205,15 +205,18 @@ object ClassManifestFactory { case m: ClassManifest[_] => m.asInstanceOf[ClassManifest[T]].arrayManifest } + @SerialVersionUID(1L) + private class AbstractTypeClassManifest[T](prefix: OptManifest[_], name: String, clazz: jClass[_], args: OptManifest[_]*) extends ClassManifest[T] { + override def runtimeClass = clazz + override val typeArguments = args.toList + override def toString = prefix.toString+"#"+name+argString + } + /** ClassManifest for the abstract type `prefix # name`. `upperBound` is not * strictly necessary as it could be obtained by reflection. It was * added so that erasure can be calculated without reflection. */ def abstractType[T](prefix: OptManifest[_], name: String, clazz: jClass[_], args: OptManifest[_]*): ClassManifest[T] = - new ClassManifest[T] { - override def runtimeClass = clazz - override val typeArguments = args.toList - override def toString = prefix.toString+"#"+name+argString - } + new AbstractTypeClassManifest(prefix, name, clazz) /** ClassManifest for the abstract type `prefix # name`. `upperBound` is not * strictly necessary as it could be obtained by reflection. It was @@ -221,15 +224,12 @@ object ClassManifestFactory { * todo: remove after next bootstrap */ def abstractType[T](prefix: OptManifest[_], name: String, upperbound: ClassManifest[_], args: OptManifest[_]*): ClassManifest[T] = - new ClassManifest[T] { - override def runtimeClass = upperbound.runtimeClass - override val typeArguments = args.toList - override def toString = prefix.toString+"#"+name+argString - } + new AbstractTypeClassManifest(prefix, name, upperbound.runtimeClass) } /** Manifest for the class type `clazz[args]`, where `clazz` is * a top-level or static class */ +@SerialVersionUID(1L) private class ClassTypeManifest[T]( prefix: Option[OptManifest[_]], val runtimeClass: jClass[_], diff --git a/src/library/scala/reflect/ClassTag.scala b/src/library/scala/reflect/ClassTag.scala index 3a300e0593..30ceadceeb 100644 --- a/src/library/scala/reflect/ClassTag.scala +++ b/src/library/scala/reflect/ClassTag.scala @@ -83,21 +83,6 @@ trait ClassTag[T] extends ClassManifestDeprecatedApis[T] with Equals with Serial ) Some(x.asInstanceOf[T]) else None - // TODO: deprecate overloads in 2.12.0, remove in 2.13.0 - def unapply(x: Byte) : Option[T] = unapplyImpl(x, classOf[Byte]) - def unapply(x: Short) : Option[T] = unapplyImpl(x, classOf[Short]) - def unapply(x: Char) : Option[T] = unapplyImpl(x, classOf[Char]) - def unapply(x: Int) : Option[T] = unapplyImpl(x, classOf[Int]) - def unapply(x: Long) : Option[T] = unapplyImpl(x, classOf[Long]) - def unapply(x: Float) : Option[T] = unapplyImpl(x, classOf[Float]) - def unapply(x: Double) : Option[T] = unapplyImpl(x, classOf[Double]) - def unapply(x: Boolean) : Option[T] = unapplyImpl(x, classOf[Boolean]) - def unapply(x: Unit) : Option[T] = unapplyImpl(x, classOf[Unit]) - - private[this] def unapplyImpl(x: Any, primitiveCls: java.lang.Class[_]): Option[T] = - if (runtimeClass.isInstance(x) || runtimeClass.isAssignableFrom(primitiveCls)) Some(x.asInstanceOf[T]) - else None - // case class accessories override def canEqual(x: Any) = x.isInstanceOf[ClassTag[_]] override def equals(x: Any) = x.isInstanceOf[ClassTag[_]] && this.runtimeClass == x.asInstanceOf[ClassTag[_]].runtimeClass @@ -134,6 +119,7 @@ object ClassTag { val Nothing : ClassTag[scala.Nothing] = Manifest.Nothing val Null : ClassTag[scala.Null] = Manifest.Null + @SerialVersionUID(1L) private class GenericClassTag[T](val runtimeClass: jClass[_]) extends ClassTag[T] def apply[T](runtimeClass1: jClass[_]): ClassTag[T] = diff --git a/src/library/scala/reflect/Manifest.scala b/src/library/scala/reflect/Manifest.scala index 9c38864194..8e5ba6376e 100644 --- a/src/library/scala/reflect/Manifest.scala +++ b/src/library/scala/reflect/Manifest.scala @@ -87,6 +87,7 @@ object ManifestFactory { def valueManifests: List[AnyValManifest[_]] = List(Byte, Short, Char, Int, Long, Float, Double, Boolean, Unit) + @SerialVersionUID(1L) private class ByteManifest extends AnyValManifest[scala.Byte]("Byte") { def runtimeClass = java.lang.Byte.TYPE override def newArray(len: Int): Array[Byte] = new Array[Byte](len) @@ -96,6 +97,7 @@ object ManifestFactory { } val Byte: AnyValManifest[Byte] = new ByteManifest + @SerialVersionUID(1L) private class ShortManifest extends AnyValManifest[scala.Short]("Short") { def runtimeClass = java.lang.Short.TYPE override def newArray(len: Int): Array[Short] = new Array[Short](len) @@ -105,6 +107,7 @@ object ManifestFactory { } val Short: AnyValManifest[Short] = new ShortManifest + @SerialVersionUID(1L) private class CharManifest extends AnyValManifest[scala.Char]("Char") { def runtimeClass = java.lang.Character.TYPE override def newArray(len: Int): Array[Char] = new Array[Char](len) @@ -114,6 +117,7 @@ object ManifestFactory { } val Char: AnyValManifest[Char] = new CharManifest + @SerialVersionUID(1L) private class IntManifest extends AnyValManifest[scala.Int]("Int") { def runtimeClass = java.lang.Integer.TYPE override def newArray(len: Int): Array[Int] = new Array[Int](len) @@ -123,6 +127,7 @@ object ManifestFactory { } val Int: AnyValManifest[Int] = new IntManifest + @SerialVersionUID(1L) private class LongManifest extends AnyValManifest[scala.Long]("Long") { def runtimeClass = java.lang.Long.TYPE override def newArray(len: Int): Array[Long] = new Array[Long](len) @@ -132,6 +137,7 @@ object ManifestFactory { } val Long: AnyValManifest[Long] = new LongManifest + @SerialVersionUID(1L) private class FloatManifest extends AnyValManifest[scala.Float]("Float") { def runtimeClass = java.lang.Float.TYPE override def newArray(len: Int): Array[Float] = new Array[Float](len) @@ -141,6 +147,7 @@ object ManifestFactory { } val Float: AnyValManifest[Float] = new FloatManifest + @SerialVersionUID(1L) private class DoubleManifest extends AnyValManifest[scala.Double]("Double") { def runtimeClass = java.lang.Double.TYPE override def newArray(len: Int): Array[Double] = new Array[Double](len) @@ -150,6 +157,7 @@ object ManifestFactory { } val Double: AnyValManifest[Double] = new DoubleManifest + @SerialVersionUID(1L) private class BooleanManifest extends AnyValManifest[scala.Boolean]("Boolean") { def runtimeClass = java.lang.Boolean.TYPE override def newArray(len: Int): Array[Boolean] = new Array[Boolean](len) @@ -159,6 +167,7 @@ object ManifestFactory { } val Boolean: AnyValManifest[Boolean] = new BooleanManifest + @SerialVersionUID(1L) private class UnitManifest extends AnyValManifest[scala.Unit]("Unit") { def runtimeClass = java.lang.Void.TYPE override def newArray(len: Int): Array[Unit] = new Array[Unit](len) @@ -175,6 +184,7 @@ object ManifestFactory { private val NothingTYPE = classOf[scala.runtime.Nothing$] private val NullTYPE = classOf[scala.runtime.Null$] + @SerialVersionUID(1L) private class AnyManifest extends PhantomManifest[scala.Any](ObjectTYPE, "Any") { override def newArray(len: Int) = new Array[scala.Any](len) override def <:<(that: ClassManifest[_]): Boolean = (that eq this) @@ -182,6 +192,7 @@ object ManifestFactory { } val Any: Manifest[scala.Any] = new AnyManifest + @SerialVersionUID(1L) private class ObjectManifest extends PhantomManifest[java.lang.Object](ObjectTYPE, "Object") { override def newArray(len: Int) = new Array[java.lang.Object](len) override def <:<(that: ClassManifest[_]): Boolean = (that eq this) || (that eq Any) @@ -191,6 +202,7 @@ object ManifestFactory { val AnyRef: Manifest[scala.AnyRef] = Object.asInstanceOf[Manifest[scala.AnyRef]] + @SerialVersionUID(1L) private class AnyValPhantomManifest extends PhantomManifest[scala.AnyVal](ObjectTYPE, "AnyVal") { override def newArray(len: Int) = new Array[scala.AnyVal](len) override def <:<(that: ClassManifest[_]): Boolean = (that eq this) || (that eq Any) @@ -198,6 +210,7 @@ object ManifestFactory { } val AnyVal: Manifest[scala.AnyVal] = new AnyValPhantomManifest + @SerialVersionUID(1L) private class NullManifest extends PhantomManifest[scala.Null](NullTYPE, "Null") { override def newArray(len: Int) = new Array[scala.Null](len) override def <:<(that: ClassManifest[_]): Boolean = @@ -206,6 +219,7 @@ object ManifestFactory { } val Null: Manifest[scala.Null] = new NullManifest + @SerialVersionUID(1L) private class NothingManifest extends PhantomManifest[scala.Nothing](NothingTYPE, "Nothing") { override def newArray(len: Int) = new Array[scala.Nothing](len) override def <:<(that: ClassManifest[_]): Boolean = (that ne null) @@ -213,6 +227,7 @@ object ManifestFactory { } val Nothing: Manifest[scala.Nothing] = new NothingManifest + @SerialVersionUID(1L) private class SingletonTypeManifest[T <: AnyRef](value: AnyRef) extends Manifest[T] { lazy val runtimeClass = value.getClass override lazy val toString = value.toString + ".type" @@ -243,6 +258,7 @@ object ManifestFactory { def classType[T](prefix: Manifest[_], clazz: Predef.Class[_], args: Manifest[_]*): Manifest[T] = new ClassTypeManifest[T](Some(prefix), clazz, args.toList) + @SerialVersionUID(1L) private abstract class PhantomManifest[T](_runtimeClass: Predef.Class[_], override val toString: String) extends ClassTypeManifest[T](None, _runtimeClass, Nil) { override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef] @@ -252,6 +268,7 @@ object ManifestFactory { /** Manifest for the class type `clazz[args]`, where `clazz` is * a top-level or static class. */ + @SerialVersionUID(1L) private class ClassTypeManifest[T](prefix: Option[Manifest[_]], val runtimeClass: Predef.Class[_], override val typeArguments: List[Manifest[_]]) extends Manifest[T] { @@ -264,6 +281,7 @@ object ManifestFactory { def arrayType[T](arg: Manifest[_]): Manifest[Array[T]] = arg.asInstanceOf[Manifest[T]].arrayManifest + @SerialVersionUID(1L) private class AbstractTypeManifest[T](prefix: Manifest[_], name: String, upperBound: Predef.Class[_], args: Seq[Manifest[_]]) extends Manifest[T] { def runtimeClass = upperBound override val typeArguments = args.toList @@ -276,6 +294,7 @@ object ManifestFactory { def abstractType[T](prefix: Manifest[_], name: String, upperBound: Predef.Class[_], args: Manifest[_]*): Manifest[T] = new AbstractTypeManifest[T](prefix, name, upperBound, args) + @SerialVersionUID(1L) private class WildcardManifest[T](lowerBound: Manifest[_], upperBound: Manifest[_]) extends Manifest[T] { def runtimeClass = upperBound.runtimeClass override def toString = @@ -289,6 +308,7 @@ object ManifestFactory { def wildcardType[T](lowerBound: Manifest[_], upperBound: Manifest[_]): Manifest[T] = new WildcardManifest[T](lowerBound, upperBound) + @SerialVersionUID(1L) private class IntersectionTypeManifest[T](parents: Seq[Manifest[_]]) extends Manifest[T] { def runtimeClass = parents.head.runtimeClass override def toString = parents.mkString(" with ") diff --git a/src/library/scala/reflect/NameTransformer.scala b/src/library/scala/reflect/NameTransformer.scala index a8430548f5..bdf5165df5 100644 --- a/src/library/scala/reflect/NameTransformer.scala +++ b/src/library/scala/reflect/NameTransformer.scala @@ -13,14 +13,16 @@ package reflect * Also provides some constants. */ object NameTransformer { - // XXX Short term: providing a way to alter these without having to recompile - // the compiler before recompiling the compiler. - val MODULE_SUFFIX_STRING = sys.props.getOrElse("SCALA_MODULE_SUFFIX_STRING", "$") - val NAME_JOIN_STRING = sys.props.getOrElse("SCALA_NAME_JOIN_STRING", "$") - val MODULE_INSTANCE_NAME = "MODULE$" - val LOCAL_SUFFIX_STRING = " " - val SETTER_SUFFIX_STRING = "_$eq" - val TRAIT_SETTER_SEPARATOR_STRING = "$_setter_$" + // TODO: reduce duplication with and in StdNames + // I made these constants because we cannot change them without bumping our major version anyway. + final val NAME_JOIN_STRING = "$" + final val MODULE_SUFFIX_STRING = "$" + final val MODULE_INSTANCE_NAME = "MODULE$" + final val LOCAL_SUFFIX_STRING = " " + final val LAZY_LOCAL_SUFFIX_STRING = "$lzy" + final val MODULE_VAR_SUFFIX_STRING = "$module" + final val SETTER_SUFFIX_STRING = "_$eq" + final val TRAIT_SETTER_SEPARATOR_STRING = "$_setter_$" private val nops = 128 private val ncodes = 26 * 26 diff --git a/src/library/scala/runtime/LambdaDeserialize.java b/src/library/scala/runtime/LambdaDeserialize.java index e239debf25..4c5198cc48 100644 --- a/src/library/scala/runtime/LambdaDeserialize.java +++ b/src/library/scala/runtime/LambdaDeserialize.java @@ -2,28 +2,37 @@ package scala.runtime; import java.lang.invoke.*; -import java.util.Arrays; import java.util.HashMap; public final class LambdaDeserialize { + public static final MethodType DESERIALIZE_LAMBDA_MT = MethodType.fromMethodDescriptorString("(Ljava/lang/invoke/SerializedLambda;)Ljava/lang/Object;", LambdaDeserialize.class.getClassLoader()); private MethodHandles.Lookup lookup; private final HashMap<String, MethodHandle> cache = new HashMap<>(); private final LambdaDeserializer$ l = LambdaDeserializer$.MODULE$; + private final HashMap<String, MethodHandle> targetMethodMap; - private LambdaDeserialize(MethodHandles.Lookup lookup) { + private LambdaDeserialize(MethodHandles.Lookup lookup, MethodHandle[] targetMethods) { this.lookup = lookup; + targetMethodMap = new HashMap<>(targetMethods.length); + for (MethodHandle targetMethod : targetMethods) { + MethodHandleInfo info = lookup.revealDirect(targetMethod); + String key = nameAndDescriptorKey(info.getName(), info.getMethodType().toMethodDescriptorString()); + targetMethodMap.put(key, targetMethod); + } } public Object deserializeLambda(SerializedLambda serialized) { - return l.deserializeLambda(lookup, cache, serialized); + return l.deserializeLambda(lookup, cache, targetMethodMap, serialized); } public static CallSite bootstrap(MethodHandles.Lookup lookup, String invokedName, - MethodType invokedType) throws Throwable { - MethodType type = MethodType.fromMethodDescriptorString("(Ljava/lang/invoke/SerializedLambda;)Ljava/lang/Object;", lookup.getClass().getClassLoader()); - MethodHandle deserializeLambda = lookup.findVirtual(LambdaDeserialize.class, "deserializeLambda", type); - MethodHandle exact = deserializeLambda.bindTo(new LambdaDeserialize(lookup)).asType(invokedType); + MethodType invokedType, MethodHandle... targetMethods) throws Throwable { + MethodHandle deserializeLambda = lookup.findVirtual(LambdaDeserialize.class, "deserializeLambda", DESERIALIZE_LAMBDA_MT); + MethodHandle exact = deserializeLambda.bindTo(new LambdaDeserialize(lookup, targetMethods)).asType(invokedType); return new ConstantCallSite(exact); } + public static String nameAndDescriptorKey(String name, String descriptor) { + return name + descriptor; + } } diff --git a/src/library/scala/runtime/LambdaDeserializer.scala b/src/library/scala/runtime/LambdaDeserializer.scala index ad7d12ba5d..25f41fd049 100644 --- a/src/library/scala/runtime/LambdaDeserializer.scala +++ b/src/library/scala/runtime/LambdaDeserializer.scala @@ -31,10 +31,13 @@ object LambdaDeserializer { * member of the anonymous class created by `LambdaMetaFactory`. * @return An instance of the functional interface */ - def deserializeLambda(lookup: MethodHandles.Lookup, cache: java.util.Map[String, MethodHandle], serialized: SerializedLambda): AnyRef = { + def deserializeLambda(lookup: MethodHandles.Lookup, cache: java.util.Map[String, MethodHandle], + targetMethodMap: java.util.Map[String, MethodHandle], serialized: SerializedLambda): AnyRef = { + assert(targetMethodMap != null) def slashDot(name: String) = name.replaceAll("/", ".") val loader = lookup.lookupClass().getClassLoader val implClass = loader.loadClass(slashDot(serialized.getImplClass)) + val key = LambdaDeserialize.nameAndDescriptorKey(serialized.getImplMethodName, serialized.getImplMethodSignature) def makeCallSite: CallSite = { import serialized._ @@ -69,7 +72,11 @@ object LambdaDeserializer { // Lookup the implementation method val implMethod: MethodHandle = try { - findMember(lookup, getImplMethodKind, implClass, getImplMethodName, implMethodSig) + if (targetMethodMap.containsKey(key)) { + targetMethodMap.get(key) + } else { + throw new IllegalArgumentException("Illegal lambda deserialization") + } } catch { case e: ReflectiveOperationException => throw new IllegalArgumentException("Illegal lambda deserialization", e) } @@ -91,16 +98,17 @@ object LambdaDeserializer { ) } - val key = serialized.getImplMethodName + " : " + serialized.getImplMethodSignature val factory: MethodHandle = if (cache == null) { makeCallSite.getTarget - } else cache.get(key) match { - case null => - val callSite = makeCallSite - val temp = callSite.getTarget - cache.put(key, temp) - temp - case target => target + } else cache.synchronized{ + cache.get(key) match { + case null => + val callSite = makeCallSite + val temp = callSite.getTarget + cache.put(key, temp) + temp + case target => target + } } val captures = Array.tabulate(serialized.getCapturedArgCount)(n => serialized.getCapturedArg(n)) @@ -115,18 +123,4 @@ object LambdaDeserializer { // is cleaner if we uniformly add a single marker, so I'm leaving it in place. "java.io.Serializable" } - - private def findMember(lookup: MethodHandles.Lookup, kind: Int, owner: Class[_], - name: String, signature: MethodType): MethodHandle = { - kind match { - case MethodHandleInfo.REF_invokeStatic => - lookup.findStatic(owner, name, signature) - case MethodHandleInfo.REF_newInvokeSpecial => - lookup.findConstructor(owner, signature) - case MethodHandleInfo.REF_invokeVirtual | MethodHandleInfo.REF_invokeInterface => - lookup.findVirtual(owner, name, signature) - case MethodHandleInfo.REF_invokeSpecial => - lookup.findSpecial(owner, name, signature, owner) - } - } } diff --git a/src/library/scala/runtime/LazyRef.scala b/src/library/scala/runtime/LazyRef.scala new file mode 100644 index 0000000000..5a0bd5442c --- /dev/null +++ b/src/library/scala/runtime/LazyRef.scala @@ -0,0 +1,157 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2016, LAMP/EPFL and Lightbend, Inc ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala.runtime + +/** Classes used as holders for lazy vals defined in methods. */ + +class LazyRef[T] { + @volatile private[this] var _initialized: Boolean = _ + def initialized = _initialized + + private[this] var _value: T = _ + def value: T = _value + def initialize(value: T): T = { + _value = value + _initialized = true + value + } + + override def toString = s"LazyRef ${if (_initialized) s"of: ${_value}" else "thunk"}" +} + +class LazyBoolean { + @volatile private[this] var _initialized: Boolean = _ + def initialized = _initialized + + private[this] var _value: Boolean = _ + def value: Boolean = _value + def initialize(value: Boolean): Boolean = { + _value = value + _initialized = true + value + } + + override def toString = s"LazyBoolean ${if (_initialized) s"of: ${_value}" else "thunk"}" +} + +class LazyByte { + @volatile private[this] var _initialized: Boolean = _ + def initialized = _initialized + + private[this] var _value: Byte = _ + + def value: Byte = _value + + def initialize(value: Byte): Byte = { + _value = value + _initialized = true + value + } + + override def toString = s"LazyByte ${if (_initialized) s"of: ${_value}" else "thunk"}" +} + +class LazyChar { + @volatile private[this] var _initialized: Boolean = _ + def initialized = _initialized + + private[this] var _value: Char = _ + def value: Char = _value + def initialize(value: Char): Char = { + _value = value + _initialized = true + value + } + + override def toString = s"LazyChar ${if (_initialized) s"of: ${_value}" else "thunk"}" +} + +class LazyShort { + @volatile private[this] var _initialized: Boolean = _ + def initialized = _initialized + + private[this] var _value: Short = _ + def value: Short = _value + def initialize(value: Short): Short = { + _value = value + _initialized = true + value + } + + override def toString = s"LazyShort ${if (_initialized) s"of: ${_value}" else "thunk"}" +} + +class LazyInt { + @volatile private[this] var _initialized: Boolean = _ + def initialized = _initialized + + private[this] var _value: Int = _ + def value: Int = _value + def initialize(value: Int): Int = { + _value = value + _initialized = true + value + } + + override def toString = s"LazyInt ${if (_initialized) s"of: ${_value}" else "thunk"}" +} + +class LazyLong { + @volatile private[this] var _initialized: Boolean = _ + def initialized = _initialized + + private[this] var _value: Long = _ + def value: Long = _value + def initialize(value: Long): Long = { + _value = value + _initialized = true + value + } + + override def toString = s"LazyLong ${if (_initialized) s"of: ${_value}" else "thunk"}" +} + +class LazyFloat { + @volatile private[this] var _initialized: Boolean = _ + def initialized = _initialized + + private[this] var _value: Float = _ + def value: Float = _value + def initialize(value: Float): Float = { + _value = value + _initialized = true + value + } + + override def toString = s"LazyFloat ${if (_initialized) s"of: ${_value}" else "thunk"}" +} + +class LazyDouble { + @volatile private[this] var _initialized: Boolean = _ + def initialized = _initialized + + private[this] var _value: Double = _ + def value: Double = _value + def initialize(value: Double): Double = { + _value = value + _initialized = true + value + } + + override def toString = s"LazyDouble ${if (_initialized) s"of: ${_value}" else "thunk"}" +} + +class LazyUnit { + @volatile private[this] var _initialized: Boolean = _ + def initialized = _initialized + + def initialize(): Unit = _initialized = true + + override def toString = s"LazyUnit${if (_initialized) "" else " thunk"}" +} diff --git a/src/library/scala/runtime/TraitSetter.java b/src/library/scala/runtime/TraitSetter.java index d9907c0ac0..d8dd8c6b04 100644 --- a/src/library/scala/runtime/TraitSetter.java +++ b/src/library/scala/runtime/TraitSetter.java @@ -2,5 +2,6 @@ package scala.runtime; /** A marker annotation to tag a setter of a mutable variable in a trait */ +@Deprecated public @interface TraitSetter { }
\ No newline at end of file diff --git a/src/library/scala/sys/process/ProcessBuilder.scala b/src/library/scala/sys/process/ProcessBuilder.scala index 35f3f4d7a5..8288d8d480 100644 --- a/src/library/scala/sys/process/ProcessBuilder.scala +++ b/src/library/scala/sys/process/ProcessBuilder.scala @@ -15,8 +15,8 @@ import ProcessBuilder._ /** Represents a sequence of one or more external processes that can be * executed. A `ProcessBuilder` can be a single external process, or a - * combination of other `ProcessBuilder`. One can control where a - * the output of an external process will go to, and where its input will come + * combination of other `ProcessBuilder`. One can control where the + * output of an external process will go to, and where its input will come * from, or leave that decision to whoever starts it. * * One creates a `ProcessBuilder` through factories provided in @@ -90,19 +90,19 @@ import ProcessBuilder._ * * If not specified, the input of the external commands executed with `run` or * `!` will not be tied to anything, and the output will be redirected to the - * stdout and stderr of the Scala process. For the methods `!!` and `lines`, no + * stdout and stderr of the Scala process. For the methods `!!` and `lineStream`, no * input will be provided, and the output will be directed according to the * semantics of these methods. * * Some methods will cause stdin to be used as input. Output can be controlled - * with a [[scala.sys.process.ProcessLogger]] -- `!!` and `lines` will only + * with a [[scala.sys.process.ProcessLogger]] -- `!!` and `lineStream` will only * redirect error output when passed a `ProcessLogger`. If one desires full * control over input and output, then a [[scala.sys.process.ProcessIO]] can be * used with `run`. * - * For example, we could silence the error output from `lines_!` like this: + * For example, we could silence the error output from `lineStream_!` like this: * {{{ - * val etcFiles = "find /etc" lines_! ProcessLogger(line => ()) + * val etcFiles = "find /etc" lineStream_! ProcessLogger(line => ()) * }}} * * ==Extended Example== @@ -342,7 +342,7 @@ object ProcessBuilder extends ProcessBuilderImpl { /** Writes the output stream of this process to a [[scala.sys.process.ProcessBuilder]]. */ def #>(b: ProcessBuilder): ProcessBuilder = new PipedBuilder(toSource, b, false) - /** Returnes a [[scala.sys.process.ProcessBuilder]] representing this `Source`. */ + /** Returns a [[scala.sys.process.ProcessBuilder]] representing this `Source`. */ def cat = toSource private def toFile(f: File, append: Boolean) = #> (new FileOutput(f, append)) } diff --git a/src/library/scala/sys/process/package.scala b/src/library/scala/sys/process/package.scala index ff0fd920c9..440e62b6aa 100644 --- a/src/library/scala/sys/process/package.scala +++ b/src/library/scala/sys/process/package.scala @@ -25,7 +25,7 @@ package scala.sys { * * {{{ * import scala.sys.process._ - * "ls" #| "grep .scala" #&& Seq("sh", "-c", "scalac *.scala") #|| "echo nothing found" lines + * "ls" #| "grep .scala" #&& Seq("sh", "-c", "scalac *.scala") #|| "echo nothing found" lineStream * }}} * * We describe below the general concepts and architecture of the package, @@ -92,7 +92,7 @@ package scala.sys { * * - Return status of the process (`!` methods) * - Output of the process as a `String` (`!!` methods) - * - Continuous output of the process as a `Stream[String]` (`lines` methods) + * - Continuous output of the process as a `Stream[String]` (`lineStream` methods) * - The `Process` representing it (`run` methods) * * Some simple examples of these methods: @@ -109,7 +109,7 @@ package scala.sys { * // a Stream[String] * def sourceFilesAt(baseDir: String): Stream[String] = { * val cmd = Seq("find", baseDir, "-name", "*.scala", "-type", "f") - * cmd.lines + * cmd.lineStream * } * }}} * @@ -167,8 +167,8 @@ package scala.sys { * def sourceFilesAt(baseDir: String): (Stream[String], StringBuffer) = { * val buffer = new StringBuffer() * val cmd = Seq("find", baseDir, "-name", "*.scala", "-type", "f") - * val lines = cmd lines_! ProcessLogger(buffer append _) - * (lines, buffer) + * val lineStream = cmd lineStream_! ProcessLogger(buffer append _) + * (lineStream, buffer) * } * }}} * @@ -185,8 +185,8 @@ package scala.sys { * new URL("http://www.scala-lang.org/") #> new File("scala-lang.html") ! * }}} * - * More information about the other ways of controlling I/O can be looked at - * in the scaladoc for the associated objects, traits and classes. + * More information about the other ways of controlling I/O can be found + * in the Scaladoc for the associated objects, traits and classes. * * ==Running the Process== * diff --git a/src/library/scala/util/Either.scala b/src/library/scala/util/Either.scala index 169786d31b..523c10c483 100644 --- a/src/library/scala/util/Either.scala +++ b/src/library/scala/util/Either.scala @@ -55,31 +55,31 @@ package util * val left23: Left[Double, Int] = Left(23.0) * val left42 = Left(42.0) * - * for ( - * a <- right1; - * b <- right2; + * for { + * a <- right1 + * b <- right2 * c <- right3 - * ) yield a + b + c // Right(6) + * } yield a + b + c // Right(6) * - * for ( - * a <- right1; - * b <- right2; + * for { + * a <- right1 + * b <- right2 * c <- left23 - * ) yield a + b + c // Left(23.0) + * } yield a + b + c // Left(23.0) * - * for ( - * a <- right1; - * b <- left23; + * for { + * a <- right1 + * b <- left23 * c <- right2 - * ) yield a + b + c // Left(23.0) + * } yield a + b + c // Left(23.0) * * // It is advisable to provide the type of the “missing” value (especially the right value for `Left`) - * // as otherwise that type might be infered as `Nothing` without context: - * for ( - * a <- left23; - * b <- right1; + * // as otherwise that type might be inferred as `Nothing` without context: + * for { + * a <- left23 + * b <- right1 * c <- left42 // type at this position: Either[Double, Nothing] - * ) yield a + b + c + * } yield a + b + c * // ^ * // error: ambiguous reference to overloaded definition, * // both method + in class Int of type (x: Char)Int @@ -95,13 +95,15 @@ sealed abstract class Either[+A, +B] extends Product with Serializable { /** * Projects this `Either` as a `Left`. */ - @deprecated("use swap instead", "2.12.0") def left = Either.LeftProjection(this) /** * Projects this `Either` as a `Right`. + * + * Because `Either` is right-biased, this method is not normally needed. + * (It is retained in the API for now for easy cross-compilation between Scala + * 2.11 and 2.12.) */ - @deprecated("Either is now right-biased", "2.12.0") def right = Either.RightProjection(this) /** @@ -134,10 +136,10 @@ sealed abstract class Either[+A, +B] extends Product with Serializable { * @example {{{ * val right = Right(2) * val left = Left(3) - * for ( - * r1 <- right; + * for { + * r1 <- right * r2 <- left.swap - * ) yield r1 * r2 // Right(6) + * } yield r1 * r2 // Right(6) * }}} */ def swap: Either[B, A] = this match { @@ -245,7 +247,7 @@ sealed abstract class Either[+A, +B] extends Product with Serializable { /** * Returns `true` if `Left` or returns the result of the application of - * the given function to the `Right` value. + * the given predicate to the `Right` value. * * {{{ * Right(12).forall(_ > 10) // true @@ -260,7 +262,7 @@ sealed abstract class Either[+A, +B] extends Product with Serializable { /** * Returns `false` if `Left` or returns the result of the application of - * the given function to the `Right` value. + * the given predicate to the `Right` value. * * {{{ * Right(12).exists(_ > 10) // true @@ -426,7 +428,10 @@ object Either { /** * Projects an `Either` into a `Left`. * - * This allows for-comprehensions over Either instances - for example {{{ + * This allows for-comprehensions over the left side of Either instances, + * reversing Either's usual right-bias. + * + * For example {{{ * for (s <- Left("flower").left) yield s.length // Left(6) * }}} * @@ -472,7 +477,6 @@ object Either { * @author <a href="mailto:research@workingmouse.com">Tony Morris</a>, Workingmouse * @version 1.0, 11/10/2008 */ - @deprecated("use swap instead", "2.12.0") final case class LeftProjection[+A, +B](e: Either[A, B]) { /** * Returns the value from this `Left` or throws `java.util.NoSuchElementException` @@ -624,19 +628,13 @@ object Either { /** * Projects an `Either` into a `Right`. * - * This allows for-comprehensions over Either instances - for example {{{ - * for (s <- Right("flower").right) yield s.length // Right(6) - * }}} - * - * Continuing the analogy with [[scala.Option]], a `RightProjection` declares - * that `Right` should be analogous to `Some` in some code. - * - * Analogous to `LeftProjection`, see example usage in its documentation above. + * Because `Either` is already right-biased, this class is not normally needed. + * (It is retained in the library for now for easy cross-compilation between Scala + * 2.11 and 2.12.) * * @author <a href="mailto:research@workingmouse.com">Tony Morris</a>, Workingmouse * @version 1.0, 11/10/2008 */ - @deprecated("Either is now right-biased", "2.12.0") final case class RightProjection[+A, +B](e: Either[A, B]) { /** diff --git a/src/library/scala/util/Properties.scala b/src/library/scala/util/Properties.scala index a176748cd6..7b21351cf6 100644 --- a/src/library/scala/util/Properties.scala +++ b/src/library/scala/util/Properties.scala @@ -105,7 +105,7 @@ private[scala] trait PropertiesTrait { * or "version (unknown)" if it cannot be determined. */ val versionString = "version " + scalaPropOrElse("version.number", "(unknown)") - val copyrightString = scalaPropOrElse("copyright.string", "Copyright 2002-2016, LAMP/EPFL") + val copyrightString = scalaPropOrElse("copyright.string", "Copyright 2002-2016, LAMP/EPFL and Lightbend, Inc.") /** This is the encoding to use reading in source files, overridden with -encoding. * Note that it uses "prop" i.e. looks in the scala jar, not the system properties. @@ -168,27 +168,53 @@ private[scala] trait PropertiesTrait { /** Compares the given specification version to the specification version of the platform. * - * @param version a specification version of the form "major.minor" - * @return `true` iff the specification version of the current runtime - * is equal to or higher than the version denoted by the given string. - * @throws NumberFormatException if the given string is not a version string + * @param version a specification version number (legacy forms acceptable) + * @return `true` if the specification version of the current runtime + * is equal to or higher than the version denoted by the given string. + * @throws NumberFormatException if the given string is not a version string * - * @example {{{ - * // In this example, the runtime's Java specification is assumed to be at version 1.7. - * isJavaAtLeast("1.6") // true - * isJavaAtLeast("1.7") // true - * isJavaAtLeast("1.8") // false - * }}} + * @example {{{ + * // In this example, the runtime's Java specification is assumed to be at version 8. + * isJavaAtLeast("1.8") // true + * isJavaAtLeast("8") // true + * isJavaAtLeast("9") // false + * isJavaAtLeast("9.1") // false + * isJavaAtLeast("1.9") // throws + * }}} */ def isJavaAtLeast(version: String): Boolean = { - def parts(x: String) = { - val i = x.indexOf('.') - if (i < 0) throw new NumberFormatException("Not a version: " + x) - (x.substring(0, i), x.substring(i+1, x.length)) + def versionOf(s: String, depth: Int): (Int, String) = + s.indexOf('.') match { + case 0 => + (-2, s.substring(1)) + case 1 if depth == 0 && s.charAt(0) == '1' => + val r0 = s.substring(2) + val (v, r) = versionOf(r0, 1) + val n = if (v > 8 || r0.isEmpty) -2 else v // accept 1.8, not 1.9 or 1. + (n, r) + case -1 => + val n = if (!s.isEmpty) s.toInt else if (depth == 0) -2 else 0 + (n, "") + case i => + val r = s.substring(i + 1) + val n = if (depth < 2 && r.isEmpty) -2 else s.substring(0, i).toInt + (n, r) + } + def compareVersions(s: String, v: String, depth: Int): Int = { + if (depth >= 3) 0 + else { + val (sn, srest) = versionOf(s, depth) + val (vn, vrest) = versionOf(v, depth) + if (vn < 0) -2 + else if (sn < vn) -1 + else if (sn > vn) 1 + else compareVersions(srest, vrest, depth + 1) + } + } + compareVersions(javaSpecVersion, version, 0) match { + case -2 => throw new NumberFormatException(s"Not a version: $version") + case i => i >= 0 } - val (v, _v) = parts(version) - val (s, _s) = parts(javaSpecVersion) - s.toInt >= v.toInt && _s.toInt >= _v.toInt } // provide a main method so version info can be obtained by running this diff --git a/src/library/scala/util/Random.scala b/src/library/scala/util/Random.scala index 2d38c9d4a0..16d18d7d6d 100644 --- a/src/library/scala/util/Random.scala +++ b/src/library/scala/util/Random.scala @@ -121,9 +121,6 @@ class Random(val self: java.util.Random) extends AnyRef with Serializable { (bf(xs) ++= buf).result() } - @deprecated("Preserved for backwards binary compatibility. To remove in 2.12.x.", "2.11.6") - final def `scala$util$Random$$isAlphaNum$1`(c: Char) = (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') - /** Returns a Stream of pseudorandomly chosen alphanumeric characters, * equally chosen from A-Z, a-z, and 0-9. * |