diff options
Diffstat (limited to 'src/library')
182 files changed, 3926 insertions, 1720 deletions
diff --git a/src/library/scala/Array.scala b/src/library/scala/Array.scala index 99c54ce58c..5b8ebde308 100644 --- a/src/library/scala/Array.scala +++ b/src/library/scala/Array.scala @@ -467,6 +467,19 @@ object Array extends FallbackArrayBuilding { * @version 1.0 * @see [[http://www.scala-lang.org/docu/files/collections-api/collections_38.html#anchor "The Scala 2.8 Collections' API"]] * section on `Array` by Martin Odersky for more information. + * @define coll array + * @define Coll Array + * @define orderDependent + * @define orderDependentFold + * @define mayNotTerminateInf + * @define willNotTerminateInf + * @define collectExample + * @define undefinedorder + * @define thatinfo the class of the returned collection. In the standard library configuration, + * `That` is either `Array[B]` if a ClassManifest is available for B or `ArraySeq[B]` otherwise. + * @define zipthatinfo $thatinfo + * @define bfinfo an implicit value of class `CanBuildFrom` which determines the result class `That` from the current + * representation type `Repr` and the new element type `B`. */ final class Array[T](_length: Int) extends java.io.Serializable with java.lang.Cloneable { diff --git a/src/library/scala/Boolean.scala b/src/library/scala/Boolean.scala index 5078e59d28..edb82b33fe 100644 --- a/src/library/scala/Boolean.scala +++ b/src/library/scala/Boolean.scala @@ -17,7 +17,7 @@ package scala * There is an implicit conversion from [[scala.Boolean]] => [[scala.runtime.RichBoolean]] * which provides useful non-primitive operations. */ -final class Boolean extends AnyVal { +final class Boolean private extends AnyVal { /** * Negates a Boolean expression. * @@ -110,7 +110,7 @@ final class Boolean extends AnyVal { override def getClass(): Class[Boolean] = sys.error("stub") } -object Boolean extends AnyValCompanion { +object Boolean extends AnyValCompanion { /** Transform a value type into a boxed reference type. * diff --git a/src/library/scala/Byte.scala b/src/library/scala/Byte.scala index f9c5f6003e..b5b3d88e3f 100644 --- a/src/library/scala/Byte.scala +++ b/src/library/scala/Byte.scala @@ -17,7 +17,7 @@ package scala * There is an implicit conversion from [[scala.Byte]] => [[scala.runtime.RichByte]] * which provides useful non-primitive operations. */ -final class Byte extends AnyVal { +final class Byte private extends AnyVal { def toByte: Byte = sys.error("stub") def toShort: Short = sys.error("stub") def toChar: Char = sys.error("stub") @@ -27,7 +27,7 @@ final class Byte extends AnyVal { def toDouble: Double = sys.error("stub") /** - * @return the bitwise negation of this value + * Returns the bitwise negation of this value. * @example {{{ * ~5 == -6 * // in binary: ~00000101 == @@ -36,30 +36,30 @@ final class Byte extends AnyVal { */ def unary_~ : Int = sys.error("stub") /** - * @return this value, unmodified + * Returns this value, unmodified. */ def unary_+ : Int = sys.error("stub") /** - * @return the negation of this value + * Returns the negation of this value. */ def unary_- : Int = sys.error("stub") def +(x: String): String = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the new right bits with zeroes. * @example {{{ 6 << 3 == 48 // in binary: 0110 << 3 == 0110000 }}} */ def <<(x: Int): Int = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the new right bits with zeroes. * @example {{{ 6 << 3 == 48 // in binary: 0110 << 3 == 0110000 }}} */ def <<(x: Long): Int = sys.error("stub") /** - * @return this value bit-shifted right by the specified number of bits, + * Returns this value bit-shifted right by the specified number of bits, * filling the new left bits with zeroes. * @example {{{ 21 >>> 3 == 2 // in binary: 010101 >>> 3 == 010 }}} * @example {{{ @@ -70,7 +70,7 @@ final class Byte extends AnyVal { */ def >>>(x: Int): Int = sys.error("stub") /** - * @return this value bit-shifted right by the specified number of bits, + * Returns this value bit-shifted right by the specified number of bits, * filling the new left bits with zeroes. * @example {{{ 21 >>> 3 == 2 // in binary: 010101 >>> 3 == 010 }}} * @example {{{ @@ -81,7 +81,7 @@ final class Byte extends AnyVal { */ def >>>(x: Long): Int = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the right bits with the same value as the left-most bit of this. * The effect of this is to retain the sign of the value. * @example {{{ @@ -92,7 +92,7 @@ final class Byte extends AnyVal { */ def >>(x: Int): Int = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the right bits with the same value as the left-most bit of this. * The effect of this is to retain the sign of the value. * @example {{{ @@ -104,181 +104,181 @@ final class Byte extends AnyVal { def >>(x: Long): Int = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Double): Boolean = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -289,7 +289,7 @@ final class Byte extends AnyVal { */ def |(x: Byte): Int = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -300,7 +300,7 @@ final class Byte extends AnyVal { */ def |(x: Short): Int = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -311,7 +311,7 @@ final class Byte extends AnyVal { */ def |(x: Char): Int = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -322,7 +322,7 @@ final class Byte extends AnyVal { */ def |(x: Int): Int = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -334,7 +334,7 @@ final class Byte extends AnyVal { def |(x: Long): Long = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -345,7 +345,7 @@ final class Byte extends AnyVal { */ def &(x: Byte): Int = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -356,7 +356,7 @@ final class Byte extends AnyVal { */ def &(x: Short): Int = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -367,7 +367,7 @@ final class Byte extends AnyVal { */ def &(x: Char): Int = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -378,7 +378,7 @@ final class Byte extends AnyVal { */ def &(x: Int): Int = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -390,7 +390,7 @@ final class Byte extends AnyVal { def &(x: Long): Long = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -401,7 +401,7 @@ final class Byte extends AnyVal { */ def ^(x: Byte): Int = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -412,7 +412,7 @@ final class Byte extends AnyVal { */ def ^(x: Short): Int = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -423,7 +423,7 @@ final class Byte extends AnyVal { */ def ^(x: Char): Int = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -434,7 +434,7 @@ final class Byte extends AnyVal { */ def ^(x: Int): Int = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -446,154 +446,154 @@ final class Byte extends AnyVal { def ^(x: Long): Long = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Byte): Int = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Short): Int = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Char): Int = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Int): Int = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Long): Long = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Float): Float = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Double): Double = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Byte): Int = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Short): Int = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Char): Int = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Int): Int = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Long): Long = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Float): Float = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Double): Double = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Byte): Int = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Short): Int = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Char): Int = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Int): Int = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Long): Long = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Float): Float = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Double): Double = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Byte): Int = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Short): Int = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Char): Int = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Int): Int = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Long): Long = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Float): Float = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Double): Double = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Byte): Int = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Short): Int = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Char): Int = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Int): Int = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Long): Long = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Float): Float = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Double): Double = sys.error("stub") override def getClass(): Class[Byte] = sys.error("stub") } -object Byte extends AnyValCompanion { +object Byte extends AnyValCompanion { /** The smallest value representable as a Byte. */ final val MinValue = java.lang.Byte.MIN_VALUE @@ -622,5 +622,10 @@ object Byte extends AnyValCompanion { /** The String representation of the scala.Byte companion object. */ override def toString = "object scala.Byte" + implicit def byte2short(x: Byte): Short = x.toShort + implicit def byte2int(x: Byte): Int = x.toInt + implicit def byte2long(x: Byte): Long = x.toLong + implicit def byte2float(x: Byte): Float = x.toFloat + implicit def byte2double(x: Byte): Double = x.toDouble } diff --git a/src/library/scala/Char.scala b/src/library/scala/Char.scala index 3d459782cd..e0ac9a2550 100644 --- a/src/library/scala/Char.scala +++ b/src/library/scala/Char.scala @@ -17,7 +17,7 @@ package scala * There is an implicit conversion from [[scala.Char]] => [[scala.runtime.RichChar]] * which provides useful non-primitive operations. */ -final class Char extends AnyVal { +final class Char private extends AnyVal { def toByte: Byte = sys.error("stub") def toShort: Short = sys.error("stub") def toChar: Char = sys.error("stub") @@ -27,7 +27,7 @@ final class Char extends AnyVal { def toDouble: Double = sys.error("stub") /** - * @return the bitwise negation of this value + * Returns the bitwise negation of this value. * @example {{{ * ~5 == -6 * // in binary: ~00000101 == @@ -36,30 +36,30 @@ final class Char extends AnyVal { */ def unary_~ : Int = sys.error("stub") /** - * @return this value, unmodified + * Returns this value, unmodified. */ def unary_+ : Int = sys.error("stub") /** - * @return the negation of this value + * Returns the negation of this value. */ def unary_- : Int = sys.error("stub") def +(x: String): String = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the new right bits with zeroes. * @example {{{ 6 << 3 == 48 // in binary: 0110 << 3 == 0110000 }}} */ def <<(x: Int): Int = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the new right bits with zeroes. * @example {{{ 6 << 3 == 48 // in binary: 0110 << 3 == 0110000 }}} */ def <<(x: Long): Int = sys.error("stub") /** - * @return this value bit-shifted right by the specified number of bits, + * Returns this value bit-shifted right by the specified number of bits, * filling the new left bits with zeroes. * @example {{{ 21 >>> 3 == 2 // in binary: 010101 >>> 3 == 010 }}} * @example {{{ @@ -70,7 +70,7 @@ final class Char extends AnyVal { */ def >>>(x: Int): Int = sys.error("stub") /** - * @return this value bit-shifted right by the specified number of bits, + * Returns this value bit-shifted right by the specified number of bits, * filling the new left bits with zeroes. * @example {{{ 21 >>> 3 == 2 // in binary: 010101 >>> 3 == 010 }}} * @example {{{ @@ -81,7 +81,7 @@ final class Char extends AnyVal { */ def >>>(x: Long): Int = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the right bits with the same value as the left-most bit of this. * The effect of this is to retain the sign of the value. * @example {{{ @@ -92,7 +92,7 @@ final class Char extends AnyVal { */ def >>(x: Int): Int = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the right bits with the same value as the left-most bit of this. * The effect of this is to retain the sign of the value. * @example {{{ @@ -104,181 +104,181 @@ final class Char extends AnyVal { def >>(x: Long): Int = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Double): Boolean = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -289,7 +289,7 @@ final class Char extends AnyVal { */ def |(x: Byte): Int = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -300,7 +300,7 @@ final class Char extends AnyVal { */ def |(x: Short): Int = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -311,7 +311,7 @@ final class Char extends AnyVal { */ def |(x: Char): Int = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -322,7 +322,7 @@ final class Char extends AnyVal { */ def |(x: Int): Int = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -334,7 +334,7 @@ final class Char extends AnyVal { def |(x: Long): Long = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -345,7 +345,7 @@ final class Char extends AnyVal { */ def &(x: Byte): Int = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -356,7 +356,7 @@ final class Char extends AnyVal { */ def &(x: Short): Int = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -367,7 +367,7 @@ final class Char extends AnyVal { */ def &(x: Char): Int = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -378,7 +378,7 @@ final class Char extends AnyVal { */ def &(x: Int): Int = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -390,7 +390,7 @@ final class Char extends AnyVal { def &(x: Long): Long = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -401,7 +401,7 @@ final class Char extends AnyVal { */ def ^(x: Byte): Int = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -412,7 +412,7 @@ final class Char extends AnyVal { */ def ^(x: Short): Int = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -423,7 +423,7 @@ final class Char extends AnyVal { */ def ^(x: Char): Int = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -434,7 +434,7 @@ final class Char extends AnyVal { */ def ^(x: Int): Int = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -446,154 +446,154 @@ final class Char extends AnyVal { def ^(x: Long): Long = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Byte): Int = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Short): Int = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Char): Int = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Int): Int = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Long): Long = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Float): Float = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Double): Double = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Byte): Int = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Short): Int = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Char): Int = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Int): Int = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Long): Long = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Float): Float = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Double): Double = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Byte): Int = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Short): Int = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Char): Int = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Int): Int = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Long): Long = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Float): Float = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Double): Double = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Byte): Int = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Short): Int = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Char): Int = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Int): Int = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Long): Long = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Float): Float = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Double): Double = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Byte): Int = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Short): Int = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Char): Int = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Int): Int = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Long): Long = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Float): Float = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Double): Double = sys.error("stub") override def getClass(): Class[Char] = sys.error("stub") } -object Char extends AnyValCompanion { +object Char extends AnyValCompanion { /** The smallest value representable as a Char. */ final val MinValue = java.lang.Character.MIN_VALUE @@ -622,5 +622,9 @@ object Char extends AnyValCompanion { /** The String representation of the scala.Char companion object. */ override def toString = "object scala.Char" + implicit def char2int(x: Char): Int = x.toInt + implicit def char2long(x: Char): Long = x.toLong + implicit def char2float(x: Char): Float = x.toFloat + implicit def char2double(x: Char): Double = x.toDouble } diff --git a/src/library/scala/Double.scala b/src/library/scala/Double.scala index 01414265c4..bb659b963a 100644 --- a/src/library/scala/Double.scala +++ b/src/library/scala/Double.scala @@ -17,7 +17,7 @@ package scala * There is an implicit conversion from [[scala.Double]] => [[scala.runtime.RichDouble]] * which provides useful non-primitive operations. */ -final class Double extends AnyVal { +final class Double private extends AnyVal { def toByte: Byte = sys.error("stub") def toShort: Short = sys.error("stub") def toChar: Char = sys.error("stub") @@ -27,339 +27,339 @@ final class Double extends AnyVal { def toDouble: Double = sys.error("stub") /** - * @return this value, unmodified + * Returns this value, unmodified. */ def unary_+ : Double = sys.error("stub") /** - * @return the negation of this value + * Returns the negation of this value. */ def unary_- : Double = sys.error("stub") def +(x: String): String = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Double): Boolean = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Byte): Double = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Short): Double = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Char): Double = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Int): Double = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Long): Double = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Float): Double = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Double): Double = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Byte): Double = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Short): Double = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Char): Double = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Int): Double = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Long): Double = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Float): Double = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Double): Double = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Byte): Double = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Short): Double = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Char): Double = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Int): Double = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Long): Double = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Float): Double = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Double): Double = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Byte): Double = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Short): Double = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Char): Double = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Int): Double = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Long): Double = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Float): Double = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Double): Double = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Byte): Double = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Short): Double = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Char): Double = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Int): Double = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Long): Double = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Float): Double = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Double): Double = sys.error("stub") override def getClass(): Class[Double] = sys.error("stub") } -object Double extends AnyValCompanion { +object Double extends AnyValCompanion { /** The smallest positive value greater than 0.0d which is * representable as a Double. */ diff --git a/src/library/scala/Dynamic.scala b/src/library/scala/Dynamic.scala index 32b57ee88f..dcf7599742 100644 --- a/src/library/scala/Dynamic.scala +++ b/src/library/scala/Dynamic.scala @@ -11,7 +11,7 @@ package scala /** A marker trait that enables dynamic invocations. Instances `x` of this * trait allow calls `x.meth(args)` for arbitrary method names `meth` and * argument lists `args`. If a call is not natively supported by `x`, it - * is rewritten to `x.applyDynamic("meth", args)`. + * is rewritten to `x.applyDynamic("meth")(args)`. * * As of scala 2.9, `scalac` must receive the `-Xexperimental` option for * `Dynamic` to receive this treatment. diff --git a/src/library/scala/Either.scala b/src/library/scala/Either.scala index e454cdf5ec..a5e1dc7fe7 100644 --- a/src/library/scala/Either.scala +++ b/src/library/scala/Either.scala @@ -10,6 +10,8 @@ package scala +import language.implicitConversions + /** Represents a value of one of two possible types (a disjoint union.) * Instances of Either are either an instance of [[scala.Left]] or [[scala.Right]]. * @@ -201,12 +203,6 @@ final case class Right[+A, +B](b: B) extends Either[A, B] { } object Either { - class MergeableEither[A](x: Either[A, A]) { - def merge: A = x match { - case Left(a) => a - case Right(a) => a - } - } /** * Allows use of a ``merge`` method to extract values from Either instances @@ -219,7 +215,14 @@ object Either { * r.merge: Seq[Int] // Vector(1) * }}} */ - implicit def either2mergeable[A](x: Either[A, A]): MergeableEither[A] = new MergeableEither(x) + implicit class MergeableEither[A](x: Either[A, A]) { + def merge: A = x match { + case Left(a) => a + case Right(a) => a + } + } + @deprecated("use MergeableEither instead", "2.10") + def either2mergeable[A](x: Either[A, A]): MergeableEither[A] = new MergeableEither(x) /** * Projects an `Either` into a `Left`. diff --git a/src/library/scala/Enumeration.scala b/src/library/scala/Enumeration.scala index dc67d32ba0..ea0d20957d 100644 --- a/src/library/scala/Enumeration.scala +++ b/src/library/scala/Enumeration.scala @@ -70,10 +70,9 @@ abstract class Enumeration (initial: Int) extends Serializable { /** The name of this enumeration. */ - override def toString = ( - (getClass.getName stripSuffix MODULE_SUFFIX_STRING split '.' last) - split Pattern.quote(NAME_JOIN_STRING) last - ) + override def toString = + ((getClass.getName stripSuffix MODULE_SUFFIX_STRING split '.').last split + Pattern.quote(NAME_JOIN_STRING)).last /** The mapping from the integer used to identify values to the actual * values. */ diff --git a/src/library/scala/Float.scala b/src/library/scala/Float.scala index ff5b3cb112..bb03581062 100644 --- a/src/library/scala/Float.scala +++ b/src/library/scala/Float.scala @@ -17,7 +17,7 @@ package scala * There is an implicit conversion from [[scala.Float]] => [[scala.runtime.RichFloat]] * which provides useful non-primitive operations. */ -final class Float extends AnyVal { +final class Float private extends AnyVal { def toByte: Byte = sys.error("stub") def toShort: Short = sys.error("stub") def toChar: Char = sys.error("stub") @@ -27,339 +27,339 @@ final class Float extends AnyVal { def toDouble: Double = sys.error("stub") /** - * @return this value, unmodified + * Returns this value, unmodified. */ def unary_+ : Float = sys.error("stub") /** - * @return the negation of this value + * Returns the negation of this value. */ def unary_- : Float = sys.error("stub") def +(x: String): String = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Double): Boolean = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Byte): Float = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Short): Float = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Char): Float = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Int): Float = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Long): Float = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Float): Float = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Double): Double = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Byte): Float = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Short): Float = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Char): Float = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Int): Float = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Long): Float = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Float): Float = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Double): Double = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Byte): Float = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Short): Float = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Char): Float = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Int): Float = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Long): Float = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Float): Float = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Double): Double = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Byte): Float = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Short): Float = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Char): Float = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Int): Float = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Long): Float = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Float): Float = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Double): Double = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Byte): Float = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Short): Float = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Char): Float = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Int): Float = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Long): Float = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Float): Float = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Double): Double = sys.error("stub") override def getClass(): Class[Float] = sys.error("stub") } -object Float extends AnyValCompanion { +object Float extends AnyValCompanion { /** The smallest positive value greater than 0.0f which is * representable as a Float. */ @@ -401,5 +401,6 @@ object Float extends AnyValCompanion { /** The String representation of the scala.Float companion object. */ override def toString = "object scala.Float" + implicit def float2double(x: Float): Double = x.toDouble } diff --git a/src/library/scala/Int.scala b/src/library/scala/Int.scala index 316bbced2d..d5d7ef011d 100644 --- a/src/library/scala/Int.scala +++ b/src/library/scala/Int.scala @@ -17,7 +17,7 @@ package scala * There is an implicit conversion from [[scala.Int]] => [[scala.runtime.RichInt]] * which provides useful non-primitive operations. */ -final class Int extends AnyVal { +final class Int private extends AnyVal { def toByte: Byte = sys.error("stub") def toShort: Short = sys.error("stub") def toChar: Char = sys.error("stub") @@ -27,7 +27,7 @@ final class Int extends AnyVal { def toDouble: Double = sys.error("stub") /** - * @return the bitwise negation of this value + * Returns the bitwise negation of this value. * @example {{{ * ~5 == -6 * // in binary: ~00000101 == @@ -36,30 +36,30 @@ final class Int extends AnyVal { */ def unary_~ : Int = sys.error("stub") /** - * @return this value, unmodified + * Returns this value, unmodified. */ def unary_+ : Int = sys.error("stub") /** - * @return the negation of this value + * Returns the negation of this value. */ def unary_- : Int = sys.error("stub") def +(x: String): String = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the new right bits with zeroes. * @example {{{ 6 << 3 == 48 // in binary: 0110 << 3 == 0110000 }}} */ def <<(x: Int): Int = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the new right bits with zeroes. * @example {{{ 6 << 3 == 48 // in binary: 0110 << 3 == 0110000 }}} */ def <<(x: Long): Int = sys.error("stub") /** - * @return this value bit-shifted right by the specified number of bits, + * Returns this value bit-shifted right by the specified number of bits, * filling the new left bits with zeroes. * @example {{{ 21 >>> 3 == 2 // in binary: 010101 >>> 3 == 010 }}} * @example {{{ @@ -70,7 +70,7 @@ final class Int extends AnyVal { */ def >>>(x: Int): Int = sys.error("stub") /** - * @return this value bit-shifted right by the specified number of bits, + * Returns this value bit-shifted right by the specified number of bits, * filling the new left bits with zeroes. * @example {{{ 21 >>> 3 == 2 // in binary: 010101 >>> 3 == 010 }}} * @example {{{ @@ -81,7 +81,7 @@ final class Int extends AnyVal { */ def >>>(x: Long): Int = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the right bits with the same value as the left-most bit of this. * The effect of this is to retain the sign of the value. * @example {{{ @@ -92,7 +92,7 @@ final class Int extends AnyVal { */ def >>(x: Int): Int = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the right bits with the same value as the left-most bit of this. * The effect of this is to retain the sign of the value. * @example {{{ @@ -104,181 +104,181 @@ final class Int extends AnyVal { def >>(x: Long): Int = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Double): Boolean = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -289,7 +289,7 @@ final class Int extends AnyVal { */ def |(x: Byte): Int = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -300,7 +300,7 @@ final class Int extends AnyVal { */ def |(x: Short): Int = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -311,7 +311,7 @@ final class Int extends AnyVal { */ def |(x: Char): Int = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -322,7 +322,7 @@ final class Int extends AnyVal { */ def |(x: Int): Int = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -334,7 +334,7 @@ final class Int extends AnyVal { def |(x: Long): Long = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -345,7 +345,7 @@ final class Int extends AnyVal { */ def &(x: Byte): Int = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -356,7 +356,7 @@ final class Int extends AnyVal { */ def &(x: Short): Int = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -367,7 +367,7 @@ final class Int extends AnyVal { */ def &(x: Char): Int = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -378,7 +378,7 @@ final class Int extends AnyVal { */ def &(x: Int): Int = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -390,7 +390,7 @@ final class Int extends AnyVal { def &(x: Long): Long = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -401,7 +401,7 @@ final class Int extends AnyVal { */ def ^(x: Byte): Int = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -412,7 +412,7 @@ final class Int extends AnyVal { */ def ^(x: Short): Int = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -423,7 +423,7 @@ final class Int extends AnyVal { */ def ^(x: Char): Int = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -434,7 +434,7 @@ final class Int extends AnyVal { */ def ^(x: Int): Int = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -446,154 +446,154 @@ final class Int extends AnyVal { def ^(x: Long): Long = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Byte): Int = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Short): Int = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Char): Int = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Int): Int = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Long): Long = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Float): Float = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Double): Double = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Byte): Int = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Short): Int = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Char): Int = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Int): Int = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Long): Long = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Float): Float = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Double): Double = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Byte): Int = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Short): Int = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Char): Int = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Int): Int = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Long): Long = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Float): Float = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Double): Double = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Byte): Int = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Short): Int = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Char): Int = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Int): Int = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Long): Long = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Float): Float = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Double): Double = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Byte): Int = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Short): Int = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Char): Int = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Int): Int = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Long): Long = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Float): Float = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Double): Double = sys.error("stub") override def getClass(): Class[Int] = sys.error("stub") } -object Int extends AnyValCompanion { +object Int extends AnyValCompanion { /** The smallest value representable as a Int. */ final val MinValue = java.lang.Integer.MIN_VALUE @@ -622,5 +622,8 @@ object Int extends AnyValCompanion { /** The String representation of the scala.Int companion object. */ override def toString = "object scala.Int" + implicit def int2long(x: Int): Long = x.toLong + implicit def int2float(x: Int): Float = x.toFloat + implicit def int2double(x: Int): Double = x.toDouble } diff --git a/src/library/scala/Long.scala b/src/library/scala/Long.scala index ce8618c22a..85131b4f54 100644 --- a/src/library/scala/Long.scala +++ b/src/library/scala/Long.scala @@ -17,7 +17,7 @@ package scala * There is an implicit conversion from [[scala.Long]] => [[scala.runtime.RichLong]] * which provides useful non-primitive operations. */ -final class Long extends AnyVal { +final class Long private extends AnyVal { def toByte: Byte = sys.error("stub") def toShort: Short = sys.error("stub") def toChar: Char = sys.error("stub") @@ -27,7 +27,7 @@ final class Long extends AnyVal { def toDouble: Double = sys.error("stub") /** - * @return the bitwise negation of this value + * Returns the bitwise negation of this value. * @example {{{ * ~5 == -6 * // in binary: ~00000101 == @@ -36,30 +36,30 @@ final class Long extends AnyVal { */ def unary_~ : Long = sys.error("stub") /** - * @return this value, unmodified + * Returns this value, unmodified. */ def unary_+ : Long = sys.error("stub") /** - * @return the negation of this value + * Returns the negation of this value. */ def unary_- : Long = sys.error("stub") def +(x: String): String = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the new right bits with zeroes. * @example {{{ 6 << 3 == 48 // in binary: 0110 << 3 == 0110000 }}} */ def <<(x: Int): Long = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the new right bits with zeroes. * @example {{{ 6 << 3 == 48 // in binary: 0110 << 3 == 0110000 }}} */ def <<(x: Long): Long = sys.error("stub") /** - * @return this value bit-shifted right by the specified number of bits, + * Returns this value bit-shifted right by the specified number of bits, * filling the new left bits with zeroes. * @example {{{ 21 >>> 3 == 2 // in binary: 010101 >>> 3 == 010 }}} * @example {{{ @@ -70,7 +70,7 @@ final class Long extends AnyVal { */ def >>>(x: Int): Long = sys.error("stub") /** - * @return this value bit-shifted right by the specified number of bits, + * Returns this value bit-shifted right by the specified number of bits, * filling the new left bits with zeroes. * @example {{{ 21 >>> 3 == 2 // in binary: 010101 >>> 3 == 010 }}} * @example {{{ @@ -81,7 +81,7 @@ final class Long extends AnyVal { */ def >>>(x: Long): Long = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the right bits with the same value as the left-most bit of this. * The effect of this is to retain the sign of the value. * @example {{{ @@ -92,7 +92,7 @@ final class Long extends AnyVal { */ def >>(x: Int): Long = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the right bits with the same value as the left-most bit of this. * The effect of this is to retain the sign of the value. * @example {{{ @@ -104,181 +104,181 @@ final class Long extends AnyVal { def >>(x: Long): Long = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Double): Boolean = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -289,7 +289,7 @@ final class Long extends AnyVal { */ def |(x: Byte): Long = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -300,7 +300,7 @@ final class Long extends AnyVal { */ def |(x: Short): Long = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -311,7 +311,7 @@ final class Long extends AnyVal { */ def |(x: Char): Long = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -322,7 +322,7 @@ final class Long extends AnyVal { */ def |(x: Int): Long = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -334,7 +334,7 @@ final class Long extends AnyVal { def |(x: Long): Long = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -345,7 +345,7 @@ final class Long extends AnyVal { */ def &(x: Byte): Long = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -356,7 +356,7 @@ final class Long extends AnyVal { */ def &(x: Short): Long = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -367,7 +367,7 @@ final class Long extends AnyVal { */ def &(x: Char): Long = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -378,7 +378,7 @@ final class Long extends AnyVal { */ def &(x: Int): Long = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -390,7 +390,7 @@ final class Long extends AnyVal { def &(x: Long): Long = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -401,7 +401,7 @@ final class Long extends AnyVal { */ def ^(x: Byte): Long = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -412,7 +412,7 @@ final class Long extends AnyVal { */ def ^(x: Short): Long = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -423,7 +423,7 @@ final class Long extends AnyVal { */ def ^(x: Char): Long = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -434,7 +434,7 @@ final class Long extends AnyVal { */ def ^(x: Int): Long = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -446,154 +446,154 @@ final class Long extends AnyVal { def ^(x: Long): Long = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Byte): Long = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Short): Long = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Char): Long = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Int): Long = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Long): Long = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Float): Float = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Double): Double = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Byte): Long = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Short): Long = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Char): Long = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Int): Long = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Long): Long = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Float): Float = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Double): Double = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Byte): Long = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Short): Long = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Char): Long = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Int): Long = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Long): Long = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Float): Float = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Double): Double = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Byte): Long = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Short): Long = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Char): Long = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Int): Long = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Long): Long = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Float): Float = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Double): Double = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Byte): Long = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Short): Long = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Char): Long = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Int): Long = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Long): Long = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Float): Float = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Double): Double = sys.error("stub") override def getClass(): Class[Long] = sys.error("stub") } -object Long extends AnyValCompanion { +object Long extends AnyValCompanion { /** The smallest value representable as a Long. */ final val MinValue = java.lang.Long.MIN_VALUE @@ -622,5 +622,7 @@ object Long extends AnyValCompanion { /** The String representation of the scala.Long companion object. */ override def toString = "object scala.Long" + implicit def long2float(x: Long): Float = x.toFloat + implicit def long2double(x: Long): Double = x.toDouble } diff --git a/src/library/scala/LowPriorityImplicits.scala b/src/library/scala/LowPriorityImplicits.scala index 447a3c3819..491cd417a3 100644 --- a/src/library/scala/LowPriorityImplicits.scala +++ b/src/library/scala/LowPriorityImplicits.scala @@ -12,6 +12,7 @@ import scala.collection.{ mutable, immutable, generic } import mutable.WrappedArray import immutable.WrappedString import generic.CanBuildFrom +import language.implicitConversions /** The `LowPriorityImplicits` class provides implicit values that * are valid in all Scala compilation units without explicit qualification, diff --git a/src/library/scala/Option.scala b/src/library/scala/Option.scala index 2d87ccb261..a58297d7d4 100644 --- a/src/library/scala/Option.scala +++ b/src/library/scala/Option.scala @@ -9,6 +9,9 @@ package scala object Option { + + import language.implicitConversions + /** An implicit conversion that converts an option to an iterable value */ implicit def option2Iterable[A](xo: Option[A]): Iterable[A] = xo.toList @@ -79,6 +82,17 @@ object Option { * @define option [[scala.Option]] * @define p `p` * @define f `f` + * @define coll option + * @define Coll Option + * @define orderDependent + * @define orderDependentFold + * @define mayNotTerminateInf + * @define willNotTerminateInf + * @define collectExample + * @define undefinedorder + * @define thatinfo the class of the returned collection. In the standard library configuration, `That` is `Iterable[B]` + * @define bfinfo an implicit value of class `CanBuildFrom` which determines the result class `That` from the current + * representation type `Repr` and the new element type `B`. */ sealed abstract class Option[+A] extends Product with Serializable { self => diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index b5006e7948..15e007528b 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -14,6 +14,7 @@ import mutable.ArrayOps import generic.CanBuildFrom import annotation.{ elidable, implicitNotFound } import annotation.elidable.ASSERTION +import language.{implicitConversions, existentials} /** The `Predef` object provides definitions that are accessible in all Scala * compilation units without explicit qualification. @@ -99,17 +100,40 @@ object Predef extends LowPriorityImplicits { // def AnyRef = scala.AnyRef // Manifest types, companions, and incantations for summoning + @deprecated("Use `@scala.reflect.ClassTag` instead", "2.10.0") type ClassManifest[T] = scala.reflect.ClassManifest[T] - type Manifest[T] = scala.reflect.Manifest[T] + @deprecated("OptManifest is no longer supported and using it may lead to incorrect results, use `@scala.reflect.TypeTag` instead", "2.10.0") type OptManifest[T] = scala.reflect.OptManifest[T] + @deprecated("Use `@scala.reflect.ConcreteTypeTag` instead", "2.10.0") + type Manifest[T] = scala.reflect.Manifest[T] + @deprecated("Use `@scala.reflect.ClassTag` instead", "2.10.0") val ClassManifest = scala.reflect.ClassManifest - val Manifest = scala.reflect.Manifest - val NoManifest = scala.reflect.NoManifest + // [Paul to Eugene] No lazy vals in Predef. Too expensive. Have to work harder on breaking initialization dependencies. + @deprecated("Use `@scala.reflect.ConcreteTypeTag` instead", "2.10.0") + lazy val Manifest = scala.reflect.Manifest // needs to be lazy, because requires scala.reflect.mirror instance + @deprecated("NoManifest is no longer supported and using it may lead to incorrect results, use `@scala.reflect.TypeTag` instead", "2.10.0") + lazy val NoManifest = scala.reflect.NoManifest // needs to be lazy, because requires scala.reflect.mirror instance def manifest[T](implicit m: Manifest[T]) = m def classManifest[T](implicit m: ClassManifest[T]) = m def optManifest[T](implicit m: OptManifest[T]) = m + // Tag types and companions, and incantations for summoning + type ClassTag[T] = scala.reflect.ClassTag[T] + type TypeTag[T] = scala.reflect.TypeTag[T] + type ConcreteTypeTag[T] = scala.reflect.ConcreteTypeTag[T] + val ClassTag = scala.reflect.ClassTag // doesn't need to be lazy, because it's not a path-dependent type + // [Paul to Eugene] No lazy vals in Predef. Too expensive. Have to work harder on breaking initialization dependencies. + lazy val TypeTag = scala.reflect.TypeTag // needs to be lazy, because requires scala.reflect.mirror instance + lazy val ConcreteTypeTag = scala.reflect.ConcreteTypeTag + + // [Eugene to Martin] it's really tedious to type "implicitly[...]" all the time, so I'm reintroducing these shortcuts + def classTag[T](implicit ctag: ClassTag[T]) = ctag + def tag[T](implicit ttag: TypeTag[T]) = ttag + def typeTag[T](implicit ttag: TypeTag[T]) = ttag + def concreteTag[T](implicit cttag: ConcreteTypeTag[T]) = cttag + def concreteTypeTag[T](implicit cttag: ConcreteTypeTag[T]) = cttag + // Minor variations on identity functions def identity[A](x: A): A = x // @see `conforms` for the implicit version @inline def implicitly[T](implicit e: T) = e // for summoning implicit values from the nether world -- TODO: when dependent method types are on by default, give this result type `e.type`, so that inliner has better chance of knowing which method to inline in calls like `implicitly[MatchingStrategy[Option]].zero` @@ -325,30 +349,30 @@ object Predef extends LowPriorityImplicits { // Primitive Widenings -------------------------------------------------------------- - implicit def byte2short(x: Byte): Short = x.toShort - implicit def byte2int(x: Byte): Int = x.toInt - implicit def byte2long(x: Byte): Long = x.toLong - implicit def byte2float(x: Byte): Float = x.toFloat - implicit def byte2double(x: Byte): Double = x.toDouble + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def byte2short(x: Byte): Short = x.toShort + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def byte2int(x: Byte): Int = x.toInt + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def byte2long(x: Byte): Long = x.toLong + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def byte2float(x: Byte): Float = x.toFloat + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def byte2double(x: Byte): Double = x.toDouble - implicit def short2int(x: Short): Int = x.toInt - implicit def short2long(x: Short): Long = x.toLong - implicit def short2float(x: Short): Float = x.toFloat - implicit def short2double(x: Short): Double = x.toDouble + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def short2int(x: Short): Int = x.toInt + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def short2long(x: Short): Long = x.toLong + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def short2float(x: Short): Float = x.toFloat + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def short2double(x: Short): Double = x.toDouble - implicit def char2int(x: Char): Int = x.toInt - implicit def char2long(x: Char): Long = x.toLong - implicit def char2float(x: Char): Float = x.toFloat - implicit def char2double(x: Char): Double = x.toDouble + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def char2int(x: Char): Int = x.toInt + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def char2long(x: Char): Long = x.toLong + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def char2float(x: Char): Float = x.toFloat + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def char2double(x: Char): Double = x.toDouble - implicit def int2long(x: Int): Long = x.toLong - implicit def int2float(x: Int): Float = x.toFloat - implicit def int2double(x: Int): Double = x.toDouble + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def int2long(x: Int): Long = x.toLong + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def int2float(x: Int): Float = x.toFloat + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def int2double(x: Int): Double = x.toDouble - implicit def long2float(x: Long): Float = x.toFloat - implicit def long2double(x: Long): Double = x.toDouble + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def long2float(x: Long): Float = x.toFloat + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def long2double(x: Long): Double = x.toDouble - implicit def float2double(x: Float): Double = x.toDouble + @deprecated("Use a method in an AnyVal's companion object", "2.10.0") def float2double(x: Float): Double = x.toDouble // "Autoboxing" and "Autounboxing" --------------------------------------------------- diff --git a/src/library/scala/Short.scala b/src/library/scala/Short.scala index 5664c3b44c..1060a9db16 100644 --- a/src/library/scala/Short.scala +++ b/src/library/scala/Short.scala @@ -17,7 +17,7 @@ package scala * There is an implicit conversion from [[scala.Short]] => [[scala.runtime.RichShort]] * which provides useful non-primitive operations. */ -final class Short extends AnyVal { +final class Short private extends AnyVal { def toByte: Byte = sys.error("stub") def toShort: Short = sys.error("stub") def toChar: Char = sys.error("stub") @@ -27,7 +27,7 @@ final class Short extends AnyVal { def toDouble: Double = sys.error("stub") /** - * @return the bitwise negation of this value + * Returns the bitwise negation of this value. * @example {{{ * ~5 == -6 * // in binary: ~00000101 == @@ -36,30 +36,30 @@ final class Short extends AnyVal { */ def unary_~ : Int = sys.error("stub") /** - * @return this value, unmodified + * Returns this value, unmodified. */ def unary_+ : Int = sys.error("stub") /** - * @return the negation of this value + * Returns the negation of this value. */ def unary_- : Int = sys.error("stub") def +(x: String): String = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the new right bits with zeroes. * @example {{{ 6 << 3 == 48 // in binary: 0110 << 3 == 0110000 }}} */ def <<(x: Int): Int = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the new right bits with zeroes. * @example {{{ 6 << 3 == 48 // in binary: 0110 << 3 == 0110000 }}} */ def <<(x: Long): Int = sys.error("stub") /** - * @return this value bit-shifted right by the specified number of bits, + * Returns this value bit-shifted right by the specified number of bits, * filling the new left bits with zeroes. * @example {{{ 21 >>> 3 == 2 // in binary: 010101 >>> 3 == 010 }}} * @example {{{ @@ -70,7 +70,7 @@ final class Short extends AnyVal { */ def >>>(x: Int): Int = sys.error("stub") /** - * @return this value bit-shifted right by the specified number of bits, + * Returns this value bit-shifted right by the specified number of bits, * filling the new left bits with zeroes. * @example {{{ 21 >>> 3 == 2 // in binary: 010101 >>> 3 == 010 }}} * @example {{{ @@ -81,7 +81,7 @@ final class Short extends AnyVal { */ def >>>(x: Long): Int = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the right bits with the same value as the left-most bit of this. * The effect of this is to retain the sign of the value. * @example {{{ @@ -92,7 +92,7 @@ final class Short extends AnyVal { */ def >>(x: Int): Int = sys.error("stub") /** - * @return this value bit-shifted left by the specified number of bits, + * Returns this value bit-shifted left by the specified number of bits, * filling in the right bits with the same value as the left-most bit of this. * The effect of this is to retain the sign of the value. * @example {{{ @@ -104,181 +104,181 @@ final class Short extends AnyVal { def >>(x: Long): Int = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is equal x, `false` otherwise + * Returns `true` if this value is equal to x, `false` otherwise. */ def ==(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is not equal to x, `false` otherwise + * Returns `true` if this value is not equal to x, `false` otherwise. */ def !=(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is less than x, `false` otherwise + * Returns `true` if this value is less than x, `false` otherwise. */ def <(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is less than or equal to x, `false` otherwise + * Returns `true` if this value is less than or equal to x, `false` otherwise. */ def <=(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than x, `false` otherwise + * Returns `true` if this value is greater than x, `false` otherwise. */ def >(x: Double): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Byte): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Short): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Char): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Int): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Long): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Float): Boolean = sys.error("stub") /** - * @return `true` if this value is greater than or equal to x, `false` otherwise + * Returns `true` if this value is greater than or equal to x, `false` otherwise. */ def >=(x: Double): Boolean = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -289,7 +289,7 @@ final class Short extends AnyVal { */ def |(x: Byte): Int = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -300,7 +300,7 @@ final class Short extends AnyVal { */ def |(x: Short): Int = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -311,7 +311,7 @@ final class Short extends AnyVal { */ def |(x: Char): Int = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -322,7 +322,7 @@ final class Short extends AnyVal { */ def |(x: Int): Int = sys.error("stub") /** - * @return the bitwise OR of this value and x + * Returns the bitwise OR of this value and `x`. * @example {{{ * (0xf0 | 0xaa) == 0xfa * // in binary: 11110000 @@ -334,7 +334,7 @@ final class Short extends AnyVal { def |(x: Long): Long = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -345,7 +345,7 @@ final class Short extends AnyVal { */ def &(x: Byte): Int = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -356,7 +356,7 @@ final class Short extends AnyVal { */ def &(x: Short): Int = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -367,7 +367,7 @@ final class Short extends AnyVal { */ def &(x: Char): Int = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -378,7 +378,7 @@ final class Short extends AnyVal { */ def &(x: Int): Int = sys.error("stub") /** - * @return the bitwise AND of this value and x + * Returns the bitwise AND of this value and `x`. * @example {{{ * (0xf0 & 0xaa) == 0xa0 * // in binary: 11110000 @@ -390,7 +390,7 @@ final class Short extends AnyVal { def &(x: Long): Long = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -401,7 +401,7 @@ final class Short extends AnyVal { */ def ^(x: Byte): Int = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -412,7 +412,7 @@ final class Short extends AnyVal { */ def ^(x: Short): Int = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -423,7 +423,7 @@ final class Short extends AnyVal { */ def ^(x: Char): Int = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -434,7 +434,7 @@ final class Short extends AnyVal { */ def ^(x: Int): Int = sys.error("stub") /** - * @return the bitwise XOR of this value and x + * Returns the bitwise XOR of this value and `x`. * @example {{{ * (0xf0 ^ 0xaa) == 0x5a * // in binary: 11110000 @@ -446,154 +446,154 @@ final class Short extends AnyVal { def ^(x: Long): Long = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Byte): Int = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Short): Int = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Char): Int = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Int): Int = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Long): Long = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Float): Float = sys.error("stub") /** - * @return the sum of this value and x + * Returns the sum of this value and `x`. */ def +(x: Double): Double = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Byte): Int = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Short): Int = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Char): Int = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Int): Int = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Long): Long = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Float): Float = sys.error("stub") /** - * @return the difference of this value and x + * Returns the difference of this value and `x`. */ def -(x: Double): Double = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Byte): Int = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Short): Int = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Char): Int = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Int): Int = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Long): Long = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Float): Float = sys.error("stub") /** - * @return the product of this value and x + * Returns the product of this value and `x`. */ def *(x: Double): Double = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Byte): Int = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Short): Int = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Char): Int = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Int): Int = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Long): Long = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Float): Float = sys.error("stub") /** - * @return the quotient of this value and x + * Returns the quotient of this value and `x`. */ def /(x: Double): Double = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Byte): Int = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Short): Int = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Char): Int = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Int): Int = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Long): Long = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Float): Float = sys.error("stub") /** - * @return the remainder of the division of this value by x + * Returns the remainder of the division of this value by `x`. */ def %(x: Double): Double = sys.error("stub") override def getClass(): Class[Short] = sys.error("stub") } -object Short extends AnyValCompanion { +object Short extends AnyValCompanion { /** The smallest value representable as a Short. */ final val MinValue = java.lang.Short.MIN_VALUE @@ -622,5 +622,9 @@ object Short extends AnyValCompanion { /** The String representation of the scala.Short companion object. */ override def toString = "object scala.Short" + implicit def short2int(x: Short): Int = x.toInt + implicit def short2long(x: Short): Long = x.toLong + implicit def short2float(x: Short): Float = x.toFloat + implicit def short2double(x: Short): Double = x.toDouble } diff --git a/src/library/scala/Tuple2.scala b/src/library/scala/Tuple2.scala index b1befca4fa..37ab564c3c 100644 --- a/src/library/scala/Tuple2.scala +++ b/src/library/scala/Tuple2.scala @@ -23,7 +23,7 @@ case class Tuple2[@specialized(Int, Long, Double, Char, Boolean, AnyRef) +T1, @s extends Product2[T1, T2] { override def toString() = "(" + _1 + "," + _2 + ")" - + /** Swaps the elements of this `Tuple`. * @return a new Tuple where the first element is the second element of this Tuple and the * second element is the first element of this Tuple. @@ -54,6 +54,16 @@ case class Tuple2[@specialized(Int, Long, Double, Char, Boolean, AnyRef) +T1, @s def zipped[Repr1, El1, Repr2, El2](implicit w1: T1 => TLike[El1, Repr1], w2: T2 => ILike[El2, Repr2]): Zipped[Repr1, El1, Repr2, El2] = new Zipped[Repr1, El1, Repr2, El2](_1, _2) + /** + * @define coll zipped + * @define Coll Zipped + * @define orderDependent + * @define orderDependentFold + * @define mayNotTerminateInf + * @define willNotTerminateInf + * @define collectExample + * @define undefinedorder + */ class Zipped[+Repr1, +El1, +Repr2, +El2](coll1: TLike[El1, Repr1], coll2: ILike[El2, Repr2]) { // coll2: ILike for filter def map[B, To](f: (El1, El2) => B)(implicit cbf: CBF[Repr1, B, To]): To = { val b = cbf(coll1.repr) diff --git a/src/library/scala/Tuple3.scala b/src/library/scala/Tuple3.scala index 0d5399308b..cd5ee23757 100644 --- a/src/library/scala/Tuple3.scala +++ b/src/library/scala/Tuple3.scala @@ -24,7 +24,7 @@ case class Tuple3[+T1, +T2, +T3](_1: T1, _2: T2, _3: T3) extends Product3[T1, T2, T3] { override def toString() = "(" + _1 + "," + _2 + "," + _3 + ")" - + @deprecated("Use `zipped` instead.", "2.9.0") def zip[Repr1, El1, El2, El3, To](implicit w1: T1 => TLike[El1, Repr1], @@ -53,6 +53,17 @@ case class Tuple3[+T1, +T2, +T3](_1: T1, _2: T2, _3: T3) w3: T3 => ILike[El3, Repr3]): Zipped[Repr1, El1, Repr2, El2, Repr3, El3] = new Zipped[Repr1, El1, Repr2, El2, Repr3, El3](_1, _2, _3) + /** + * @define coll zipped + * @define Coll Zipped + * @define orderDependent + * @define orderDependentFold + * @define mayNotTerminateInf + * @define willNotTerminateInf + * @define collectExample + * @define undefinedorder + * @define thatInfo The class of the returned collection. + */ class Zipped[+Repr1, +El1, +Repr2, +El2, +Repr3, +El3](coll1: TLike[El1, Repr1], coll2: ILike[El2, Repr2], coll3: ILike[El3, Repr3]) { diff --git a/src/library/scala/Unit.scala b/src/library/scala/Unit.scala index f6ed0121ab..3da5c083d4 100644 --- a/src/library/scala/Unit.scala +++ b/src/library/scala/Unit.scala @@ -16,11 +16,11 @@ package scala * runtime system. A method with return type `Unit` is analogous to a Java * method which is declared `void`. */ -final class Unit extends AnyVal { +final class Unit private extends AnyVal { override def getClass(): Class[Unit] = sys.error("stub") } -object Unit extends AnyValCompanion { +object Unit extends AnyValCompanion { /** Transform a value type into a boxed reference type. * diff --git a/src/library/scala/annotation/meta/companionClass.scala b/src/library/scala/annotation/meta/companionClass.scala new file mode 100644 index 0000000000..8e53f6caf9 --- /dev/null +++ b/src/library/scala/annotation/meta/companionClass.scala @@ -0,0 +1,17 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ +package scala.annotation.meta + +/** + * When defining an implicit class, the Scala compiler creates an implicit + * conversion method for it. Annotations `@companionClass` and `@companionMethod` + * control where an annotation on the implicit class will go. By default, annotations + * on an implicit class end up only on the class. + * + */ +final class companionClass extends annotation.StaticAnnotation diff --git a/src/library/scala/annotation/meta/companionMethod.scala b/src/library/scala/annotation/meta/companionMethod.scala new file mode 100644 index 0000000000..379c4f3385 --- /dev/null +++ b/src/library/scala/annotation/meta/companionMethod.scala @@ -0,0 +1,17 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ +package scala.annotation.meta + +/** + * When defining an implicit class, the Scala compiler creates an implicit + * conversion method for it. Annotations `@companionClass` and `@companionMethod` + * control where an annotation on the implicit class will go. By default, annotations + * on an implicit class end up only on the class. + * + */ +final class companionMethod extends annotation.StaticAnnotation diff --git a/src/library/scala/reflect/NoManifest.scala b/src/library/scala/annotation/meta/companionObject.scala index 191e46ae39..d329df5c42 100644 --- a/src/library/scala/reflect/NoManifest.scala +++ b/src/library/scala/annotation/meta/companionObject.scala @@ -1,15 +1,14 @@ /* __ *\ ** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL ** +** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL ** ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** ** /____/\___/_/ |_/____/_/ | | ** ** |/ ** \* */ +package scala.annotation.meta -package scala.reflect - -/** One of the branches of an [[scala.reflect.OptManifest]]. - */ -object NoManifest extends OptManifest[Nothing] with Serializable { - override def toString = "<?>" -} +/** + * Currently unused; intended as an annotation target for classes such as case classes + * that automatically generate a companion object + */ +final class companionObject extends annotation.StaticAnnotation diff --git a/src/library/scala/reflect/OptManifest.scala b/src/library/scala/annotation/meta/languageFeature.scala index 2a955deb2c..23acc01b51 100644 --- a/src/library/scala/reflect/OptManifest.scala +++ b/src/library/scala/annotation/meta/languageFeature.scala @@ -1,17 +1,13 @@ /* __ *\ ** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL ** +** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL ** ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** ** /____/\___/_/ |_/____/_/ | | ** ** |/ ** \* */ +package scala.annotation.meta -package scala.reflect - -/** A `OptManifest[T]` is an optional [[scala.reflect.Manifest]]. - * - * It is either a `Manifest` or the value `NoManifest`. - * - * @author Martin Odersky +/** + * An annotation giving particulars for a language feature in object `scala.language`. */ -trait OptManifest[+T] extends Serializable +final class languageFeature(feature: String, enableRequired: Boolean) extends annotation.StaticAnnotation diff --git a/src/library/scala/collection/DefaultMap.scala b/src/library/scala/collection/DefaultMap.scala index 3af535bdaa..d00414751a 100644 --- a/src/library/scala/collection/DefaultMap.scala +++ b/src/library/scala/collection/DefaultMap.scala @@ -41,7 +41,7 @@ trait DefaultMap[A, +B] extends Map[A, B] { self => */ override def - (key: A): Map[A, B] = { val b = newBuilder - b ++= this filter (key !=) + b ++= this filter (key != _) b.result } } diff --git a/src/library/scala/collection/GenSeqLike.scala b/src/library/scala/collection/GenSeqLike.scala index 755abcd2bf..71316cefc9 100644 --- a/src/library/scala/collection/GenSeqLike.scala +++ b/src/library/scala/collection/GenSeqLike.scala @@ -142,7 +142,7 @@ trait GenSeqLike[+A, +Repr] extends Any with GenIterableLike[A, Repr] with Equal * $mayNotTerminateInf * */ - def indexOf[B >: A](elem: B, from: Int): Int = indexWhere(elem ==, from) + def indexOf[B >: A](elem: B, from: Int): Int = indexWhere(elem == _, from) /** Finds index of last occurrence of some value in this $coll. * @@ -157,7 +157,7 @@ trait GenSeqLike[+A, +Repr] extends Any with GenIterableLike[A, Repr] with Equal * $willNotTerminateInf * */ - def lastIndexOf[B >: A](elem: B): Int = lastIndexWhere(elem ==) + def lastIndexOf[B >: A](elem: B): Int = lastIndexWhere(elem == _) /** Finds index of last occurrence of some value in this $coll before or at a given end index. * @@ -170,7 +170,7 @@ trait GenSeqLike[+A, +Repr] extends Any with GenIterableLike[A, Repr] with Equal * @usecase def lastIndexOf(elem: A, end: Int): Int * @inheritdoc */ - def lastIndexOf[B >: A](elem: B, end: Int): Int = lastIndexWhere(elem ==, end) + def lastIndexOf[B >: A](elem: B, end: Int): Int = lastIndexWhere(elem == _, end) /** Finds index of last element satisfying some predicate. * diff --git a/src/library/scala/collection/IterableLike.scala b/src/library/scala/collection/IterableLike.scala index fb6d154952..3c4ad0612a 100644 --- a/src/library/scala/collection/IterableLike.scala +++ b/src/library/scala/collection/IterableLike.scala @@ -134,7 +134,7 @@ self => it.next i += 1 } - b ++= it result + (b ++= it).result } override /*TraversableLike*/ def takeWhile(p: A => Boolean): Repr = { diff --git a/src/library/scala/collection/IterableViewLike.scala b/src/library/scala/collection/IterableViewLike.scala index ce2daf08d4..c842475590 100644 --- a/src/library/scala/collection/IterableViewLike.scala +++ b/src/library/scala/collection/IterableViewLike.scala @@ -11,6 +11,7 @@ package scala.collection import generic._ import TraversableView.NoBuilder import immutable.Stream +import language.implicitConversions /** A template trait for non-strict views of iterable collections. * $iterableViewInfo diff --git a/src/library/scala/collection/SeqLike.scala b/src/library/scala/collection/SeqLike.scala index fd1d42d7e9..ced99e897f 100644 --- a/src/library/scala/collection/SeqLike.scala +++ b/src/library/scala/collection/SeqLike.scala @@ -185,7 +185,7 @@ trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[ private[this] def init() = { val m = mutable.HashMap[A, Int]() - val (es, is) = thisCollection map (e => (e, m.getOrElseUpdate(e, m.size))) sortBy (_._2) unzip + val (es, is) = (thisCollection map (e => (e, m.getOrElseUpdate(e, m.size))) sortBy (_._2)).unzip (es.toBuffer, is.toArray) } @@ -240,7 +240,7 @@ trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[ val m = mutable.HashMap[A, Int]() // e => (e, weight(e)) - val (es, is) = thisCollection map (e => (e, m.getOrElseUpdate(e, m.size))) sortBy (_._2) unzip + val (es, is) = (thisCollection map (e => (e, m.getOrElseUpdate(e, m.size))) sortBy (_._2)).unzip val cs = new Array[Int](m.size) is foreach (i => cs(i) += 1) val ns = new Array[Int](cs.length) diff --git a/src/library/scala/collection/SeqProxyLike.scala b/src/library/scala/collection/SeqProxyLike.scala index ce32ba97c2..3783ef771f 100644 --- a/src/library/scala/collection/SeqProxyLike.scala +++ b/src/library/scala/collection/SeqProxyLike.scala @@ -36,7 +36,7 @@ trait SeqProxyLike[+A, +Repr <: SeqLike[A, Repr] with Seq[A]] extends SeqLike[A, override def indexOf[B >: A](elem: B): Int = self.indexOf(elem) override def indexOf[B >: A](elem: B, from: Int): Int = self.indexOf(elem, from) override def lastIndexOf[B >: A](elem: B): Int = self.lastIndexOf(elem) - override def lastIndexOf[B >: A](elem: B, end: Int): Int = self.lastIndexWhere(elem ==, end) + override def lastIndexOf[B >: A](elem: B, end: Int): Int = self.lastIndexWhere(elem == _, end) override def lastIndexWhere(p: A => Boolean): Int = self.lastIndexWhere(p, length - 1) override def lastIndexWhere(p: A => Boolean, end: Int): Int = self.lastIndexWhere(p) override def reverse: Repr = self.reverse diff --git a/src/library/scala/collection/TraversableLike.scala b/src/library/scala/collection/TraversableLike.scala index 1f5beb5109..a4f36d20c7 100644 --- a/src/library/scala/collection/TraversableLike.scala +++ b/src/library/scala/collection/TraversableLike.scala @@ -487,7 +487,7 @@ trait TraversableLike[+A, +Repr] extends Any if (n <= 0) { val b = newBuilder b.sizeHint(this) - b ++= thisCollection result + (b ++= thisCollection).result } else sliceWithKnownDelta(n, Int.MaxValue, -n) @@ -775,6 +775,6 @@ trait TraversableLike[+A, +Repr] extends Any // A helper for tails and inits. private def iterateUntilEmpty(f: Traversable[A @uV] => Traversable[A @uV]): Iterator[Repr] = { val it = Iterator.iterate(thisCollection)(f) takeWhile (x => !x.isEmpty) - it ++ Iterator(Nil) map (newBuilder ++= _ result) + it ++ Iterator(Nil) map (x => (newBuilder ++= x).result) } } diff --git a/src/library/scala/collection/TraversableOnce.scala b/src/library/scala/collection/TraversableOnce.scala index 62ea692b90..e68ef9e4de 100644 --- a/src/library/scala/collection/TraversableOnce.scala +++ b/src/library/scala/collection/TraversableOnce.scala @@ -10,6 +10,7 @@ package scala.collection import mutable.{ Buffer, ListBuffer, ArrayBuffer } import annotation.unchecked.{ uncheckedVariance => uV } +import language.{implicitConversions, higherKinds} /** A template trait for collections which can be traversed either once only * or one or more times. @@ -239,7 +240,7 @@ trait TraversableOnce[+A] extends Any with GenTraversableOnce[A] { def toTraversable: Traversable[A] - def toList: List[A] = new ListBuffer[A] ++= seq toList + def toList: List[A] = (new ListBuffer[A] ++= seq).toList def toIterable: Iterable[A] = toStream @@ -358,8 +359,11 @@ trait TraversableOnce[+A] extends Any with GenTraversableOnce[A] { object TraversableOnce { - implicit def traversableOnceCanBuildFrom[T] = new OnceCanBuildFrom[T] - implicit def wrapTraversableOnce[A](trav: TraversableOnce[A]) = new MonadOps(trav) + @deprecated("use OnceCanBuildFrom instead") + def traversableOnceCanBuildFrom[T] = new OnceCanBuildFrom[T] + @deprecated("use MonadOps instead") + def wrapTraversableOnce[A](trav: TraversableOnce[A]) = new MonadOps(trav) + implicit def alternateImplicit[A](trav: TraversableOnce[A]) = new ForceImplicitAmbiguity implicit def flattenTraversableOnce[A, CC[_]](travs: TraversableOnce[CC[A]])(implicit ev: CC[A] => TraversableOnce[A]) = new FlattenOps[A](travs map ev) @@ -368,7 +372,7 @@ object TraversableOnce { * operates on Iterators so they can be treated uniformly along with the collections. * See scala.util.Random.shuffle for an example. */ - class OnceCanBuildFrom[A] extends generic.CanBuildFrom[TraversableOnce[A], A, TraversableOnce[A]] { + implicit class OnceCanBuildFrom[A] extends generic.CanBuildFrom[TraversableOnce[A], A, TraversableOnce[A]] { def newIterator = new ArrayBuffer[A] mapResult (_.iterator) /** Creates a new builder on request of a collection. @@ -394,7 +398,7 @@ object TraversableOnce { class ForceImplicitAmbiguity - class MonadOps[+A](trav: TraversableOnce[A]) { + implicit class MonadOps[+A](trav: TraversableOnce[A]) { def map[B](f: A => B): TraversableOnce[B] = trav.toIterator map f def flatMap[B](f: A => GenTraversableOnce[B]): TraversableOnce[B] = trav.toIterator flatMap f def withFilter(p: A => Boolean) = trav.toIterator filter p diff --git a/src/library/scala/collection/TraversableViewLike.scala b/src/library/scala/collection/TraversableViewLike.scala index fbecad98fe..ad5e3d3240 100644 --- a/src/library/scala/collection/TraversableViewLike.scala +++ b/src/library/scala/collection/TraversableViewLike.scala @@ -12,13 +12,14 @@ import generic._ import mutable.{ Builder, ArrayBuffer } import TraversableView.NoBuilder import annotation.migration +import language.implicitConversions trait ViewMkString[+A] { self: Traversable[A] => // It is necessary to use thisSeq rather than toSeq to avoid cycles in the // eager evaluation of vals in transformed view subclasses, see #4558. - protected[this] def thisSeq: Seq[A] = new ArrayBuffer[A] ++= self result + protected[this] def thisSeq: Seq[A] = (new ArrayBuffer[A] ++= self).result // Have to overload all three to work around #4299. The overload // is because mkString should force a view but toString should not. diff --git a/src/library/scala/collection/convert/DecorateAsJava.scala b/src/library/scala/collection/convert/DecorateAsJava.scala index e05bfc41cd..bde13f2830 100644 --- a/src/library/scala/collection/convert/DecorateAsJava.scala +++ b/src/library/scala/collection/convert/DecorateAsJava.scala @@ -12,6 +12,8 @@ package convert import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc } import Decorators._ import WrapAsJava._ +import language.implicitConversions + /** A collection of decorators that allow to convert between * Scala and Java collections using `asScala` and `asJava` methods. diff --git a/src/library/scala/collection/convert/DecorateAsScala.scala b/src/library/scala/collection/convert/DecorateAsScala.scala index 722f0b9af9..b170d8d139 100644 --- a/src/library/scala/collection/convert/DecorateAsScala.scala +++ b/src/library/scala/collection/convert/DecorateAsScala.scala @@ -12,6 +12,7 @@ package convert import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc } import Decorators._ import WrapAsScala._ +import language.implicitConversions trait DecorateAsScala { /** diff --git a/src/library/scala/collection/convert/WrapAsJava.scala b/src/library/scala/collection/convert/WrapAsJava.scala index cdec72b9fe..ecf91deb3a 100644 --- a/src/library/scala/collection/convert/WrapAsJava.scala +++ b/src/library/scala/collection/convert/WrapAsJava.scala @@ -11,6 +11,7 @@ package convert import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc } import Wrappers._ +import language.implicitConversions trait WrapAsJava { /** diff --git a/src/library/scala/collection/convert/WrapAsScala.scala b/src/library/scala/collection/convert/WrapAsScala.scala index 56e13b2105..14c64695ff 100644 --- a/src/library/scala/collection/convert/WrapAsScala.scala +++ b/src/library/scala/collection/convert/WrapAsScala.scala @@ -11,6 +11,7 @@ package convert import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc } import Wrappers._ +import language.implicitConversions trait WrapAsScala { /** diff --git a/src/library/scala/collection/generic/ClassManifestTraversableFactory.scala b/src/library/scala/collection/generic/ClassManifestTraversableFactory.scala index e54ce9cdbf..e418ca623f 100644 --- a/src/library/scala/collection/generic/ClassManifestTraversableFactory.scala +++ b/src/library/scala/collection/generic/ClassManifestTraversableFactory.scala @@ -9,6 +9,8 @@ package scala.collection package generic +import language.higherKinds + /** A template for companion objects of `ClassManifestTraversable` and * subclasses thereof. * diff --git a/src/library/scala/collection/generic/GenMapFactory.scala b/src/library/scala/collection/generic/GenMapFactory.scala index d6f6978ead..b3faf0497b 100644 --- a/src/library/scala/collection/generic/GenMapFactory.scala +++ b/src/library/scala/collection/generic/GenMapFactory.scala @@ -10,6 +10,7 @@ package scala.collection package generic import mutable.{Builder, MapBuilder} +import language.higherKinds /** A template for companion objects of `Map` and subclasses thereof. * diff --git a/src/library/scala/collection/generic/GenSeqFactory.scala b/src/library/scala/collection/generic/GenSeqFactory.scala index ee6ecae3c2..3bd63c08b8 100644 --- a/src/library/scala/collection/generic/GenSeqFactory.scala +++ b/src/library/scala/collection/generic/GenSeqFactory.scala @@ -12,6 +12,7 @@ package scala.collection package generic import annotation.bridge +import language.higherKinds /** A template for companion objects of Seq and subclasses thereof. * diff --git a/src/library/scala/collection/generic/GenSetFactory.scala b/src/library/scala/collection/generic/GenSetFactory.scala index d83f248aff..caae8afa1c 100644 --- a/src/library/scala/collection/generic/GenSetFactory.scala +++ b/src/library/scala/collection/generic/GenSetFactory.scala @@ -12,6 +12,7 @@ package scala.collection package generic import mutable.Builder +import language.higherKinds /** A template for companion objects of `Set` and subclasses thereof. * diff --git a/src/library/scala/collection/generic/GenTraversableFactory.scala b/src/library/scala/collection/generic/GenTraversableFactory.scala index 34cbe1a7f2..f233a40d35 100644 --- a/src/library/scala/collection/generic/GenTraversableFactory.scala +++ b/src/library/scala/collection/generic/GenTraversableFactory.scala @@ -10,6 +10,8 @@ package scala.collection package generic +import language.higherKinds + /** A template for companion objects of `Traversable` and subclasses thereof. * This class provides a set of operations to create `$Coll` objects. * It is typically inherited by companion objects of subclasses of `Traversable`. @@ -71,7 +73,7 @@ abstract class GenTraversableFactory[CC[X] <: GenTraversable[X] with GenericTrav val b = newBuilder[A] // At present we're using IndexedSeq as a proxy for "has a cheap size method". if (xss forall (_.isInstanceOf[IndexedSeq[_]])) - b.sizeHint(xss map (_.size) sum) + b.sizeHint(xss.map(_.size).sum) for (xs <- xss.seq) b ++= xs b.result diff --git a/src/library/scala/collection/generic/GenericClassManifestCompanion.scala b/src/library/scala/collection/generic/GenericClassManifestCompanion.scala index 546e82fb4a..f357091361 100644 --- a/src/library/scala/collection/generic/GenericClassManifestCompanion.scala +++ b/src/library/scala/collection/generic/GenericClassManifestCompanion.scala @@ -10,6 +10,7 @@ package scala.collection package generic import mutable.Builder +import language.higherKinds /** This class represents companions of classes which require ClassManifests * for their element types. diff --git a/src/library/scala/collection/generic/GenericClassManifestTraversableTemplate.scala b/src/library/scala/collection/generic/GenericClassManifestTraversableTemplate.scala index 12b5a495f0..1a5db4bab2 100644 --- a/src/library/scala/collection/generic/GenericClassManifestTraversableTemplate.scala +++ b/src/library/scala/collection/generic/GenericClassManifestTraversableTemplate.scala @@ -11,6 +11,7 @@ package generic import mutable.Builder import annotation.unchecked.uncheckedVariance +import language.higherKinds /** This trait represents collections classes which require class * manifests for their element types. diff --git a/src/library/scala/collection/generic/GenericCompanion.scala b/src/library/scala/collection/generic/GenericCompanion.scala index b36a1e297f..cf01cf5f08 100644 --- a/src/library/scala/collection/generic/GenericCompanion.scala +++ b/src/library/scala/collection/generic/GenericCompanion.scala @@ -10,6 +10,7 @@ package scala.collection package generic import mutable.Builder +import language.higherKinds /** A template class for companion objects of "regular" collection classes * represent an unconstrained higher-kinded type. Typically diff --git a/src/library/scala/collection/generic/GenericOrderedCompanion.scala b/src/library/scala/collection/generic/GenericOrderedCompanion.scala index c3baa28147..290dc435c8 100644 --- a/src/library/scala/collection/generic/GenericOrderedCompanion.scala +++ b/src/library/scala/collection/generic/GenericOrderedCompanion.scala @@ -10,6 +10,7 @@ package scala.collection package generic import mutable.Builder +import language.higherKinds /** This class represents companions of classes which require the ordered trait * for their element types. diff --git a/src/library/scala/collection/generic/GenericOrderedTraversableTemplate.scala b/src/library/scala/collection/generic/GenericOrderedTraversableTemplate.scala index 5cfc4666b3..6e04420315 100644 --- a/src/library/scala/collection/generic/GenericOrderedTraversableTemplate.scala +++ b/src/library/scala/collection/generic/GenericOrderedTraversableTemplate.scala @@ -13,8 +13,7 @@ package generic import mutable.Builder import annotation.unchecked.uncheckedVariance - - +import language.higherKinds /** This trait represents collections classes which require * ordered element types. diff --git a/src/library/scala/collection/generic/GenericParCompanion.scala b/src/library/scala/collection/generic/GenericParCompanion.scala index 40fcfa31d0..93c166b7ba 100644 --- a/src/library/scala/collection/generic/GenericParCompanion.scala +++ b/src/library/scala/collection/generic/GenericParCompanion.scala @@ -11,6 +11,7 @@ package scala.collection.generic import scala.collection.parallel.Combiner import scala.collection.parallel.ParIterable import scala.collection.parallel.ParMap +import language.higherKinds /** A template class for companion objects of parallel collection classes. * They should be mixed in together with `GenericCompanion` type. diff --git a/src/library/scala/collection/generic/GenericParTemplate.scala b/src/library/scala/collection/generic/GenericParTemplate.scala index 430dcb9e29..fc1c3f5eaa 100644 --- a/src/library/scala/collection/generic/GenericParTemplate.scala +++ b/src/library/scala/collection/generic/GenericParTemplate.scala @@ -14,6 +14,7 @@ import scala.collection.parallel.ParMap import scala.collection.parallel.TaskSupport import annotation.unchecked.uncheckedVariance +import language.higherKinds /** A template trait for collections having a companion. * diff --git a/src/library/scala/collection/generic/GenericSeqCompanion.scala b/src/library/scala/collection/generic/GenericSeqCompanion.scala index 41e8d6dd39..4c0c34733c 100644 --- a/src/library/scala/collection/generic/GenericSeqCompanion.scala +++ b/src/library/scala/collection/generic/GenericSeqCompanion.scala @@ -11,6 +11,7 @@ package scala.collection package generic import annotation.bridge +import language.higherKinds trait GenericSeqCompanion[CC[X] <: Traversable[X]] extends GenericCompanion[CC] { diff --git a/src/library/scala/collection/generic/GenericSetTemplate.scala b/src/library/scala/collection/generic/GenericSetTemplate.scala index 6af6a36981..221bcfb379 100644 --- a/src/library/scala/collection/generic/GenericSetTemplate.scala +++ b/src/library/scala/collection/generic/GenericSetTemplate.scala @@ -8,7 +8,7 @@ package scala.collection package generic - +import language.higherKinds /** * @since 2.8 */ diff --git a/src/library/scala/collection/generic/GenericTraversableTemplate.scala b/src/library/scala/collection/generic/GenericTraversableTemplate.scala index 6586434924..b26e07393c 100644 --- a/src/library/scala/collection/generic/GenericTraversableTemplate.scala +++ b/src/library/scala/collection/generic/GenericTraversableTemplate.scala @@ -14,6 +14,7 @@ package generic import mutable.Builder import annotation.migration import annotation.unchecked.uncheckedVariance +import language.higherKinds /** A template class for companion objects of ``regular`` collection classes * that represent an unconstrained higher-kinded type. diff --git a/src/library/scala/collection/generic/ImmutableMapFactory.scala b/src/library/scala/collection/generic/ImmutableMapFactory.scala index bdb657f320..d893188e92 100644 --- a/src/library/scala/collection/generic/ImmutableMapFactory.scala +++ b/src/library/scala/collection/generic/ImmutableMapFactory.scala @@ -10,6 +10,8 @@ package scala.collection package generic +import language.higherKinds + /** A template for companion objects of `immutable.Map` and subclasses thereof. * @author Martin Odersky * @version 2.8 diff --git a/src/library/scala/collection/generic/ImmutableSetFactory.scala b/src/library/scala/collection/generic/ImmutableSetFactory.scala index e128be70a1..7bd5bf2ef8 100644 --- a/src/library/scala/collection/generic/ImmutableSetFactory.scala +++ b/src/library/scala/collection/generic/ImmutableSetFactory.scala @@ -10,6 +10,7 @@ package scala.collection package generic import mutable.{ Builder, SetBuilder } +import language.higherKinds abstract class ImmutableSetFactory[CC[X] <: immutable.Set[X] with SetLike[X, CC[X]]] extends SetFactory[CC] { diff --git a/src/library/scala/collection/generic/ImmutableSortedMapFactory.scala b/src/library/scala/collection/generic/ImmutableSortedMapFactory.scala index 89e19eed87..93aae0e355 100644 --- a/src/library/scala/collection/generic/ImmutableSortedMapFactory.scala +++ b/src/library/scala/collection/generic/ImmutableSortedMapFactory.scala @@ -11,6 +11,8 @@ package scala.collection package generic +import language.higherKinds + /** A template for companion objects of `SortedMap` and subclasses thereof. * * @since 2.8 diff --git a/src/library/scala/collection/generic/ImmutableSortedSetFactory.scala b/src/library/scala/collection/generic/ImmutableSortedSetFactory.scala index fe807d9fe6..67fb72270c 100644 --- a/src/library/scala/collection/generic/ImmutableSortedSetFactory.scala +++ b/src/library/scala/collection/generic/ImmutableSortedSetFactory.scala @@ -11,6 +11,8 @@ package scala.collection package generic +import language.higherKinds + /** A template for companion objects of `SortedSet` and subclasses thereof. * * @since 2.8 @@ -23,4 +25,4 @@ package generic * @define sortedSetCanBuildFromInfo * The standard `CanBuildFrom` instance for sorted sets */ -abstract class ImmutableSortedSetFactory[CC[A] <: immutable.SortedSet[A] with SortedSetLike[A, CC[A]]] extends SortedSetFactory[CC]
\ No newline at end of file +abstract class ImmutableSortedSetFactory[CC[A] <: immutable.SortedSet[A] with SortedSetLike[A, CC[A]]] extends SortedSetFactory[CC] diff --git a/src/library/scala/collection/generic/MapFactory.scala b/src/library/scala/collection/generic/MapFactory.scala index a60e3032c1..e502c4067e 100644 --- a/src/library/scala/collection/generic/MapFactory.scala +++ b/src/library/scala/collection/generic/MapFactory.scala @@ -12,6 +12,7 @@ package generic import mutable.{Builder, MapBuilder} import annotation.bridge +import language.higherKinds /** A template for companion objects of `Map` and subclasses thereof. * diff --git a/src/library/scala/collection/generic/MutableMapFactory.scala b/src/library/scala/collection/generic/MutableMapFactory.scala index 076e41c9f8..8b38b4ddd5 100644 --- a/src/library/scala/collection/generic/MutableMapFactory.scala +++ b/src/library/scala/collection/generic/MutableMapFactory.scala @@ -12,6 +12,7 @@ package scala.collection package generic import mutable.Builder +import language.higherKinds /** A template for companion objects of `mutable.Map` and subclasses thereof. * @author Martin Odersky diff --git a/src/library/scala/collection/generic/MutableSetFactory.scala b/src/library/scala/collection/generic/MutableSetFactory.scala index 6130ef2042..f130489814 100644 --- a/src/library/scala/collection/generic/MutableSetFactory.scala +++ b/src/library/scala/collection/generic/MutableSetFactory.scala @@ -10,6 +10,7 @@ package scala.collection package generic import mutable.{ Builder, GrowingBuilder } +import language.higherKinds abstract class MutableSetFactory[CC[X] <: mutable.Set[X] with mutable.SetLike[X, CC[X]]] extends SetFactory[CC] { diff --git a/src/library/scala/collection/generic/MutableSortedSetFactory.scala b/src/library/scala/collection/generic/MutableSortedSetFactory.scala index cbbedc0231..b0dd23ee1a 100644 --- a/src/library/scala/collection/generic/MutableSortedSetFactory.scala +++ b/src/library/scala/collection/generic/MutableSortedSetFactory.scala @@ -10,6 +10,7 @@ package scala.collection package generic import scala.collection.mutable.{ Builder, GrowingBuilder } +import language.higherKinds /** * @define Coll mutable.SortedSet diff --git a/src/library/scala/collection/generic/OrderedTraversableFactory.scala b/src/library/scala/collection/generic/OrderedTraversableFactory.scala index 259e4123c4..92f166ae08 100644 --- a/src/library/scala/collection/generic/OrderedTraversableFactory.scala +++ b/src/library/scala/collection/generic/OrderedTraversableFactory.scala @@ -10,9 +10,7 @@ package scala.collection package generic - - - +import language.higherKinds abstract class OrderedTraversableFactory[CC[X] <: Traversable[X] with GenericOrderedTraversableTemplate[X, CC]] extends GenericOrderedCompanion[CC] { diff --git a/src/library/scala/collection/generic/ParFactory.scala b/src/library/scala/collection/generic/ParFactory.scala index 558024d45c..0829ba6616 100644 --- a/src/library/scala/collection/generic/ParFactory.scala +++ b/src/library/scala/collection/generic/ParFactory.scala @@ -10,6 +10,7 @@ package scala.collection.generic import scala.collection.parallel.ParIterable import scala.collection.parallel.Combiner +import language.higherKinds /** A template class for companion objects of `ParIterable` and subclasses * thereof. This class extends `TraversableFactory` and provides a set of diff --git a/src/library/scala/collection/generic/ParMapFactory.scala b/src/library/scala/collection/generic/ParMapFactory.scala index 2d89f79c13..c05ab73431 100644 --- a/src/library/scala/collection/generic/ParMapFactory.scala +++ b/src/library/scala/collection/generic/ParMapFactory.scala @@ -12,6 +12,7 @@ import scala.collection.parallel.ParMap import scala.collection.parallel.ParMapLike import scala.collection.parallel.Combiner import scala.collection.mutable.Builder +import language.higherKinds /** A template class for companion objects of `ParMap` and subclasses thereof. * This class extends `TraversableFactory` and provides a set of operations diff --git a/src/library/scala/collection/generic/ParSetFactory.scala b/src/library/scala/collection/generic/ParSetFactory.scala index c2cf971d73..30a36a734a 100644 --- a/src/library/scala/collection/generic/ParSetFactory.scala +++ b/src/library/scala/collection/generic/ParSetFactory.scala @@ -12,6 +12,7 @@ import collection.mutable.Builder import collection.parallel.Combiner import collection.parallel.ParSet import collection.parallel.ParSetLike +import language.higherKinds /** * @author Aleksandar Prokopec diff --git a/src/library/scala/collection/generic/SeqFactory.scala b/src/library/scala/collection/generic/SeqFactory.scala index 7bd92173ff..3f61de6ceb 100644 --- a/src/library/scala/collection/generic/SeqFactory.scala +++ b/src/library/scala/collection/generic/SeqFactory.scala @@ -10,6 +10,7 @@ package scala.collection package generic +import language.higherKinds /** A template for companion objects of Seq and subclasses thereof. * diff --git a/src/library/scala/collection/generic/SetFactory.scala b/src/library/scala/collection/generic/SetFactory.scala index 348743a120..fb99f83ebb 100644 --- a/src/library/scala/collection/generic/SetFactory.scala +++ b/src/library/scala/collection/generic/SetFactory.scala @@ -13,6 +13,7 @@ package generic import mutable.Builder import annotation.bridge +import language.higherKinds abstract class SetFactory[CC[X] <: Set[X] with SetLike[X, CC[X]]] extends GenSetFactory[CC] with GenericSeqCompanion[CC] { diff --git a/src/library/scala/collection/generic/SortedMapFactory.scala b/src/library/scala/collection/generic/SortedMapFactory.scala index 962a945037..f038c8b09b 100644 --- a/src/library/scala/collection/generic/SortedMapFactory.scala +++ b/src/library/scala/collection/generic/SortedMapFactory.scala @@ -12,6 +12,7 @@ package scala.collection package generic import mutable.{Builder, MapBuilder} +import language.higherKinds /** A template for companion objects of mutable.Map and subclasses thereof. * diff --git a/src/library/scala/collection/generic/SortedSetFactory.scala b/src/library/scala/collection/generic/SortedSetFactory.scala index 45340cf6c1..bb261803a9 100644 --- a/src/library/scala/collection/generic/SortedSetFactory.scala +++ b/src/library/scala/collection/generic/SortedSetFactory.scala @@ -12,6 +12,7 @@ package scala.collection package generic import mutable.{Builder, SetBuilder} +import language.higherKinds /** A template for companion objects of Set and subclasses thereof. * diff --git a/src/library/scala/collection/generic/TraversableFactory.scala b/src/library/scala/collection/generic/TraversableFactory.scala index e71de1252c..07da1bb5c2 100644 --- a/src/library/scala/collection/generic/TraversableFactory.scala +++ b/src/library/scala/collection/generic/TraversableFactory.scala @@ -11,6 +11,7 @@ package scala.collection package generic import annotation.bridge +import language.higherKinds /** A template for companion objects of `Traversable` and subclasses thereof. * This class provides a set of operations to create `$Coll` objects. diff --git a/src/library/scala/collection/immutable/ListSet.scala b/src/library/scala/collection/immutable/ListSet.scala index 47e3245117..b71071d3c0 100644 --- a/src/library/scala/collection/immutable/ListSet.scala +++ b/src/library/scala/collection/immutable/ListSet.scala @@ -33,7 +33,7 @@ object ListSet extends ImmutableSetFactory[ListSet] { */ class ListSetBuilder[Elem](initial: ListSet[Elem]) extends Builder[Elem, ListSet[Elem]] { def this() = this(empty[Elem]) - protected val elems = new mutable.ListBuffer[Elem] ++= initial reverse + protected val elems = (new mutable.ListBuffer[Elem] ++= initial).reverse protected val seen = new mutable.HashSet[Elem] ++= initial def +=(x: Elem): this.type = { @@ -100,7 +100,7 @@ class ListSet[A] extends AbstractSet[A] */ override def ++(xs: GenTraversableOnce[A]): ListSet[A] = if (xs.isEmpty) this - else new ListSet.ListSetBuilder(this) ++= xs.seq result + else (new ListSet.ListSetBuilder(this) ++= xs.seq).result @bridge def ++(xs: TraversableOnce[A]): ListSet[A] = ++(xs: GenTraversableOnce[A]): ListSet[A] diff --git a/src/library/scala/collection/immutable/Stream.scala b/src/library/scala/collection/immutable/Stream.scala index 2eb2f8eb09..2df4ed70c7 100644 --- a/src/library/scala/collection/immutable/Stream.scala +++ b/src/library/scala/collection/immutable/Stream.scala @@ -13,6 +13,7 @@ import generic._ import mutable.{Builder, StringBuilder, LazyBuilder, ListBuffer} import scala.annotation.tailrec import Stream.cons +import language.implicitConversions /** The class `Stream` implements lazy lists where elements * are only evaluated when they are needed. Here is an example: @@ -821,7 +822,7 @@ self => */ override def distinct: Stream[A] = if (isEmpty) this - else cons(head, tail.filter(head !=).distinct) + else cons(head, tail.filter(head != _).distinct) /** Returns a new sequence of given length containing the elements of this * sequence followed by zero or more occurrences of given elements. diff --git a/src/library/scala/collection/immutable/StringLike.scala b/src/library/scala/collection/immutable/StringLike.scala index fc4e7bf0a8..06f09f359f 100644 --- a/src/library/scala/collection/immutable/StringLike.scala +++ b/src/library/scala/collection/immutable/StringLike.scala @@ -60,7 +60,7 @@ self => val end = until min length if (start >= end) newBuilder.result - else newBuilder ++= toString.substring(start, end) result + else (newBuilder ++= toString.substring(start, end)).result } /** Return the current string concatenated `n` times. diff --git a/src/library/scala/collection/immutable/TrieIterator.scala b/src/library/scala/collection/immutable/TrieIterator.scala index c77334b732..ead1a8c744 100644 --- a/src/library/scala/collection/immutable/TrieIterator.scala +++ b/src/library/scala/collection/immutable/TrieIterator.scala @@ -75,7 +75,7 @@ private[collection] abstract class TrieIterator[+T](elems: Array[Iterable[T]]) e } private[this] def iteratorWithSize(arr: Array[Iterable[T]]): (Iterator[T], Int) = - (newIterator(arr), arr map (_.size) sum) + (newIterator(arr), arr.map(_.size).sum) private[this] def arrayToIterators(arr: Array[Iterable[T]]): SplitIterators = { val (fst, snd) = arr.splitAt(arr.length / 2) diff --git a/src/library/scala/collection/mutable/ArrayBuilder.scala b/src/library/scala/collection/mutable/ArrayBuilder.scala index f0e4c79abf..e396b0695e 100644 --- a/src/library/scala/collection/mutable/ArrayBuilder.scala +++ b/src/library/scala/collection/mutable/ArrayBuilder.scala @@ -33,8 +33,22 @@ object ArrayBuilder { * @tparam T type of the elements for the array builder, with a `ClassManifest` context bound. * @return a new empty array builder. */ - def make[T: ClassManifest](): ArrayBuilder[T] = - implicitly[ClassManifest[T]].newArrayBuilder() + def make[T: ClassManifest](): ArrayBuilder[T] = { + val manifest = implicitly[ClassManifest[T]] + val erasure = manifest.erasure + erasure match { + case java.lang.Byte.TYPE => new ArrayBuilder.ofByte().asInstanceOf[ArrayBuilder[T]] + case java.lang.Short.TYPE => new ArrayBuilder.ofShort().asInstanceOf[ArrayBuilder[T]] + case java.lang.Character.TYPE => new ArrayBuilder.ofChar().asInstanceOf[ArrayBuilder[T]] + case java.lang.Integer.TYPE => new ArrayBuilder.ofInt().asInstanceOf[ArrayBuilder[T]] + case java.lang.Long.TYPE => new ArrayBuilder.ofLong().asInstanceOf[ArrayBuilder[T]] + case java.lang.Float.TYPE => new ArrayBuilder.ofFloat().asInstanceOf[ArrayBuilder[T]] + case java.lang.Double.TYPE => new ArrayBuilder.ofDouble().asInstanceOf[ArrayBuilder[T]] + case java.lang.Boolean.TYPE => new ArrayBuilder.ofBoolean().asInstanceOf[ArrayBuilder[T]] + case java.lang.Void.TYPE => new ArrayBuilder.ofUnit().asInstanceOf[ArrayBuilder[T]] + case _ => new ArrayBuilder.ofRef[T with AnyRef]()(manifest.asInstanceOf[ClassManifest[T with AnyRef]]).asInstanceOf[ArrayBuilder[T]] + } + } /** A class for array builders for arrays of reference types. * diff --git a/src/library/scala/collection/mutable/ArrayOps.scala b/src/library/scala/collection/mutable/ArrayOps.scala index 5f7c508181..875030ade0 100644 --- a/src/library/scala/collection/mutable/ArrayOps.scala +++ b/src/library/scala/collection/mutable/ArrayOps.scala @@ -39,8 +39,8 @@ abstract class ArrayOps[T] extends ArrayLike[T, Array[T]] with CustomParalleliza private def rowBuilder[U]: Builder[U, Array[U]] = Array.newBuilder( - ClassManifest.fromClass( - repr.getClass.getComponentType.getComponentType.asInstanceOf[Predef.Class[U]])) + ClassManifest[U]( + repr.getClass.getComponentType.getComponentType)) override def copyToArray[U >: T](xs: Array[U], start: Int, len: Int) { var l = math.min(len, repr.length) @@ -65,7 +65,7 @@ abstract class ArrayOps[T] extends ArrayLike[T, Array[T]] with CustomParalleliza */ def flatten[U, To](implicit asTrav: T => collection.Traversable[U], m: ClassManifest[U]): Array[U] = { val b = Array.newBuilder[U] - b.sizeHint(map{case is: collection.IndexedSeq[_] => is.size case _ => 0} sum) + b.sizeHint(map{case is: collection.IndexedSeq[_] => is.size case _ => 0}.sum) for (xs <- this) b ++= asTrav(xs) b.result @@ -87,8 +87,8 @@ abstract class ArrayOps[T] extends ArrayLike[T, Array[T]] with CustomParalleliza } } val bb: Builder[Array[U], Array[Array[U]]] = Array.newBuilder( - ClassManifest.fromClass( - repr.getClass.getComponentType.asInstanceOf[Predef.Class[Array[U]]])) + ClassManifest[Array[U]]( + repr.getClass.getComponentType)) for (b <- bs) bb += b.result bb.result } @@ -110,7 +110,7 @@ object ArrayOps { override protected[this] def thisCollection: WrappedArray[T] = new WrappedArray.ofRef[T](repr) override protected[this] def toCollection(repr: Array[T]): WrappedArray[T] = new WrappedArray.ofRef[T](repr) override protected[this] def newBuilder = new ArrayBuilder.ofRef[T]()( - ClassManifest.classType[T](repr.getClass.getComponentType)) + ClassManifest[T](repr.getClass.getComponentType)) def length: Int = repr.length def apply(index: Int): T = repr(index) diff --git a/src/library/scala/collection/mutable/IndexedSeqView.scala b/src/library/scala/collection/mutable/IndexedSeqView.scala index 593af92255..a0de2ec8ad 100644 --- a/src/library/scala/collection/mutable/IndexedSeqView.scala +++ b/src/library/scala/collection/mutable/IndexedSeqView.scala @@ -14,6 +14,7 @@ package mutable import generic._ import TraversableView.NoBuilder +import language.implicitConversions /** A non-strict view of a mutable `IndexedSeq`. * $viewInfo diff --git a/src/library/scala/collection/mutable/LinkedHashSet.scala b/src/library/scala/collection/mutable/LinkedHashSet.scala index f6d4915fef..d2815cf9de 100644 --- a/src/library/scala/collection/mutable/LinkedHashSet.scala +++ b/src/library/scala/collection/mutable/LinkedHashSet.scala @@ -82,7 +82,7 @@ class LinkedHashSet[A] extends AbstractSet[A] private def readObject(in: java.io.ObjectInputStream) { ordered = new ListBuffer[A] - init(in, ordered += ) + init(in, ordered += _) } } diff --git a/src/library/scala/collection/mutable/StringBuilder.scala b/src/library/scala/collection/mutable/StringBuilder.scala index d9ad58f054..08c881dbb8 100644 --- a/src/library/scala/collection/mutable/StringBuilder.scala +++ b/src/library/scala/collection/mutable/StringBuilder.scala @@ -404,7 +404,7 @@ final class StringBuilder(private val underlying: JavaStringBuilder) * @return the reversed StringBuilder */ @migration("`reverse` returns a new instance. Use `reverseContents` to update in place and return that StringBuilder itself.", "2.8.0") - override def reverse: StringBuilder = new StringBuilder(new JavaStringBuilder(underlying) reverse) + override def reverse: StringBuilder = new StringBuilder(new JavaStringBuilder(underlying).reverse) override def clone(): StringBuilder = new StringBuilder(new JavaStringBuilder(underlying)) diff --git a/src/library/scala/collection/mutable/WrappedArray.scala b/src/library/scala/collection/mutable/WrappedArray.scala index 4287bac249..fac4eb77bb 100644 --- a/src/library/scala/collection/mutable/WrappedArray.scala +++ b/src/library/scala/collection/mutable/WrappedArray.scala @@ -112,7 +112,7 @@ object WrappedArray { def newBuilder[A]: Builder[A, IndexedSeq[A]] = new ArrayBuffer final class ofRef[T <: AnyRef](val array: Array[T]) extends WrappedArray[T] with Serializable { - lazy val elemManifest = ClassManifest.classType[T](array.getClass.getComponentType) + lazy val elemManifest = ClassManifest[T](array.getClass.getComponentType) def length: Int = array.length def apply(index: Int): T = array(index).asInstanceOf[T] def update(index: Int, elem: T) { array(index) = elem } diff --git a/src/library/scala/collection/mutable/WrappedArrayBuilder.scala b/src/library/scala/collection/mutable/WrappedArrayBuilder.scala index 9771a45a28..fce65468e9 100644 --- a/src/library/scala/collection/mutable/WrappedArrayBuilder.scala +++ b/src/library/scala/collection/mutable/WrappedArrayBuilder.scala @@ -28,7 +28,19 @@ class WrappedArrayBuilder[A](manifest: ClassManifest[A]) extends Builder[A, Wrap private var size: Int = 0 private def mkArray(size: Int): WrappedArray[A] = { - val newelems = manifest.newWrappedArray(size) + val erasure = manifest.erasure + val newelems = erasure match { + case java.lang.Byte.TYPE => new WrappedArray.ofByte(new Array[Byte](size)).asInstanceOf[WrappedArray[A]] + case java.lang.Short.TYPE => new WrappedArray.ofShort(new Array[Short](size)).asInstanceOf[WrappedArray[A]] + case java.lang.Character.TYPE => new WrappedArray.ofChar(new Array[Char](size)).asInstanceOf[WrappedArray[A]] + case java.lang.Integer.TYPE => new WrappedArray.ofInt(new Array[Int](size)).asInstanceOf[WrappedArray[A]] + case java.lang.Long.TYPE => new WrappedArray.ofLong(new Array[Long](size)).asInstanceOf[WrappedArray[A]] + case java.lang.Float.TYPE => new WrappedArray.ofFloat(new Array[Float](size)).asInstanceOf[WrappedArray[A]] + case java.lang.Double.TYPE => new WrappedArray.ofDouble(new Array[Double](size)).asInstanceOf[WrappedArray[A]] + case java.lang.Boolean.TYPE => new WrappedArray.ofBoolean(new Array[Boolean](size)).asInstanceOf[WrappedArray[A]] + case java.lang.Void.TYPE => new WrappedArray.ofUnit(new Array[Unit](size)).asInstanceOf[WrappedArray[A]] + case _ => new WrappedArray.ofRef[A with AnyRef](manifest.newArray(size).asInstanceOf[Array[A with AnyRef]]).asInstanceOf[WrappedArray[A]] + } if (this.size > 0) Array.copy(elems.array, 0, newelems.array, 0, this.size) newelems } diff --git a/src/library/scala/collection/parallel/ParIterableLike.scala b/src/library/scala/collection/parallel/ParIterableLike.scala index 5551c04ce2..5bf338f560 100644 --- a/src/library/scala/collection/parallel/ParIterableLike.scala +++ b/src/library/scala/collection/parallel/ParIterableLike.scala @@ -29,6 +29,7 @@ import java.util.concurrent.atomic.AtomicBoolean import annotation.unchecked.uncheckedVariance import annotation.unchecked.uncheckedStable +import language.implicitConversions /** A template trait for parallel collections of type `ParIterable[T]`. diff --git a/src/library/scala/collection/parallel/ParIterableViewLike.scala b/src/library/scala/collection/parallel/ParIterableViewLike.scala index 536139c812..91eefc2aa5 100644 --- a/src/library/scala/collection/parallel/ParIterableViewLike.scala +++ b/src/library/scala/collection/parallel/ParIterableViewLike.scala @@ -18,6 +18,7 @@ import scala.collection.GenSeq import scala.collection.generic.{ CanBuildFrom, SliceInterval } import scala.collection.generic.CanCombineFrom import scala.collection.parallel.immutable.ParRange +import language.implicitConversions diff --git a/src/library/scala/collection/parallel/package.scala b/src/library/scala/collection/parallel/package.scala index 943e0208c7..e3124af12e 100644 --- a/src/library/scala/collection/parallel/package.scala +++ b/src/library/scala/collection/parallel/package.scala @@ -13,6 +13,7 @@ import scala.collection.generic.CanCombineFrom import scala.collection.parallel.mutable.ParArray import scala.collection.mutable.UnrolledBuffer import annotation.unchecked.uncheckedVariance +import language.implicitConversions /** Package object for parallel collections. */ diff --git a/src/library/scala/concurrent/Awaitable.scala b/src/library/scala/concurrent/Awaitable.scala index 052e6e2366..99bdfbc5a9 100644 --- a/src/library/scala/concurrent/Awaitable.scala +++ b/src/library/scala/concurrent/Awaitable.scala @@ -10,18 +10,23 @@ package scala.concurrent -import scala.annotation.implicitNotFound import scala.concurrent.util.Duration trait Awaitable[+T] { + /** + * Should throw [[scala.concurrent.TimeoutException]] if it times out + * This method should not be called directly. + */ + @throws(classOf[TimeoutException]) def ready(atMost: Duration)(implicit permit: CanAwait): this.type /** - * Throws exceptions if cannot produce a T within the specified time + * Throws exceptions if it cannot produce a T within the specified time. * This method should not be called directly. */ + @throws(classOf[Exception]) def result(atMost: Duration)(implicit permit: CanAwait): T } diff --git a/src/library/scala/concurrent/ConcurrentPackageObject.scala b/src/library/scala/concurrent/ConcurrentPackageObject.scala index d185ade8a4..fafd7fd238 100644 --- a/src/library/scala/concurrent/ConcurrentPackageObject.scala +++ b/src/library/scala/concurrent/ConcurrentPackageObject.scala @@ -12,7 +12,7 @@ import java.util.concurrent.{ Executors, ExecutorService, ThreadFactory } import scala.concurrent.forkjoin.{ ForkJoinPool, ForkJoinWorkerThread } import scala.concurrent.util.Duration import ConcurrentPackageObject._ - +import language.implicitConversions /** This package object contains primitives for concurrent and parallel programming. @@ -36,34 +36,42 @@ abstract class ConcurrentPackageObject { case _ => true } - private[concurrent] def resolve[T](source: Either[Throwable, T]): Either[Throwable, T] = source match { - case Left(t: scala.runtime.NonLocalReturnControl[_]) => Right(t.value.asInstanceOf[T]) - case Left(t: scala.util.control.ControlThrowable) => Left(new ExecutionException("Boxed ControlThrowable", t)) - case Left(t: InterruptedException) => Left(new ExecutionException("Boxed InterruptedException", t)) - case Left(e: Error) => Left(new ExecutionException("Boxed Error", e)) - case _ => source + private[concurrent] def resolveEither[T](source: Either[Throwable, T]): Either[Throwable, T] = source match { + case Left(t) => resolver(t) + case _ => source } - private[concurrent] def resolver[T] = - resolverFunction.asInstanceOf[PartialFunction[Throwable, Either[Throwable, T]]] - + private[concurrent] def resolver[T](throwable: Throwable): Either[Throwable, T] = throwable match { + case t: scala.runtime.NonLocalReturnControl[_] => Right(t.value.asInstanceOf[T]) + case t: scala.util.control.ControlThrowable => Left(new ExecutionException("Boxed ControlThrowable", t)) + case t: InterruptedException => Left(new ExecutionException("Boxed InterruptedException", t)) + case e: Error => Left(new ExecutionException("Boxed Error", e)) + case t => Left(t) + } + /* concurrency constructs */ + /** Starts an asynchronous computation and returns a `Future` object with the result of that computation. + * + * The result becomes available once the asynchronous computation is completed. + * + * @tparam T the type of the result + * @param body the asychronous computation + * @param execctx the execution context on which the future is run + * @return the `Future` holding the result of the computation + */ def future[T](body: =>T)(implicit execctx: ExecutionContext = defaultExecutionContext): Future[T] = Future[T](body) + /** Creates a promise object which can be completed with a value. + * + * @tparam T the type of the value in the promise + * @param execctx the execution context on which the promise is created on + * @return the newly created `Promise` object + */ def promise[T]()(implicit execctx: ExecutionContext = defaultExecutionContext): Promise[T] = Promise[T]() - /** Wraps a block of code into an awaitable object. */ - def body2awaitable[T](body: =>T) = new Awaitable[T] { - def ready(atMost: Duration)(implicit permit: CanAwait) = { - body - this - } - def result(atMost: Duration)(implicit permit: CanAwait) = body - } - /** Used to block on a piece of code which potentially blocks. * * @param body A piece of code which contains potentially blocking or long running calls. @@ -74,7 +82,7 @@ abstract class ConcurrentPackageObject { * - TimeoutException - in the case that the blockable object timed out */ def blocking[T](body: =>T): T = - blocking(body2awaitable(body), Duration.fromNanos(0)) + blocking(impl.Future.body2awaitable(body), Duration.fromNanos(0)) /** Blocks on an awaitable object. * @@ -100,11 +108,11 @@ private[concurrent] object ConcurrentPackageObject { // compiling a subset of sources; it seems that the wildcard is not // properly handled, and you get messages like "type _$1 defined twice". // This is consistent with other package object breakdowns. - private val resolverFunction: PartialFunction[Throwable, Either[Throwable, _]] = { - case t: scala.runtime.NonLocalReturnControl[_] => Right(t.value) - case t: scala.util.control.ControlThrowable => Left(new ExecutionException("Boxed ControlThrowable", t)) - case t: InterruptedException => Left(new ExecutionException("Boxed InterruptedException", t)) - case e: Error => Left(new ExecutionException("Boxed Error", e)) - case t => Left(t) - } + // private val resolverFunction: PartialFunction[Throwable, Either[Throwable, _]] = { + // case t: scala.runtime.NonLocalReturnControl[_] => Right(t.value) + // case t: scala.util.control.ControlThrowable => Left(new ExecutionException("Boxed ControlThrowable", t)) + // case t: InterruptedException => Left(new ExecutionException("Boxed InterruptedException", t)) + // case e: Error => Left(new ExecutionException("Boxed Error", e)) + // case t => Left(t) + // } } diff --git a/src/library/scala/concurrent/ExecutionContext.scala b/src/library/scala/concurrent/ExecutionContext.scala index e1d4276396..3f62f58bf8 100644 --- a/src/library/scala/concurrent/ExecutionContext.scala +++ b/src/library/scala/concurrent/ExecutionContext.scala @@ -20,19 +20,22 @@ import collection._ trait ExecutionContext { - + + /** Runs a block of code on this execution context. + */ def execute(runnable: Runnable): Unit - - def execute[U](body: () => U): Unit - + + /** Used internally by the framework - blocks execution for at most `atMost` time while waiting + * for an `awaitable` object to become ready. + * + * Clients should use `scala.concurrent.blocking` instead. + */ def internalBlockingCall[T](awaitable: Awaitable[T], atMost: Duration): T + /** Reports that an asynchronous computation failed. + */ def reportFailure(t: Throwable): Unit - - /* implementations follow */ - - private implicit val executionContext = this - + } diff --git a/src/library/scala/concurrent/Future.scala b/src/library/scala/concurrent/Future.scala index 5f703ac23b..0d76c23c25 100644 --- a/src/library/scala/concurrent/Future.scala +++ b/src/library/scala/concurrent/Future.scala @@ -24,6 +24,7 @@ import scala.annotation.tailrec import scala.collection.mutable.Stack import scala.collection.mutable.Builder import scala.collection.generic.CanBuildFrom +import language.higherKinds @@ -82,7 +83,6 @@ import scala.collection.generic.CanBuildFrom * }}} */ trait Future[+T] extends Awaitable[T] { -self => /* Callbacks */ @@ -132,7 +132,7 @@ self => /** Creates a new promise. */ - def newPromise[S]: Promise[S] + protected def newPromise[S]: Promise[S] /** Returns whether the future has already been completed with * a value or an exception. @@ -168,14 +168,11 @@ self => * and throws a corresponding exception if the original future fails. */ def failed: Future[Throwable] = { - def noSuchElem(v: T) = - new NoSuchElementException("Future.failed not completed with a throwable. Instead completed with: " + v) - val p = newPromise[Throwable] onComplete { case Left(t) => p success t - case Right(v) => p failure noSuchElem(v) + case Right(v) => p failure (new NoSuchElementException("Future.failed not completed with a throwable. Instead completed with: " + v)) } p.future @@ -411,21 +408,16 @@ self => * {{{ * val f = future { sys.error("failed") } * val g = future { 5 } - * val h = f orElse g + * val h = f fallbackTo g * await(h, 0) // evaluates to 5 * }}} */ def fallbackTo[U >: T](that: Future[U]): Future[U] = { val p = newPromise[U] - onComplete { - case Left(t) => that onComplete { - case Left(_) => p failure t - case Right(v) => p success v - } - case Right(v) => p success v + case r @ Right(_) ⇒ p complete r + case _ ⇒ p completeWith that } - p.future } @@ -497,14 +489,14 @@ self => * }}} */ def either[U >: T](that: Future[U]): Future[U] = { - val p = self.newPromise[U] + val p = newPromise[U] val completePromise: PartialFunction[Either[Throwable, U], _] = { case Left(t) => p tryFailure t case Right(v) => p trySuccess v } - self onComplete completePromise + this onComplete completePromise that onComplete completePromise p.future @@ -521,6 +513,15 @@ self => */ object Future { + /** Starts an asynchronous computation and returns a `Future` object with the result of that computation. + * + * The result becomes available once the asynchronous computation is completed. + * + * @tparam T the type of the result + * @param body the asychronous computation + * @param execctx the execution context on which the future is run + * @return the `Future` holding the result of the computation + */ def apply[T](body: =>T)(implicit executor: ExecutionContext): Future[T] = impl.Future(body) import scala.collection.mutable.Builder diff --git a/src/library/scala/concurrent/FutureTaskRunner.scala b/src/library/scala/concurrent/FutureTaskRunner.scala index 75e6299ad9..9d6f8a7a88 100644 --- a/src/library/scala/concurrent/FutureTaskRunner.scala +++ b/src/library/scala/concurrent/FutureTaskRunner.scala @@ -8,6 +8,8 @@ package scala.concurrent +import language.{implicitConversions, higherKinds} + /** The `FutureTaskRunner</code> trait is a base trait of task runners * that provide some sort of future abstraction. * diff --git a/src/library/scala/concurrent/JavaConversions.scala b/src/library/scala/concurrent/JavaConversions.scala index 127a0e0055..9b5e741549 100644 --- a/src/library/scala/concurrent/JavaConversions.scala +++ b/src/library/scala/concurrent/JavaConversions.scala @@ -9,6 +9,7 @@ package scala.concurrent import java.util.concurrent.{ExecutorService, Executor} +import language.implicitConversions /** The `JavaConversions` object provides implicit converstions supporting * interoperability between Scala and Java concurrency classes. diff --git a/src/library/scala/concurrent/Promise.scala b/src/library/scala/concurrent/Promise.scala index 8f2bce5d1a..cd22a55ce7 100644 --- a/src/library/scala/concurrent/Promise.scala +++ b/src/library/scala/concurrent/Promise.scala @@ -107,15 +107,27 @@ trait Promise[T] { object Promise { - /** Creates a new promise. + /** Creates a promise object which can be completed with a value. + * + * @tparam T the type of the value in the promise + * @param execctx the execution context on which the promise is created on + * @return the newly created `Promise` object */ def apply[T]()(implicit executor: ExecutionContext): Promise[T] = new impl.Promise.DefaultPromise[T]() - /** Creates an already completed Promise with the specified exception + /** Creates an already completed Promise with the specified exception. + * + * @tparam T the type of the value in the promise + * @param execctx the execution context on which the promise is created on + * @return the newly created `Promise` object */ def failed[T](exception: Throwable)(implicit executor: ExecutionContext): Promise[T] = new impl.Promise.KeptPromise[T](Left(exception)) - /** Creates an already completed Promise with the specified result + /** Creates an already completed Promise with the specified result. + * + * @tparam T the type of the value in the promise + * @param execctx the execution context on which the promise is created on + * @return the newly created `Promise` object */ def successful[T](result: T)(implicit executor: ExecutionContext): Promise[T] = new impl.Promise.KeptPromise[T](Right(result)) diff --git a/src/library/scala/concurrent/TaskRunner.scala b/src/library/scala/concurrent/TaskRunner.scala index 500d79e07f..3180e9ce8a 100644 --- a/src/library/scala/concurrent/TaskRunner.scala +++ b/src/library/scala/concurrent/TaskRunner.scala @@ -8,6 +8,8 @@ package scala.concurrent +import language.{higherKinds, implicitConversions} + /** The `TaskRunner` trait... * * @author Philipp Haller diff --git a/src/library/scala/concurrent/ThreadPoolRunner.scala b/src/library/scala/concurrent/ThreadPoolRunner.scala index a3e0253634..fd6882348a 100644 --- a/src/library/scala/concurrent/ThreadPoolRunner.scala +++ b/src/library/scala/concurrent/ThreadPoolRunner.scala @@ -9,6 +9,7 @@ package scala.concurrent import java.util.concurrent.{ExecutorService, Callable, TimeUnit} +import language.implicitConversions /** The `ThreadPoolRunner` trait uses a `java.util.concurrent.ExecutorService` * to run submitted tasks. diff --git a/src/library/scala/concurrent/ThreadRunner.scala b/src/library/scala/concurrent/ThreadRunner.scala index 28fcf57df8..76be94aa6b 100644 --- a/src/library/scala/concurrent/ThreadRunner.scala +++ b/src/library/scala/concurrent/ThreadRunner.scala @@ -9,6 +9,7 @@ package scala.concurrent import java.lang.Thread +import language.implicitConversions /** The `ThreadRunner` trait... * diff --git a/src/library/scala/concurrent/impl/ExecutionContextImpl.scala b/src/library/scala/concurrent/impl/ExecutionContextImpl.scala index 52c834359d..c308a59297 100644 --- a/src/library/scala/concurrent/impl/ExecutionContextImpl.scala +++ b/src/library/scala/concurrent/impl/ExecutionContextImpl.scala @@ -12,7 +12,7 @@ package scala.concurrent.impl import java.util.concurrent.{Callable, Executor, ExecutorService, Executors, ThreadFactory} import scala.concurrent.forkjoin._ -import scala.concurrent.{ExecutionContext, resolver, Awaitable, body2awaitable} +import scala.concurrent.{ExecutionContext, resolver, Awaitable} import scala.concurrent.util.{ Duration } @@ -56,24 +56,40 @@ private[scala] class ExecutionContextImpl(es: AnyRef) extends ExecutionContext w def execute(runnable: Runnable): Unit = executorService match { case fj: ForkJoinPool => - if (Thread.currentThread.isInstanceOf[ForkJoinWorkerThread]) { - val fjtask = ForkJoinTask.adapt(runnable) - fjtask.fork - } else { - fj.execute(runnable) + Thread.currentThread match { + case fjw: ForkJoinWorkerThread if fjw.getPool eq fj => + val fjtask = runnable match { + case fjt: ForkJoinTask[_] => fjt + case _ => ForkJoinTask.adapt(runnable) + } + fjtask.fork + case _ => + fj.execute(runnable) } case executor: Executor => executor execute runnable } - def execute[U](body: () => U): Unit = execute(new Runnable { - def run() = body() - }) - def internalBlockingCall[T](awaitable: Awaitable[T], atMost: Duration): T = { Future.releaseStack(this) - awaitable.result(atMost)(scala.concurrent.Await.canAwaitEvidence) + executorService match { + case fj: ForkJoinPool => + var result: T = null.asInstanceOf[T] + val managedBlocker = new ForkJoinPool.ManagedBlocker { + @volatile var isdone = false + def block() = { + result = awaitable.result(atMost)(scala.concurrent.Await.canAwaitEvidence) + isdone = true + true + } + def isReleasable = isdone + } + ForkJoinPool.managedBlock(managedBlocker) + result + case _ => + awaitable.result(atMost)(scala.concurrent.Await.canAwaitEvidence) + } } def reportFailure(t: Throwable) = t match { @@ -84,7 +100,7 @@ private[scala] class ExecutionContextImpl(es: AnyRef) extends ExecutionContext w } -object ExecutionContextImpl { +private[concurrent] object ExecutionContextImpl { private[concurrent] def currentExecutionContext: ThreadLocal[ExecutionContext] = new ThreadLocal[ExecutionContext] { override protected def initialValue = null diff --git a/src/library/scala/concurrent/impl/Future.scala b/src/library/scala/concurrent/impl/Future.scala index 615ab061a5..a3c8ed3095 100644 --- a/src/library/scala/concurrent/impl/Future.scala +++ b/src/library/scala/concurrent/impl/Future.scala @@ -10,9 +10,11 @@ package scala.concurrent.impl -import scala.concurrent.{Awaitable, ExecutionContext} +import scala.concurrent.util.Duration +import scala.concurrent.{Awaitable, ExecutionContext, CanAwait} import scala.collection.mutable.Stack + private[concurrent] trait Future[+T] extends scala.concurrent.Future[T] with Awaitable[T] { implicit def executor: ExecutionContext @@ -54,6 +56,15 @@ object Future { classOf[Unit] -> classOf[scala.runtime.BoxedUnit] ) + /** Wraps a block of code into an awaitable object. */ + private[concurrent] def body2awaitable[T](body: =>T) = new Awaitable[T] { + def ready(atMost: Duration)(implicit permit: CanAwait) = { + body + this + } + def result(atMost: Duration)(implicit permit: CanAwait) = body + } + def boxedType(c: Class[_]): Class[_] = { if (c.isPrimitive) toBoxed(c) else c } diff --git a/src/library/scala/concurrent/impl/Promise.scala b/src/library/scala/concurrent/impl/Promise.scala index f7e073cb78..07b6d1f278 100644 --- a/src/library/scala/concurrent/impl/Promise.scala +++ b/src/library/scala/concurrent/impl/Promise.scala @@ -12,7 +12,7 @@ package scala.concurrent.impl import java.util.concurrent.TimeUnit.{ NANOSECONDS, MILLISECONDS } import java.util.concurrent.atomic.AtomicReferenceFieldUpdater -import scala.concurrent.{Awaitable, ExecutionContext, resolve, resolver, blocking, CanAwait, TimeoutException} +import scala.concurrent.{Awaitable, ExecutionContext, resolveEither, resolver, blocking, CanAwait, TimeoutException} //import scala.util.continuations._ import scala.concurrent.util.Duration import scala.util @@ -126,7 +126,7 @@ object Promise { value.isDefined } - blocking(concurrent.body2awaitable(awaitUnsafe(dur2long(atMost))), atMost) + blocking(Future.body2awaitable(awaitUnsafe(dur2long(atMost))), atMost) } def ready(atMost: Duration)(implicit permit: CanAwait): this.type = @@ -166,7 +166,7 @@ object Promise { case _ => null } } - tryComplete(resolve(value)) + tryComplete(resolveEither(value)) } finally { synchronized { notifyAll() } // notify any blockers from `tryAwait` } @@ -220,7 +220,7 @@ object Promise { */ final class KeptPromise[T](suppliedValue: Either[Throwable, T])(implicit val executor: ExecutionContext) extends Promise[T] { - val value = Some(resolve(suppliedValue)) + val value = Some(resolveEither(suppliedValue)) def tryComplete(value: Either[Throwable, T]): Boolean = false diff --git a/src/library/scala/concurrent/package.scala b/src/library/scala/concurrent/package.scala index e2ae17498f..b06c6f3c63 100644 --- a/src/library/scala/concurrent/package.scala +++ b/src/library/scala/concurrent/package.scala @@ -31,16 +31,6 @@ package concurrent { def result[T](awaitable: Awaitable[T], atMost: Duration): T = awaitable.result(atMost) } - /** A timeout exception. - * - * Futures are failed with a timeout exception when their timeout expires. - * - * Each timeout exception contains an origin future which originally timed out. - */ - class FutureTimeoutException(origin: Future[_], message: String) extends TimeoutException(message) { - def this(origin: Future[_]) = this(origin, "Future timed out.") - } - final class DurationOps private[concurrent] (x: Int) { // TODO ADD OTHERS def ns = util.Duration.fromNanos(0) diff --git a/src/library/scala/concurrent/util/Duration.scala b/src/library/scala/concurrent/util/Duration.scala index 33d034da76..15a546de10 100644 --- a/src/library/scala/concurrent/util/Duration.scala +++ b/src/library/scala/concurrent/util/Duration.scala @@ -7,51 +7,7 @@ package scala.concurrent.util import java.util.concurrent.TimeUnit import TimeUnit._ import java.lang.{ Double ⇒ JDouble } - -object DurationImplicits { - trait Classifier[C] { - type R - def convert(d: FiniteDuration): R - } - - object span - implicit object spanConvert extends Classifier[span.type] { - type R = FiniteDuration - def convert(d: FiniteDuration) = d - } - - object fromNow - implicit object fromNowConvert extends Classifier[fromNow.type] { - type R = Deadline - def convert(d: FiniteDuration) = Deadline.now + d - } - - implicit def intToDurationInt(n: Int) = new DurationInt(n) - implicit def longToDurationLong(n: Long) = new DurationLong(n) - implicit def doubleToDurationDouble(d: Double) = new DurationDouble(d) - - implicit def pairIntToDuration(p: (Int, TimeUnit)) = Duration(p._1, p._2) - implicit def pairLongToDuration(p: (Long, TimeUnit)) = Duration(p._1, p._2) - implicit def durationToPair(d: Duration) = (d.length, d.unit) - - /* - * Avoid reflection based invocation by using non-duck type - */ - class IntMult(i: Int) { - def *(d: Duration) = d * i - } - implicit def intMult(i: Int) = new IntMult(i) - - class LongMult(l: Long) { - def *(d: Duration) = d * l - } - implicit def longMult(l: Long) = new LongMult(l) - - class DoubleMult(f: Double) { - def *(d: Duration) = d * f - } - implicit def doubleMult(f: Double) = new DoubleMult(f) -} +import language.implicitConversions case class Deadline private (time: Duration) { def +(other: Duration): Deadline = copy(time = time + other) @@ -71,10 +27,7 @@ object Duration { def apply(length: Long, unit: TimeUnit): FiniteDuration = new FiniteDuration(length, unit) def apply(length: Double, unit: TimeUnit): FiniteDuration = fromNanos(unit.toNanos(1) * length) - def apply(length: Long, unit: String): FiniteDuration = { - val (mult, timeUnit) = Duration.timeUnit(unit) - new FiniteDuration(length * mult, timeUnit) - } + def apply(length: Long, unit: String): FiniteDuration = new FiniteDuration(length, Duration.timeUnit(unit)) /** * Construct a Duration by parsing a String. In case of a format error, a @@ -117,11 +70,11 @@ object Duration { def unapply(s: String): Option[Duration] = s match { case RE(length, d, h, m, s, ms, mus, ns) ⇒ if (d ne null) - Some(Duration(JDouble.parseDouble(length) * 86400, SECONDS)) + Some(Duration(JDouble.parseDouble(length), DAYS)) else if (h ne null) - Some(Duration(JDouble.parseDouble(length) * 3600, SECONDS)) + Some(Duration(JDouble.parseDouble(length), HOURS)) else if (m ne null) - Some(Duration(JDouble.parseDouble(length) * 60, SECONDS)) + Some(Duration(JDouble.parseDouble(length), MINUTES)) else if (s ne null) Some(Duration(JDouble.parseDouble(length), SECONDS)) else if (ms ne null) @@ -142,11 +95,11 @@ object Duration { def fromNanos(nanos: Long): FiniteDuration = { if (nanos % 86400000000000L == 0) { - Duration(nanos / 1000000000L, SECONDS) - } else if (nanos % 1000000000L == 0) { - Duration(nanos / 1000000000L, SECONDS) - } else if (nanos % 1000000000L == 0) { - Duration(nanos / 1000000000L, SECONDS) + Duration(nanos / 86400000000000L, DAYS) + } else if (nanos % 3600000000000L == 0) { + Duration(nanos / 3600000000000L, HOURS) + } else if (nanos % 60000000000L == 0) { + Duration(nanos / 60000000000L, MINUTES) } else if (nanos % 1000000000L == 0) { Duration(nanos / 1000000000L, SECONDS) } else if (nanos % 1000000L == 0) { @@ -161,14 +114,14 @@ object Duration { /** * Parse TimeUnit from string representation. */ - protected[util] def timeUnit(unit: String): (Long, TimeUnit) = unit.toLowerCase match { - case "d" | "day" | "days" ⇒ (86400, SECONDS) - case "h" | "hour" | "hours" ⇒ (3600, SECONDS) - case "min" | "minute" | "minutes" ⇒ (60, SECONDS) - case "s" | "sec" | "second" | "seconds" ⇒ (1, SECONDS) - case "ms" | "milli" | "millis" | "millisecond" | "milliseconds" ⇒ (1, MILLISECONDS) - case "µs" | "micro" | "micros" | "microsecond" | "microseconds" ⇒ (1, MICROSECONDS) - case "ns" | "nano" | "nanos" | "nanosecond" | "nanoseconds" ⇒ (1, NANOSECONDS) + protected[util] def timeUnit(unit: String): TimeUnit = unit.toLowerCase match { + case "d" | "day" | "days" ⇒ DAYS + case "h" | "hour" | "hours" ⇒ HOURS + case "min" | "minute" | "minutes" ⇒ MINUTES + case "s" | "sec" | "second" | "seconds" ⇒ SECONDS + case "ms" | "milli" | "millis" | "millisecond" | "milliseconds" ⇒ MILLISECONDS + case "µs" | "micro" | "micros" | "microsecond" | "microseconds" ⇒ MICROSECONDS + case "ns" | "nano" | "nanos" | "nanosecond" | "nanoseconds" ⇒ NANOSECONDS } val Zero: FiniteDuration = new FiniteDuration(0, NANOSECONDS) @@ -328,13 +281,9 @@ object FiniteDuration { def compare(a: FiniteDuration, b: FiniteDuration) = a compare b } - def apply(length: Long, unit: TimeUnit) = - new FiniteDuration(length, unit) + def apply(length: Long, unit: TimeUnit) = new FiniteDuration(length, unit) - def apply(length: Long, unit: String) = { - val (mult, timeUnit) = Duration.timeUnit(unit) - new FiniteDuration(length * mult, timeUnit) - } + def apply(length: Long, unit: String) = new FiniteDuration(length, Duration.timeUnit(unit)) } @@ -351,6 +300,12 @@ class FiniteDuration(val length: Long, val unit: TimeUnit) extends Duration { def toUnit(u: TimeUnit) = long2double(toNanos) / NANOSECONDS.convert(1, u) override def toString = this match { + case Duration(1, DAYS) ⇒ "1 day" + case Duration(x, DAYS) ⇒ x + " days" + case Duration(1, HOURS) ⇒ "1 hour" + case Duration(x, HOURS) ⇒ x + " hours" + case Duration(1, MINUTES) ⇒ "1 minute" + case Duration(x, MINUTES) ⇒ x + " minutes" case Duration(1, SECONDS) ⇒ "1 second" case Duration(x, SECONDS) ⇒ x + " seconds" case Duration(1, MILLISECONDS) ⇒ "1 millisecond" @@ -404,7 +359,7 @@ class FiniteDuration(val length: Long, val unit: TimeUnit) extends Duration { } class DurationInt(n: Int) { - import DurationImplicits.Classifier + import duration.Classifier def nanoseconds = Duration(n, NANOSECONDS) def nanos = Duration(n, NANOSECONDS) @@ -424,14 +379,14 @@ class DurationInt(n: Int) { def seconds = Duration(n, SECONDS) def second = Duration(n, SECONDS) - def minutes = Duration(n * 60, SECONDS) - def minute = Duration(n * 60, SECONDS) + def minutes = Duration(n, MINUTES) + def minute = Duration(n, MINUTES) - def hours = Duration(n * 3600, SECONDS) - def hour = Duration(n * 3600, SECONDS) + def hours = Duration(n, HOURS) + def hour = Duration(n, HOURS) - def days = Duration(n * 86400, SECONDS) - def day = Duration(n * 86400, SECONDS) + def days = Duration(n, DAYS) + def day = Duration(n, DAYS) def nanoseconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, NANOSECONDS)) def nanos[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, NANOSECONDS)) @@ -451,18 +406,18 @@ class DurationInt(n: Int) { def seconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, SECONDS)) def second[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, SECONDS)) - def minutes[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 60, SECONDS)) - def minute[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 60, SECONDS)) + def minutes[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, MINUTES)) + def minute[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, MINUTES)) - def hours[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 3600, SECONDS)) - def hour[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 3600, SECONDS)) + def hours[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, HOURS)) + def hour[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, HOURS)) - def days[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 86400, SECONDS)) - def day[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 86400, SECONDS)) + def days[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, DAYS)) + def day[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, DAYS)) } class DurationLong(n: Long) { - import DurationImplicits.Classifier + import duration.Classifier def nanoseconds = Duration(n, NANOSECONDS) def nanos = Duration(n, NANOSECONDS) @@ -482,14 +437,14 @@ class DurationLong(n: Long) { def seconds = Duration(n, SECONDS) def second = Duration(n, SECONDS) - def minutes = Duration(n * 60, SECONDS) - def minute = Duration(n * 60, SECONDS) + def minutes = Duration(n, MINUTES) + def minute = Duration(n, MINUTES) - def hours = Duration(n * 3600, SECONDS) - def hour = Duration(n * 3600, SECONDS) + def hours = Duration(n, HOURS) + def hour = Duration(n, HOURS) - def days = Duration(n * 86400, SECONDS) - def day = Duration(n * 86400, SECONDS) + def days = Duration(n, DAYS) + def day = Duration(n, DAYS) def nanoseconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, NANOSECONDS)) def nanos[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, NANOSECONDS)) @@ -509,18 +464,18 @@ class DurationLong(n: Long) { def seconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, SECONDS)) def second[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, SECONDS)) - def minutes[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 60, SECONDS)) - def minute[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 60, SECONDS)) + def minutes[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, MINUTES)) + def minute[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, MINUTES)) - def hours[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 3600, SECONDS)) - def hour[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 3600, SECONDS)) + def hours[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, HOURS)) + def hour[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, HOURS)) - def days[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 86400, SECONDS)) - def day[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n * 86400, SECONDS)) + def days[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, DAYS)) + def day[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(n, DAYS)) } class DurationDouble(d: Double) { - import DurationImplicits.Classifier + import duration.Classifier def nanoseconds = Duration(d, NANOSECONDS) def nanos = Duration(d, NANOSECONDS) @@ -540,14 +495,14 @@ class DurationDouble(d: Double) { def seconds = Duration(d, SECONDS) def second = Duration(d, SECONDS) - def minutes = Duration(d * 60, SECONDS) - def minute = Duration(d * 60, SECONDS) + def minutes = Duration(d, MINUTES) + def minute = Duration(d, MINUTES) - def hours = Duration(d * 3600, SECONDS) - def hour = Duration(d * 3600, SECONDS) + def hours = Duration(d, HOURS) + def hour = Duration(d, HOURS) - def days = Duration(d * 86400, SECONDS) - def day = Duration(d * 86400, SECONDS) + def days = Duration(d, DAYS) + def day = Duration(d, DAYS) def nanoseconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, NANOSECONDS)) def nanos[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, NANOSECONDS)) @@ -567,12 +522,12 @@ class DurationDouble(d: Double) { def seconds[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, SECONDS)) def second[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, SECONDS)) - def minutes[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d * 60, SECONDS)) - def minute[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d * 60, SECONDS)) + def minutes[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, MINUTES)) + def minute[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, MINUTES)) - def hours[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d * 3600, SECONDS)) - def hour[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d * 3600, SECONDS)) + def hours[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, HOURS)) + def hour[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, HOURS)) - def days[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d * 86400, SECONDS)) - def day[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d * 86400, SECONDS)) + def days[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, DAYS)) + def day[C, CC <: Classifier[C]](c: C)(implicit ev: CC): CC#R = ev.convert(Duration(d, DAYS)) } diff --git a/src/library/scala/concurrent/util/duration/Classifier.scala b/src/library/scala/concurrent/util/duration/Classifier.scala new file mode 100644 index 0000000000..10faf0a5ce --- /dev/null +++ b/src/library/scala/concurrent/util/duration/Classifier.scala @@ -0,0 +1,9 @@ +package scala.concurrent.util.duration + +import scala.concurrent.util.{ FiniteDuration } + +trait Classifier[C] { + type R + def convert(d: FiniteDuration): R +} + diff --git a/src/library/scala/concurrent/util/duration/IntMult.scala b/src/library/scala/concurrent/util/duration/IntMult.scala new file mode 100644 index 0000000000..94c58fb8c2 --- /dev/null +++ b/src/library/scala/concurrent/util/duration/IntMult.scala @@ -0,0 +1,18 @@ +package scala.concurrent.util.duration + +import scala.concurrent.util.{ Duration } + +/* + * Avoid reflection based invocation by using non-duck type + */ +protected[duration] class IntMult(i: Int) { + def *(d: Duration) = d * i +} + +protected[duration] class LongMult(i: Long) { + def *(d: Duration) = d * i +} + +protected[duration] class DoubleMult(f: Double) { + def *(d: Duration) = d * f +} diff --git a/src/library/scala/concurrent/util/duration/package.scala b/src/library/scala/concurrent/util/duration/package.scala new file mode 100644 index 0000000000..25625054ee --- /dev/null +++ b/src/library/scala/concurrent/util/duration/package.scala @@ -0,0 +1,30 @@ +package scala.concurrent.util + +import java.util.concurrent.TimeUnit + +package object duration { + + object span + implicit object spanConvert extends Classifier[span.type] { + type R = FiniteDuration + def convert(d: FiniteDuration) = d + } + + object fromNow + implicit object fromNowConvert extends Classifier[fromNow.type] { + type R = Deadline + def convert(d: FiniteDuration) = Deadline.now + d + } + + implicit def intToDurationInt(n: Int) = new DurationInt(n) + implicit def longToDurationLong(n: Long) = new DurationLong(n) + implicit def doubleToDurationDouble(d: Double) = new DurationDouble(d) + + implicit def pairIntToDuration(p: (Int, TimeUnit)) = Duration(p._1, p._2) + implicit def pairLongToDuration(p: (Long, TimeUnit)) = Duration(p._1, p._2) + implicit def durationToPair(d: Duration) = (d.length, d.unit) + + implicit def intMult(i: Int) = new IntMult(i) + implicit def longMult(l: Long) = new LongMult(l) + implicit def doubleMult(f: Double) = new DoubleMult(f) +}
\ No newline at end of file diff --git a/src/library/scala/io/BytePickle.scala b/src/library/scala/io/BytePickle.scala index bec0cfb53f..3bb5ea9c2b 100644 --- a/src/library/scala/io/BytePickle.scala +++ b/src/library/scala/io/BytePickle.scala @@ -269,7 +269,7 @@ object BytePickle { } def string: SPU[String] = share(wrap( - (a: Array[Byte]) => Codec fromUTF8 a mkString, + (a: Array[Byte]) => (Codec fromUTF8 a).mkString, (s: String) => Codec toUTF8 s, bytearray )) diff --git a/src/library/scala/io/Codec.scala b/src/library/scala/io/Codec.scala index d9cef0edb1..84cac88dcc 100644 --- a/src/library/scala/io/Codec.scala +++ b/src/library/scala/io/Codec.scala @@ -11,6 +11,7 @@ package scala.io import java.nio.charset.{ Charset, CharsetDecoder, CharsetEncoder, CharacterCodingException, CodingErrorAction => Action } import annotation.migration +import language.implicitConversions // Some notes about encodings for use in refining this implementation. // diff --git a/src/library/scala/io/Source.scala b/src/library/scala/io/Source.scala index 3cee0ace79..5e09e13680 100644 --- a/src/library/scala/io/Source.scala +++ b/src/library/scala/io/Source.scala @@ -188,7 +188,7 @@ abstract class Source extends Iterator[Char] { var nerrors = 0 var nwarnings = 0 - private def lineNum(line: Int): String = getLines() drop (line - 1) take 1 mkString + private def lineNum(line: Int): String = (getLines() drop (line - 1) take 1).mkString class LineIterator extends AbstractIterator[String] with Iterator[String] { private[this] val sb = new StringBuilder diff --git a/src/library/scala/language.scala b/src/library/scala/language.scala new file mode 100644 index 0000000000..907adb5f72 --- /dev/null +++ b/src/library/scala/language.scala @@ -0,0 +1,25 @@ +package scala + +object language { + + import languageFeature._ + + implicit val dynamics: dynamics = ??? + + implicit val postfixOps: postfixOps = ??? + + implicit val reflectiveCalls: reflectiveCalls = ??? + + implicit val implicitConversions: implicitConversions = ??? + + implicit val higherKinds: higherKinds = ??? + + implicit val existentials: existentials = ??? + + object experimental { + + import languageFeature.experimental._ + + implicit val macros: macros = ??? + } +} diff --git a/src/library/scala/languageFeature.scala b/src/library/scala/languageFeature.scala new file mode 100644 index 0000000000..c990f714c1 --- /dev/null +++ b/src/library/scala/languageFeature.scala @@ -0,0 +1,30 @@ +package scala + +import annotation.meta + +object languageFeature { + + @meta.languageFeature("extension of type scala.Dynamic", true) + sealed trait dynamics + + @meta.languageFeature("postfix operator #", false) + sealed trait postfixOps + + @meta.languageFeature("reflective access of structural type member #", false) + sealed trait reflectiveCalls + + @meta.languageFeature("implicit conversion #", false) + sealed trait implicitConversions + + @meta.languageFeature("higher-kinded type", false) + sealed trait higherKinds + + @meta.languageFeature("#, which cannot be expressed by wildcards, ", false) + sealed trait existentials + + object experimental { + @meta.languageFeature("macro definition", true) + sealed trait macros + } +} + diff --git a/src/library/scala/math/BigDecimal.scala b/src/library/scala/math/BigDecimal.scala index cb42b76b51..74daa510ca 100644 --- a/src/library/scala/math/BigDecimal.scala +++ b/src/library/scala/math/BigDecimal.scala @@ -12,6 +12,7 @@ package scala.math import java.{ lang => jl } import java.math.{ MathContext, BigDecimal => BigDec } import scala.collection.immutable.NumericRange +import language.implicitConversions /** @@ -292,7 +293,7 @@ extends ScalaNumber with ScalaNumericConversions with Serializable { /** Returns the absolute value of this BigDecimal */ - def abs: BigDecimal = this.bigDecimal abs + def abs: BigDecimal = this.bigDecimal.abs /** Returns the sign of this BigDecimal, i.e. * -1 if it is less than 0, diff --git a/src/library/scala/math/BigInt.scala b/src/library/scala/math/BigInt.scala index dbec30b2fe..ff52ca9bec 100644 --- a/src/library/scala/math/BigInt.scala +++ b/src/library/scala/math/BigInt.scala @@ -9,6 +9,7 @@ package scala.math import java.math.BigInteger +import language.implicitConversions /** * @author Martin Odersky diff --git a/src/library/scala/math/Fractional.scala b/src/library/scala/math/Fractional.scala index de09b184e0..0686569c16 100644 --- a/src/library/scala/math/Fractional.scala +++ b/src/library/scala/math/Fractional.scala @@ -8,6 +8,8 @@ package scala.math +import language.implicitConversions + /** * @since 2.8 */ diff --git a/src/library/scala/math/Integral.scala b/src/library/scala/math/Integral.scala index bb364a79b4..4b4de28228 100644 --- a/src/library/scala/math/Integral.scala +++ b/src/library/scala/math/Integral.scala @@ -10,6 +10,8 @@ package scala.math +import language.implicitConversions + /** * @since 2.8 */ diff --git a/src/library/scala/math/Numeric.scala b/src/library/scala/math/Numeric.scala index ff88e0ff4d..1f4e3c9865 100644 --- a/src/library/scala/math/Numeric.scala +++ b/src/library/scala/math/Numeric.scala @@ -8,6 +8,8 @@ package scala.math +import language.implicitConversions + /** * @since 2.8 */ diff --git a/src/library/scala/math/Ordered.scala b/src/library/scala/math/Ordered.scala index b76030718f..80addea7f3 100644 --- a/src/library/scala/math/Ordered.scala +++ b/src/library/scala/math/Ordered.scala @@ -8,6 +8,8 @@ package scala.math +import language.implicitConversions + /** A trait for data that have a single, natural ordering. See * [[scala.math.Ordering]] before using this trait for * more information about whether to use [[scala.math.Ordering]] instead. diff --git a/src/library/scala/math/Ordering.scala b/src/library/scala/math/Ordering.scala index 8fc74a9d5d..ab685815a1 100644 --- a/src/library/scala/math/Ordering.scala +++ b/src/library/scala/math/Ordering.scala @@ -9,6 +9,7 @@ package scala.math import java.util.Comparator +import language.{implicitConversions, higherKinds} /** Ordering is a trait whose instances each represent a strategy for sorting * instances of a type. diff --git a/src/library/scala/reflect/ArrayTag.scala b/src/library/scala/reflect/ArrayTag.scala new file mode 100644 index 0000000000..8df7fe5f4e --- /dev/null +++ b/src/library/scala/reflect/ArrayTag.scala @@ -0,0 +1,19 @@ +package scala.reflect + +/** An `ArrayTag[T]` is a descriptor that is requested by the compiler every time + * when an array is instantiated, but the element type is unknown at compile time. + * + * Scala library provides a standard implementation of this trait, + * `ClassTag[T]` that explicitly carries the `java.lang.Class` erasure of type T. + * + * However other platforms (e.g. a Scala -> JS crosscompiler) may reimplement this trait as they see fit + * and then expose the implementation via an implicit macro. + */ +@annotation.implicitNotFound(msg = "No ArrayTag available for ${T}") +trait ArrayTag[T] { + /** Produces an `ArrayTag` that knows how to build `Array[Array[T]]` */ + def wrap: ArrayTag[Array[T]] + + /** Produces a new array with element type `T` and length `len` */ + def newArray(len: Int): Array[T] +}
\ No newline at end of file diff --git a/src/library/scala/reflect/ClassManifest.scala b/src/library/scala/reflect/ClassManifest.scala deleted file mode 100644 index 37be067614..0000000000 --- a/src/library/scala/reflect/ClassManifest.scala +++ /dev/null @@ -1,263 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -/* [Martin] - * Todo: ClassManifests currently contain all available type arguments. - * That's a waste of cycles if all that's needed is the class. - * We should have instead consider a structure like this: - * - * OptManifest - * / \ - * / \ - * PartialManifest ClassManifest - * \ / - * \ / - * Manifest - * - * where PartialManifest means: generate as much as you can, use NoManifest - * where nothing is known, and - * ClassManifest means: generate exactly the top-level class, and nothing else. - */ -package scala.reflect - -import scala.collection.mutable.{ WrappedArray, ArrayBuilder } -import java.lang.{ Class => jClass } - -/** A `ClassManifest[T]` is an opaque descriptor for type `T`. - * It is used by the compiler to preserve information necessary - * for instantiating `Arrays` in those cases where the element type - * is unknown at compile time. - * - * The type-relation operators make an effort to present a more accurate - * picture than can be realized with erased types, but they should not be - * relied upon to give correct answers. In particular they are likely to - * be wrong when variance is involved or when a subtype has a different - * number of type arguments than a supertype. - */ -trait ClassManifest[T] extends OptManifest[T] with Equals with Serializable { - /** A class representing the type `U` to which `T` would be erased. Note - * that there is no subtyping relationship between `T` and `U`. */ - def erasure: jClass[_] - - /** The Scala type described by this manifest. - */ - lazy val tpe: mirror.Type = mirror.classToType(erasure) - - def symbol: mirror.Symbol = mirror.classToSymbol(erasure) - - private def subtype(sub: jClass[_], sup: jClass[_]): Boolean = { - def loop(left: Set[jClass[_]], seen: Set[jClass[_]]): Boolean = { - left.nonEmpty && { - val next = left.head - val supers = next.getInterfaces.toSet ++ Option(next.getSuperclass) - supers(sup) || { - val xs = left ++ supers filterNot seen - loop(xs - next, seen + next) - } - } - } - loop(Set(sub), Set()) - } - - private def subargs(args1: List[OptManifest[_]], args2: List[OptManifest[_]]) = (args1 corresponds args2) { - // !!! [Martin] this is wrong, need to take variance into account - case (x: ClassManifest[_], y: ClassManifest[_]) => x <:< y - case (x, y) => (x eq NoManifest) && (y eq NoManifest) - } - - /** Tests whether the type represented by this manifest is a subtype - * of the type represented by `that` manifest, subject to the limitations - * described in the header. - */ - def <:<(that: ClassManifest[_]): Boolean = { - // All types which could conform to these types will override <:<. - def cannotMatch = { - import Manifest._ - that.isInstanceOf[AnyValManifest[_]] || (that eq AnyVal) || (that eq Nothing) || (that eq Null) - } - - // This is wrong, and I don't know how it can be made right - // without more development of Manifests, due to arity-defying - // relationships like: - // - // List[String] <: AnyRef - // Map[Int, Int] <: Iterable[(Int, Int)] - // - // Given the manifest for Map[A, B] how do I determine that a - // supertype has single type argument (A, B) ? I don't see how we - // can say whether X <:< Y when type arguments are involved except - // when the erasure is the same, even before considering variance. - !cannotMatch && { - // this part is wrong for not considering variance - if (this.erasure == that.erasure) - subargs(this.typeArguments, that.typeArguments) - // this part is wrong for punting unless the rhs has no type - // arguments, but it's better than a blindfolded pinata swing. - else - that.typeArguments.isEmpty && subtype(this.erasure, that.erasure) - } - } - - /** Tests whether the type represented by this manifest is a supertype - * of the type represented by `that` manifest, subject to the limitations - * described in the header. - */ - def >:>(that: ClassManifest[_]): Boolean = - that <:< this - - def canEqual(other: Any) = other match { - case _: ClassManifest[_] => true - case _ => false - } - - /** Tests whether the type represented by this manifest is equal to - * the type represented by `that` manifest, subject to the limitations - * described in the header. - */ - override def equals(that: Any): Boolean = that match { - case m: ClassManifest[_] => (m canEqual this) && (this.erasure == m.erasure) - case _ => false - } - override def hashCode = this.erasure.## - - protected def arrayClass[T](tp: jClass[_]): jClass[Array[T]] = - java.lang.reflect.Array.newInstance(tp, 0).getClass.asInstanceOf[jClass[Array[T]]] - - def arrayManifest: ClassManifest[Array[T]] = - ClassManifest.classType[Array[T]](arrayClass[T](erasure), this) - - def newArray(len: Int): Array[T] = - java.lang.reflect.Array.newInstance(erasure, len).asInstanceOf[Array[T]] - - def newArray2(len: Int): Array[Array[T]] = - java.lang.reflect.Array.newInstance(arrayClass[T](erasure), len) - .asInstanceOf[Array[Array[T]]] - - def newArray3(len: Int): Array[Array[Array[T]]] = - java.lang.reflect.Array.newInstance(arrayClass[Array[T]](arrayClass[T](erasure)), len) - .asInstanceOf[Array[Array[Array[T]]]] - - def newArray4(len: Int): Array[Array[Array[Array[T]]]] = - java.lang.reflect.Array.newInstance(arrayClass[Array[Array[T]]](arrayClass[Array[T]](arrayClass[T](erasure))), len) - .asInstanceOf[Array[Array[Array[Array[T]]]]] - - def newArray5(len: Int): Array[Array[Array[Array[Array[T]]]]] = - java.lang.reflect.Array.newInstance(arrayClass[Array[Array[Array[T]]]](arrayClass[Array[Array[T]]](arrayClass[Array[T]](arrayClass[T](erasure)))), len) - .asInstanceOf[Array[Array[Array[Array[Array[T]]]]]] - - def newWrappedArray(len: Int): WrappedArray[T] = - // it's safe to assume T <: AnyRef here because the method is overridden for all value type manifests - new WrappedArray.ofRef[T with AnyRef](newArray(len).asInstanceOf[Array[T with AnyRef]]).asInstanceOf[WrappedArray[T]] - - def newArrayBuilder(): ArrayBuilder[T] = - // it's safe to assume T <: AnyRef here because the method is overridden for all value type manifests - new ArrayBuilder.ofRef[T with AnyRef]()(this.asInstanceOf[ClassManifest[T with AnyRef]]).asInstanceOf[ArrayBuilder[T]] - - def typeArguments: List[OptManifest[_]] = List() - - protected def argString = - if (typeArguments.nonEmpty) typeArguments.mkString("[", ", ", "]") - else if (erasure.isArray) "["+ClassManifest.fromClass(erasure.getComponentType)+"]" - else "" -} - -/** The object `ClassManifest` defines factory methods for manifests. - * It is intended for use by the compiler and should not be used in client code. - */ -object ClassManifest { - val Byte = Manifest.Byte - val Short = Manifest.Short - val Char = Manifest.Char - val Int = Manifest.Int - val Long = Manifest.Long - val Float = Manifest.Float - val Double = Manifest.Double - val Boolean = Manifest.Boolean - val Unit = Manifest.Unit - val Any = Manifest.Any - val Object = Manifest.Object - val AnyVal = Manifest.AnyVal - val Nothing = Manifest.Nothing - val Null = Manifest.Null - - def fromClass[T](clazz: jClass[T]): ClassManifest[T] = clazz match { - case java.lang.Byte.TYPE => Byte.asInstanceOf[ClassManifest[T]] - case java.lang.Short.TYPE => Short.asInstanceOf[ClassManifest[T]] - case java.lang.Character.TYPE => Char.asInstanceOf[ClassManifest[T]] - case java.lang.Integer.TYPE => Int.asInstanceOf[ClassManifest[T]] - case java.lang.Long.TYPE => Long.asInstanceOf[ClassManifest[T]] - case java.lang.Float.TYPE => Float.asInstanceOf[ClassManifest[T]] - case java.lang.Double.TYPE => Double.asInstanceOf[ClassManifest[T]] - case java.lang.Boolean.TYPE => Boolean.asInstanceOf[ClassManifest[T]] - case java.lang.Void.TYPE => Unit.asInstanceOf[ClassManifest[T]] - case _ => classType[T with AnyRef](clazz).asInstanceOf[ClassManifest[T]] - } - - def singleType[T <: AnyRef](value: AnyRef): Manifest[T] = Manifest.singleType(value) - - /** ClassManifest for the class type `clazz`, where `clazz` is - * a top-level or static class. - * @note This no-prefix, no-arguments case is separate because we - * it's called from ScalaRunTime.boxArray itself. If we - * pass varargs as arrays into this, we get an infinitely recursive call - * to boxArray. (Besides, having a separate case is more efficient) - */ - def classType[T](clazz: jClass[_]): ClassManifest[T] = - new ClassTypeManifest[T](None, clazz, Nil) - - /** ClassManifest for the class type `clazz[args]`, where `clazz` is - * a top-level or static class and `args` are its type arguments */ - def classType[T](clazz: jClass[_], arg1: OptManifest[_], args: OptManifest[_]*): ClassManifest[T] = - new ClassTypeManifest[T](None, clazz, arg1 :: args.toList) - - /** ClassManifest for the class type `clazz[args]`, where `clazz` is - * a class with non-package prefix type `prefix` and type arguments `args`. - */ - def classType[T](prefix: OptManifest[_], clazz: jClass[_], args: OptManifest[_]*): ClassManifest[T] = - new ClassTypeManifest[T](Some(prefix), clazz, args.toList) - - def arrayType[T](arg: OptManifest[_]): ClassManifest[Array[T]] = arg match { - case NoManifest => Object.asInstanceOf[ClassManifest[Array[T]]] - case m: ClassManifest[_] => m.asInstanceOf[ClassManifest[T]].arrayManifest - } - - /** 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] { - def erasure = 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. - * todo: remove after next boostrap - */ - def abstractType[T](prefix: OptManifest[_], name: String, upperbound: ClassManifest[_], args: OptManifest[_]*): ClassManifest[T] = - new ClassManifest[T] { - def erasure = upperbound.erasure - override val typeArguments = args.toList - override def toString = prefix.toString+"#"+name+argString - } -} - -/** Manifest for the class type `clazz[args]`, where `clazz` is - * a top-level or static class: todo: we should try to merge this with Manifest's class */ -private class ClassTypeManifest[T]( - prefix: Option[OptManifest[_]], - val erasure: jClass[_], - override val typeArguments: List[OptManifest[_]]) extends ClassManifest[T] -{ - override def toString = - (if (prefix.isEmpty) "" else prefix.get.toString+"#") + - (if (erasure.isArray) "Array" else erasure.getName) + - argString -} diff --git a/src/library/scala/reflect/ClassTag.scala b/src/library/scala/reflect/ClassTag.scala new file mode 100644 index 0000000000..7138837f0d --- /dev/null +++ b/src/library/scala/reflect/ClassTag.scala @@ -0,0 +1,168 @@ +package scala.reflect + +import java.lang.{ Class => jClass } +import scala.reflect.{ mirror => rm } +import language.{implicitConversions, existentials} + +/** A `ClassTag[T]` wraps a Java class, which can be accessed via the `erasure` method. + * + * This is useful in itself, but also enables very important use case. + * Having this knowledge ClassTag can instantiate `Arrays` + * in those cases where the element type is unknown at compile time. + * Hence, ClassTag[T] conforms to the ArrayTag[T] trait. + * + * If an implicit value of type u.ClassTag[T] is required, the compiler will make one up on demand. + * The implicitly created value contains in its erasure field the Java class that is the result of erasing type T. + * In that value, any occurrences of type parameters or abstract types U which come themselves with a ClassTag + * or a reflect.mirror.ConcreteTypeTag are represented by the type referenced by that tag. + * If the type T contains unresolved references to type parameters or abstract types, a static error results. + * + * A ConcreteTypeTag member of the reflect.mirror object is convertible to a ClassTag via an implicit conversion + * (this is not possible to do in all reflection universes because an operation that converts a type to a Java class might not be available). */ +// please, don't add any APIs here, like it was with `newWrappedArray` and `newArrayBuilder` +// class tags, and all tags in general, should be as minimalistic as possible +@annotation.implicitNotFound(msg = "No ClassTag available for ${T}") +abstract case class ClassTag[T](erasure: jClass[_]) extends ArrayTag[T] { + // quick and dirty fix to a deadlock in Predef: + // http://groups.google.com/group/scala-internals/browse_thread/thread/977de028a4e75d6f + // todo. fix that in a sane way + // assert(erasure != null) + + /** A Scala reflection type representing T. + * For ClassTags this representation is lossy (in their case tpe is retrospectively constructed from erasure). + * For TypeTags and ConcreteTypeTags the representation is almost precise, because they use reification + * (information is lost only when T refers to non-locatable symbols, which are then reified as free variables). */ + def tpe: rm.Type = rm.classToType(erasure) + + /** A Scala reflection symbol representing T. */ + def symbol: rm.Symbol = rm.classToSymbol(erasure) + + /** Produces a `ClassTag` that knows how to build `Array[Array[T]]` */ + def wrap: ClassTag[Array[T]] = { + val arrayClazz = java.lang.reflect.Array.newInstance(erasure, 0).getClass.asInstanceOf[jClass[Array[T]]] + ClassTag[Array[T]](arrayClazz) + } + + /** Produces a new array with element type `T` and length `len` */ + def newArray(len: Int): Array[T] = + erasure match { + case java.lang.Byte.TYPE => new Array[Byte](len).asInstanceOf[Array[T]] + case java.lang.Short.TYPE => new Array[Short](len).asInstanceOf[Array[T]] + case java.lang.Character.TYPE => new Array[Char](len).asInstanceOf[Array[T]] + case java.lang.Integer.TYPE => new Array[Int](len).asInstanceOf[Array[T]] + case java.lang.Long.TYPE => new Array[Long](len).asInstanceOf[Array[T]] + case java.lang.Float.TYPE => new Array[Float](len).asInstanceOf[Array[T]] + case java.lang.Double.TYPE => new Array[Double](len).asInstanceOf[Array[T]] + case java.lang.Boolean.TYPE => new Array[Boolean](len).asInstanceOf[Array[T]] + case java.lang.Void.TYPE => new Array[Unit](len).asInstanceOf[Array[T]] + case _ => java.lang.reflect.Array.newInstance(erasure, len).asInstanceOf[Array[T]] + } +} + +object ClassTag { + private val ObjectTYPE = classOf[java.lang.Object] + private val StringTYPE = classOf[java.lang.String] + + val Byte : ClassTag[scala.Byte] = new ClassTag[scala.Byte](java.lang.Byte.TYPE) { private def readResolve() = ClassTag.Byte } + val Short : ClassTag[scala.Short] = new ClassTag[scala.Short](java.lang.Short.TYPE) { private def readResolve() = ClassTag.Short } + val Char : ClassTag[scala.Char] = new ClassTag[scala.Char](java.lang.Character.TYPE) { private def readResolve() = ClassTag.Char } + val Int : ClassTag[scala.Int] = new ClassTag[scala.Int](java.lang.Integer.TYPE) { private def readResolve() = ClassTag.Int } + val Long : ClassTag[scala.Long] = new ClassTag[scala.Long](java.lang.Long.TYPE) { private def readResolve() = ClassTag.Long } + val Float : ClassTag[scala.Float] = new ClassTag[scala.Float](java.lang.Float.TYPE) { private def readResolve() = ClassTag.Float } + val Double : ClassTag[scala.Double] = new ClassTag[scala.Double](java.lang.Double.TYPE) { private def readResolve() = ClassTag.Double } + val Boolean : ClassTag[scala.Boolean] = new ClassTag[scala.Boolean](java.lang.Boolean.TYPE) { private def readResolve() = ClassTag.Boolean } + val Unit : ClassTag[scala.Unit] = new ClassTag[scala.Unit](java.lang.Void.TYPE) { private def readResolve() = ClassTag.Unit } + val Any : ClassTag[scala.Any] = new ClassTag[scala.Any](ObjectTYPE) { private def readResolve() = ClassTag.Any } + val Object : ClassTag[java.lang.Object] = new ClassTag[java.lang.Object](ObjectTYPE) { private def readResolve() = ClassTag.Object } + val AnyVal : ClassTag[scala.AnyVal] = new ClassTag[scala.AnyVal](ObjectTYPE) { private def readResolve() = ClassTag.AnyVal } + val AnyRef : ClassTag[scala.AnyRef] = new ClassTag[scala.AnyRef](ObjectTYPE) { private def readResolve() = ClassTag.AnyRef } + val Nothing : ClassTag[scala.Nothing] = new ClassTag[scala.Nothing](ObjectTYPE) { private def readResolve() = ClassTag.Nothing } + val Null : ClassTag[scala.Null] = new ClassTag[scala.Null](ObjectTYPE) { private def readResolve() = ClassTag.Null } + val String : ClassTag[java.lang.String] = new ClassTag[java.lang.String](StringTYPE) { private def readResolve() = ClassTag.String } + + def apply[T](clazz: jClass[_]): ClassTag[T] = + clazz match { + case java.lang.Byte.TYPE => ClassTag.Byte.asInstanceOf[ClassTag[T]] + case java.lang.Short.TYPE => ClassTag.Short.asInstanceOf[ClassTag[T]] + case java.lang.Character.TYPE => ClassTag.Char.asInstanceOf[ClassTag[T]] + case java.lang.Integer.TYPE => ClassTag.Int.asInstanceOf[ClassTag[T]] + case java.lang.Long.TYPE => ClassTag.Long.asInstanceOf[ClassTag[T]] + case java.lang.Float.TYPE => ClassTag.Float.asInstanceOf[ClassTag[T]] + case java.lang.Double.TYPE => ClassTag.Double.asInstanceOf[ClassTag[T]] + case java.lang.Boolean.TYPE => ClassTag.Boolean.asInstanceOf[ClassTag[T]] + case java.lang.Void.TYPE => ClassTag.Unit.asInstanceOf[ClassTag[T]] + case ObjectTYPE => ClassTag.Object.asInstanceOf[ClassTag[T]] + case StringTYPE => ClassTag.String.asInstanceOf[ClassTag[T]] + case _ => new ClassTag[T](clazz) {} + } + + def apply[T](tpe: rm.Type): ClassTag[T] = + tpe match { + case rm.ByteTpe => ClassTag.Byte.asInstanceOf[ClassTag[T]] + case rm.ShortTpe => ClassTag.Short.asInstanceOf[ClassTag[T]] + case rm.CharTpe => ClassTag.Char.asInstanceOf[ClassTag[T]] + case rm.IntTpe => ClassTag.Int.asInstanceOf[ClassTag[T]] + case rm.LongTpe => ClassTag.Long.asInstanceOf[ClassTag[T]] + case rm.FloatTpe => ClassTag.Float.asInstanceOf[ClassTag[T]] + case rm.DoubleTpe => ClassTag.Double.asInstanceOf[ClassTag[T]] + case rm.BooleanTpe => ClassTag.Boolean.asInstanceOf[ClassTag[T]] + case rm.UnitTpe => ClassTag.Unit.asInstanceOf[ClassTag[T]] + case rm.AnyTpe => ClassTag.Any.asInstanceOf[ClassTag[T]] + case rm.ObjectTpe => ClassTag.Object.asInstanceOf[ClassTag[T]] + case rm.AnyValTpe => ClassTag.AnyVal.asInstanceOf[ClassTag[T]] + case rm.AnyRefTpe => ClassTag.AnyRef.asInstanceOf[ClassTag[T]] + case rm.NothingTpe => ClassTag.Nothing.asInstanceOf[ClassTag[T]] + case rm.NullTpe => ClassTag.Null.asInstanceOf[ClassTag[T]] + case rm.StringTpe => ClassTag.String.asInstanceOf[ClassTag[T]] + case _ => apply[T](rm.typeToClass(tpe.erasure)) + } + + implicit def toDeprecatedClassManifestApis[T](ctag: ClassTag[T]): DeprecatedClassManifestApis[T] = new DeprecatedClassManifestApis[T](ctag) +} + +// this class should not be used directly in client code +class DeprecatedClassManifestApis[T](ctag: ClassTag[T]) { + import scala.collection.mutable.{ WrappedArray, ArrayBuilder } + + @deprecated("Use `tpe` to analyze the underlying type", "2.10.0") + def <:<(that: ClassManifest[_]): Boolean = ctag.tpe <:< that.tpe + + @deprecated("Use `tpe` to analyze the underlying type", "2.10.0") + def >:>(that: ClassManifest[_]): Boolean = that <:< ctag + + @deprecated("Use `wrap` instead", "2.10.0") + def arrayManifest: ClassManifest[Array[T]] = ctag.wrap + + @deprecated("Use a combination of `wrap` and `newArray` instead", "2.10.0") + def newArray2(len: Int): Array[Array[T]] = ctag.wrap.newArray(len) + + @deprecated("Use a combination of `wrap` and `newArray` instead", "2.10.0") + def newArray3(len: Int): Array[Array[Array[T]]] = ctag.wrap.wrap.newArray(len) + + @deprecated("Use a combination of `wrap` and `newArray` instead", "2.10.0") + def newArray4(len: Int): Array[Array[Array[Array[T]]]] = ctag.wrap.wrap.wrap.newArray(len) + + @deprecated("Use a combination of `wrap` and `newArray` instead", "2.10.0") + def newArray5(len: Int): Array[Array[Array[Array[Array[T]]]]] = ctag.wrap.wrap.wrap.wrap.newArray(len) + + @deprecated("Use `@scala.collection.mutable.WrappedArray` object instead", "2.10.0") + def newWrappedArray(len: Int): WrappedArray[T] = + ctag.erasure match { + case java.lang.Byte.TYPE => new WrappedArray.ofByte(new Array[Byte](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Short.TYPE => new WrappedArray.ofShort(new Array[Short](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Character.TYPE => new WrappedArray.ofChar(new Array[Char](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Integer.TYPE => new WrappedArray.ofInt(new Array[Int](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Long.TYPE => new WrappedArray.ofLong(new Array[Long](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Float.TYPE => new WrappedArray.ofFloat(new Array[Float](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Double.TYPE => new WrappedArray.ofDouble(new Array[Double](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Boolean.TYPE => new WrappedArray.ofBoolean(new Array[Boolean](len)).asInstanceOf[WrappedArray[T]] + case java.lang.Void.TYPE => new WrappedArray.ofUnit(new Array[Unit](len)).asInstanceOf[WrappedArray[T]] + case _ => new WrappedArray.ofRef[T with AnyRef](ctag.newArray(len).asInstanceOf[Array[T with AnyRef]]).asInstanceOf[WrappedArray[T]] + } + + @deprecated("Use `@scala.collection.mutable.ArrayBuilder` object instead", "2.10.0") + def newArrayBuilder(): ArrayBuilder[T] = ArrayBuilder.make[T]()(ctag) + + @deprecated("`typeArguments` is no longer supported, and will always return an empty list. Use `@scala.reflect.TypeTag` or `@scala.reflect.ConcreteTypeTag` to capture and analyze type arguments", "2.10.0") + def typeArguments: List[OptManifest[_]] = List() +} diff --git a/src/library/scala/reflect/DynamicProxy.scala b/src/library/scala/reflect/DynamicProxy.scala new file mode 100644 index 0000000000..ffd1e7a39f --- /dev/null +++ b/src/library/scala/reflect/DynamicProxy.scala @@ -0,0 +1,74 @@ +package scala.reflect +/** + * A dynamic proxy which redirects method calls and attribute access to a given + * target object at runtime using reflection. + * + * Usage example: + * + * object x{ def hello = "hello world" } + * val d = new DynamicProxy{ val dynamicProxyTarget = x } + * assert( d.hello == "hello world" ) + * + * Not supported (yet): + * - implicit conversions and parameters + * - multiple arguments lists + * - explicit type arguments + */ +trait DynamicProxy extends Dynamic{ + /** Method calls on DynamicProxy are redirected to this object. Needs to be defined in a subclass. */ + val dynamicProxyTarget : AnyRef + + import scala.reflect.mirror._ + /** + * boxing to preserve information on primitive types for overloading resolution + */ + case class DynamicReflectBoxed( class_ : Class[_], value: Any ) + object DynamicReflectBoxed{ + implicit def box[@specialized T]( v:T ) = DynamicReflectBoxed( v.getClass, v ) + } + + def selectDynamic( method:String ) = { + val symbol = classToType( dynamicProxyTarget.getClass ).member( newTermName(method).encodedName ) + invoke( dynamicProxyTarget, symbol )() + } + + def updateDynamic( method:String )( value : Any ) = { + val symbol = classToType( dynamicProxyTarget.getClass ).member( newTermName(method+"_=").encodedName ) + invoke( dynamicProxyTarget, symbol )( value ) + } + + def applyDynamic( method:String )( args:DynamicReflectBoxed* ) : Any + = applyDynamicNamed( method )( args.map( value => ("",value) ) :_* ) + + def applyDynamicNamed( method:String )( args:(String,DynamicReflectBoxed)* ) : Any = { + val class_ = dynamicProxyTarget.getClass + var i = 0 + val toolbox = mkToolBox(mkConsoleReporter(),"") + val symbol = classToType( dynamicProxyTarget.getClass ).member( newTermName(method).encodedName ) + if(args.size == 0){ + invoke( dynamicProxyTarget, symbol )() + } else { + val call = + Apply( + Select( + TypeApply( + Select( + Select( + Ident(newFreeTerm("__this", symbolForName("scala.reflect.DynamicProxy").asType, this, null)) + , newTermName("dynamicProxyTarget") + ), + newTermName("asInstanceOf") ) + , List(TypeTree().setType(classToType(class_))) + ) + ,newTermName(method).encodedName + ) + ,args.map{ case(name,box) => + val value = Ident(newFreeTerm("__arg"+({i+=1;i}.toString), classToType(box.class_), box.value, null)) + if( name == "" ) value + else AssignOrNamedArg( Ident(name), value ) + }.toList + ) + toolbox.runExpr( call ) + } + } +} diff --git a/src/library/scala/reflect/Manifest.scala b/src/library/scala/reflect/Manifest.scala deleted file mode 100644 index e5df487be9..0000000000 --- a/src/library/scala/reflect/Manifest.scala +++ /dev/null @@ -1,302 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.reflect - -import scala.collection.mutable.{ ArrayBuilder, WrappedArray } -import mirror._ - -/** A `Manifest[T]` is an opaque descriptor for type T. Its supported use - * is to give access to the erasure of the type as a `Class` instance, as - * is necessary for the creation of native `Arrays` if the class is not - * known at compile time. - * - * The type-relation operators `<:<` and `=:=` should be considered - * approximations only, as there are numerous aspects of type conformance - * which are not yet adequately represented in manifests. - * - * Example usages: -{{{ - def arr[T] = new Array[T](0) // does not compile - def arr[T](implicit m: Manifest[T]) = new Array[T](0) // compiles - def arr[T: Manifest] = new Array[T](0) // shorthand for the preceding - - // Methods manifest, classManifest, and optManifest are in [[scala.Predef]]. - def isApproxSubType[T: Manifest, U: Manifest] = manifest[T] <:< manifest[U] - isApproxSubType[List[String], List[AnyRef]] // true - isApproxSubType[List[String], List[Int]] // false - - def methods[T: ClassManifest] = classManifest[T].erasure.getMethods - def retType[T: ClassManifest](name: String) = - methods[T] find (_.getName == name) map (_.getGenericReturnType) - - retType[Map[_, _]]("values") // Some(scala.collection.Iterable<B>) -}}} - * - */ -@annotation.implicitNotFound(msg = "No Manifest available for ${T}.") -trait Manifest[T] extends ClassManifest[T] with Equals { - override def typeArguments: List[Manifest[_]] = Nil - - override def arrayManifest: Manifest[Array[T]] = - Manifest.classType[Array[T]](arrayClass[T](erasure), this) - - override def canEqual(that: Any): Boolean = that match { - case _: Manifest[_] => true - case _ => false - } - /** Note: testing for erasure here is important, as it is many times - * faster than <:< and rules out most comparisons. - */ - override def equals(that: Any): Boolean = that match { - case m: Manifest[_] => (m canEqual this) && (this.erasure == m.erasure) && (this <:< m) && (m <:< this) - case _ => false - } - override def hashCode = this.erasure.## -} - -abstract class AnyValManifest[T <: AnyVal](override val toString: String) extends Manifest[T] with Equals { - override def <:<(that: ClassManifest[_]): Boolean = - (that eq this) || (that eq Manifest.Any) || (that eq Manifest.AnyVal) - override def canEqual(other: Any) = other match { - case _: AnyValManifest[_] => true - case _ => false - } - override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef] - override val hashCode = System.identityHashCode(this) -} - -/** The object `Manifest` defines factory methods for manifests. - * It is intended for use by the compiler and should not be used - * in client code. - */ -object Manifest { - import mirror.{ definitions => mdefs } - - def valueManifests: List[AnyValManifest[_]] = - List(Byte, Short, Char, Int, Long, Float, Double, Boolean, Unit) - - val Byte: AnyValManifest[Byte] = new AnyValManifest[scala.Byte]("Byte") { - def erasure = java.lang.Byte.TYPE - override def newArray(len: Int): Array[Byte] = new Array[Byte](len) - override def newWrappedArray(len: Int): WrappedArray[Byte] = new WrappedArray.ofByte(new Array[Byte](len)) - override def newArrayBuilder(): ArrayBuilder[Byte] = new ArrayBuilder.ofByte() - private def readResolve(): Any = Manifest.Byte - } - - val Short: AnyValManifest[Short] = new AnyValManifest[scala.Short]("Short") { - def erasure = java.lang.Short.TYPE - override def newArray(len: Int): Array[Short] = new Array[Short](len) - override def newWrappedArray(len: Int): WrappedArray[Short] = new WrappedArray.ofShort(new Array[Short](len)) - override def newArrayBuilder(): ArrayBuilder[Short] = new ArrayBuilder.ofShort() - private def readResolve(): Any = Manifest.Short - } - - val Char: AnyValManifest[Char] = new AnyValManifest[scala.Char]("Char") { - def erasure = java.lang.Character.TYPE - override def newArray(len: Int): Array[Char] = new Array[Char](len) - override def newWrappedArray(len: Int): WrappedArray[Char] = new WrappedArray.ofChar(new Array[Char](len)) - override def newArrayBuilder(): ArrayBuilder[Char] = new ArrayBuilder.ofChar() - private def readResolve(): Any = Manifest.Char - } - - val Int: AnyValManifest[Int] = new AnyValManifest[scala.Int]("Int") { - def erasure = java.lang.Integer.TYPE - override def newArray(len: Int): Array[Int] = new Array[Int](len) - override def newWrappedArray(len: Int): WrappedArray[Int] = new WrappedArray.ofInt(new Array[Int](len)) - override def newArrayBuilder(): ArrayBuilder[Int] = new ArrayBuilder.ofInt() - private def readResolve(): Any = Manifest.Int - } - - val Long: AnyValManifest[Long] = new AnyValManifest[scala.Long]("Long") { - def erasure = java.lang.Long.TYPE - override def newArray(len: Int): Array[Long] = new Array[Long](len) - override def newWrappedArray(len: Int): WrappedArray[Long] = new WrappedArray.ofLong(new Array[Long](len)) - override def newArrayBuilder(): ArrayBuilder[Long] = new ArrayBuilder.ofLong() - private def readResolve(): Any = Manifest.Long - } - - val Float: AnyValManifest[Float] = new AnyValManifest[scala.Float]("Float") { - def erasure = java.lang.Float.TYPE - override def newArray(len: Int): Array[Float] = new Array[Float](len) - override def newWrappedArray(len: Int): WrappedArray[Float] = new WrappedArray.ofFloat(new Array[Float](len)) - override def newArrayBuilder(): ArrayBuilder[Float] = new ArrayBuilder.ofFloat() - private def readResolve(): Any = Manifest.Float - } - - val Double: AnyValManifest[Double] = new AnyValManifest[scala.Double]("Double") { - def erasure = java.lang.Double.TYPE - override def newArray(len: Int): Array[Double] = new Array[Double](len) - override def newWrappedArray(len: Int): WrappedArray[Double] = new WrappedArray.ofDouble(new Array[Double](len)) - override def newArrayBuilder(): ArrayBuilder[Double] = new ArrayBuilder.ofDouble() - private def readResolve(): Any = Manifest.Double - } - - val Boolean: AnyValManifest[Boolean] = new AnyValManifest[scala.Boolean]("Boolean") { - def erasure = java.lang.Boolean.TYPE - override def newArray(len: Int): Array[Boolean] = new Array[Boolean](len) - override def newWrappedArray(len: Int): WrappedArray[Boolean] = new WrappedArray.ofBoolean(new Array[Boolean](len)) - override def newArrayBuilder(): ArrayBuilder[Boolean] = new ArrayBuilder.ofBoolean() - private def readResolve(): Any = Manifest.Boolean - } - - val Unit: AnyValManifest[Unit] = new AnyValManifest[scala.Unit]("Unit") { - def erasure = java.lang.Void.TYPE - override def newArray(len: Int): Array[Unit] = new Array[Unit](len) - override def newWrappedArray(len: Int): WrappedArray[Unit] = new WrappedArray.ofUnit(new Array[Unit](len)) - override def newArrayBuilder(): ArrayBuilder[Unit] = new ArrayBuilder.ofUnit() - private def readResolve(): Any = Manifest.Unit - } - - val Any: Manifest[scala.Any] = new PhantomManifest[scala.Any]("Any") { - override def symbol = mdefs.AnyClass - override def <:<(that: ClassManifest[_]): Boolean = (that eq this) - private def readResolve(): Any = Manifest.Any - } - - val Object: Manifest[java.lang.Object] = new PhantomManifest[java.lang.Object]("Object") { - override def symbol = mdefs.ObjectClass - override def <:<(that: ClassManifest[_]): Boolean = (that eq this) || (that eq Any) - private def readResolve(): Any = Manifest.Object - } - - val AnyVal: Manifest[scala.AnyVal] = new PhantomManifest[scala.AnyVal]("AnyVal") { - override def symbol = mdefs.AnyValClass - override def <:<(that: ClassManifest[_]): Boolean = (that eq this) || (that eq Any) - private def readResolve(): Any = Manifest.AnyVal - } - - val Null: Manifest[scala.Null] = new PhantomManifest[scala.Null]("Null") { - override def symbol = mdefs.NullClass - override def <:<(that: ClassManifest[_]): Boolean = - (that ne null) && (that ne Nothing) && !(that <:< AnyVal) - private def readResolve(): Any = Manifest.Null - } - - val Nothing: Manifest[scala.Nothing] = new PhantomManifest[scala.Nothing]("Nothing") { - override def symbol = mdefs.NothingClass - override def <:<(that: ClassManifest[_]): Boolean = (that ne null) - private def readResolve(): Any = Manifest.Nothing - } - - private class SingletonTypeManifest[T <: AnyRef](value: AnyRef) extends Manifest[T] { - lazy val erasure = value.getClass - override lazy val symbol = InstanceRefSymbol(value) // todo: change to freevar - override lazy val tpe = mirror.SingleType(mirror.NoPrefix, symbol) - override lazy val toString = value.toString + ".type" - } - - /** Manifest for the singleton type `value.type`. */ - def singleType[T <: AnyRef](value: AnyRef): Manifest[T] = - new SingletonTypeManifest[T](value) - - /** Manifest for the class type `clazz[args]`, where `clazz` is - * a top-level or static class. - * @note This no-prefix, no-arguments case is separate because we - * it's called from ScalaRunTime.boxArray itself. If we - * pass varargs as arrays into this, we get an infinitely recursive call - * to boxArray. (Besides, having a separate case is more efficient) - */ - def classType[T](clazz: Predef.Class[_]): Manifest[T] = - new ClassTypeManifest[T](None, clazz, Nil) - - /** Manifest for the class type `clazz`, where `clazz` is - * a top-level or static class and args are its type arguments. */ - def classType[T](clazz: Predef.Class[T], arg1: Manifest[_], args: Manifest[_]*): Manifest[T] = - new ClassTypeManifest[T](None, clazz, arg1 :: args.toList) - - /** Manifest for the class type `clazz[args]`, where `clazz` is - * a class with non-package prefix type `prefix` and type arguments `args`. - */ - def classType[T](prefix: Manifest[_], clazz: Predef.Class[_], args: Manifest[_]*): Manifest[T] = - new ClassTypeManifest[T](Some(prefix), clazz, args.toList) - - /** Phantom types have no runtime representation; they all erase to Object, - * but the Symbol preserves their identity. - */ - private abstract class PhantomManifest[T](override val toString: String) extends ClassTypeManifest[T](None, classOf[java.lang.Object], Nil) { - override lazy val tpe = namedType(mirror.NoPrefix, symbol, Nil) - override def equals(that: Any) = this eq that.asInstanceOf[AnyRef] - override val hashCode = System.identityHashCode(this) - } - - /** Manifest for the class type `clazz[args]`, where `clazz` is - * a top-level or static class. */ - private class ClassTypeManifest[T](prefix: Option[Manifest[_]], - val erasure: Predef.Class[_], - override val typeArguments: List[Manifest[_]]) extends Manifest[T] { - - override lazy val tpe = { - val pre = prefix match { - case Some(pm) => pm.tpe - case None => symbol.owner.thisPrefix - } - namedType(pre, symbol, typeArguments map (_.tpe)) - } - - override def toString = - (if (prefix.isEmpty) "" else prefix.get.toString+"#") + - (if (erasure.isArray) "Array" else erasure.getName) + - argString - } - - def arrayType[T](arg: Manifest[_]): Manifest[Array[T]] = - arg.asInstanceOf[Manifest[T]].arrayManifest - - /** Manifest 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: Manifest[_], name: String, upperBound: Predef.Class[_], args: Manifest[_]*): Manifest[T] = - new Manifest[T] { - def erasure = upperBound - override lazy val tpe = namedType(prefix.tpe, prefix.tpe.member(newTypeName(name)), args map (_.tpe) toList) - override val typeArguments = args.toList - override def toString = prefix.toString+"#"+name+argString - } - - /** Manifest for the unknown type `_ >: L <: U` in an existential. - */ - def wildcardType[T](lowerBound: Manifest[_], upperBound: Manifest[_]): Manifest[T] = - new Manifest[T] { - def erasure = upperBound.erasure - override lazy val tpe = mirror.TypeBounds(lowerBound.tpe, upperBound.tpe) - override def toString = - "_" + - (if (lowerBound eq Nothing) "" else " >: "+lowerBound) + - (if (upperBound eq Nothing) "" else " <: "+upperBound) - } - - /** Manifest for the intersection type `parents_0 with ... with parents_n'. */ - def intersectionType[T](parents: Manifest[_]*): Manifest[T] = - new Manifest[T] { - def erasure = parents.head.erasure - override lazy val tpe = mirror.RefinedType((parents map (_.tpe)).toList, newScope) - override def toString = parents.mkString(" with ") - } - - /** A generic manifest factory from a reflect.Type. Except where - * mandated by performance considerations, we should replace most - * other manifest factories by this one. There's just one thing - * that needs to be done first: A Manifest's type can refer - * to type variables that are controlled by manifests. In that - * case the reified type needs to contain the type passed in the manifest - * instead of the reference to the manifest. Note that splicing manifests - * into manfifests is completely analogous to splicing code blocks into - * code blocks. Manifest[T] and Code[T] are really the same thing, only one - * works for types, the other for trees. - * Another complication is that once we generate manifests from types, we really - * should have reflection as a standard component shipped with the standard library, - * instead of in scala-compiler.jar. - */ - def apply[T](_tpe: mirror.Type): Manifest[T] = new Manifest[T] { - override def symbol = _tpe.typeSymbol - override lazy val tpe = _tpe - override def erasure = mirror.typeToClass(_tpe.erasedType) - override def toString = _tpe.toString - } -} diff --git a/src/library/scala/reflect/ReflectionUtils.scala b/src/library/scala/reflect/ReflectionUtils.scala index 510f0819c6..1be46eac55 100644 --- a/src/library/scala/reflect/ReflectionUtils.scala +++ b/src/library/scala/reflect/ReflectionUtils.scala @@ -27,7 +27,17 @@ object ReflectionUtils { case ex if pf isDefinedAt unwrapThrowable(ex) => pf(unwrapThrowable(ex)) } - def singletonInstance(className: String, cl: ClassLoader = getClass.getClassLoader): AnyRef = { + def defaultReflectionClassLoader() = { + // say no to non-determinism of mirror classloaders + // default classloader will be instantiated using current system classloader + // if you wish so, you can rebind it by setting ``mirror.classLoader'' to whatever is necessary +// val cl = Thread.currentThread.getContextClassLoader +// if (cl == null) getClass.getClassLoader else cl +// cl + getClass.getClassLoader + } + + def singletonInstance(cl: ClassLoader, className: String): AnyRef = { val name = if (className endsWith "$") className else className + "$" val clazz = java.lang.Class.forName(name, true, cl) val singleton = clazz getField "MODULE$" get null @@ -35,7 +45,17 @@ object ReflectionUtils { } // Retrieves the MODULE$ field for the given class name. - def singletonInstanceOpt(className: String, cl: ClassLoader = getClass.getClassLoader): Option[AnyRef] = - try Some(singletonInstance(className, cl)) + def singletonInstanceOpt(cl: ClassLoader, className: String): Option[AnyRef] = + try Some(singletonInstance(cl, className)) + catch { case _: ClassNotFoundException => None } + + def invokeFactory(cl: ClassLoader, className: String, methodName: String, args: AnyRef*): AnyRef = { + val singleton = singletonInstance(cl, className) + val method = singleton.getClass.getMethod(methodName, classOf[ClassLoader]) + method.invoke(singleton, args: _*) + } + + def invokeFactoryOpt(cl: ClassLoader, className: String, methodName: String, args: AnyRef*): Option[AnyRef] = + try Some(invokeFactory(cl, className, methodName, args: _*)) catch { case _: ClassNotFoundException => None } } diff --git a/src/library/scala/reflect/TagMaterialization.scala b/src/library/scala/reflect/TagMaterialization.scala new file mode 100644 index 0000000000..aede00020f --- /dev/null +++ b/src/library/scala/reflect/TagMaterialization.scala @@ -0,0 +1,155 @@ +package scala.reflect + +import api.Universe +import makro.Context +import language.implicitConversions + +// todo. unfortunately, current type inferencer doesn't infer type parameters of implicit values +// this means that during macro expansion these macros will get Nothing instead of real T +// Oh how much I'd love to implement this now, but I have to postpone this until we have a solution for type inference + +/** This object is required by the compiler and <b>should not be used in client code</b>. */ +object TagMaterialization { + def materializeClassTag[T: c.TypeTag](c: Context): c.Expr[ClassTag[T]] = { + import c.mirror._ + val tpe = implicitly[c.TypeTag[T]].tpe + c.materializeClassTag(tpe) + } + + def materializeTypeTag[T: c.TypeTag](c: Context { type PrefixType = Universe }): c.Expr[c.prefix.value.TypeTag[T]] = { + import c.mirror._ + val tpe = implicitly[c.TypeTag[T]].tpe + c.materializeTypeTag(tpe, requireConcreteTypeTag = false) + } + + def materializeConcreteTypeTag[T: c.TypeTag](c: Context { type PrefixType = Universe }): c.Expr[c.prefix.value.ConcreteTypeTag[T]] = { + import c.mirror._ + val tpe = implicitly[c.TypeTag[T]].tpe + c.materializeTypeTag(tpe, requireConcreteTypeTag = true) + } + + private implicit def context2utils(c0: Context) : Utils { val c: c0.type } = new { val c: c0.type = c0 } with Utils + + private abstract class Utils { + val c: Context + + import c.mirror._ + import definitions._ + + val coreTags = Map( + ByteClass.asType -> newTermName("Byte"), + ShortClass.asType -> newTermName("Short"), + CharClass.asType -> newTermName("Char"), + IntClass.asType -> newTermName("Int"), + LongClass.asType -> newTermName("Long"), + FloatClass.asType -> newTermName("Float"), + DoubleClass.asType -> newTermName("Double"), + BooleanClass.asType -> newTermName("Boolean"), + UnitClass.asType -> newTermName("Unit"), + AnyClass.asType -> newTermName("Any"), + ObjectClass.asType -> newTermName("Object"), + AnyValClass.asType -> newTermName("AnyVal"), + AnyRefClass.asType -> newTermName("AnyRef"), + NothingClass.asType -> newTermName("Nothing"), + NullClass.asType -> newTermName("Null")) + + val ReflectPackage = staticModule("scala.reflect.package") + val Reflect_mirror = selectTerm(ReflectPackage, "mirror") + val ClassTagClass = staticClass("scala.reflect.ClassTag") + val ClassTagErasure = selectTerm(ClassTagClass, "erasure") + val ClassTagModule = staticModule("scala.reflect.ClassTag") + val TypeTagsClass = staticClass("scala.reflect.api.TypeTags") + val TypeTagClass = selectType(TypeTagsClass, "TypeTag") + val TypeTagTpe = selectTerm(TypeTagClass, "tpe") + val TypeTagModule = selectTerm(TypeTagsClass, "TypeTag") + val ConcreteTypeTagClass = selectType(TypeTagsClass, "ConcreteTypeTag") + val ConcreteTypeTagModule = selectTerm(TypeTagsClass, "ConcreteTypeTag") + + def materializeClassTag(tpe: Type): Tree = { + val prefix = gen.mkAttributedRef(Reflect_mirror) setType singleType(Reflect_mirror.owner.thisPrefix, Reflect_mirror) + materializeClassTag(prefix, tpe) + } + + def materializeClassTag(prefix: Tree, tpe: Type): Tree = { + val typetagInScope = c.inferImplicitValue(appliedType(typeRef(prefix.tpe, ConcreteTypeTagClass, Nil), List(tpe))) + def typetagIsSynthetic(tree: Tree) = tree.isInstanceOf[Block] || (tree exists (sub => sub.symbol == TypeTagModule || sub.symbol == ConcreteTypeTagModule)) + typetagInScope match { + case success if !success.isEmpty && !typetagIsSynthetic(success) => + val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe))) + Apply(factory, List(Select(typetagInScope, newTermName("tpe")))) + case _ => + val result = + tpe match { + case coreTpe if coreTags contains coreTpe => + Select(Ident(ClassTagModule), coreTags(coreTpe)) + case _ => + if (tpe.typeSymbol == ArrayClass) { + val componentTpe = tpe.typeArguments(0) + val classtagInScope = c.inferImplicitValue(appliedType(typeRef(NoPrefix, ClassTagClass, Nil), List(componentTpe))) + val componentTag = classtagInScope orElse materializeClassTag(prefix, componentTpe) + Select(componentTag, newTermName("wrap")) + } else { + // [Eugene] what's the intended behavior? there's no spec on ClassManifests + // for example, should we ban Array[T] or should we tag them with Array[AnyRef]? + // if its the latter, what should be the result of tagging Array[T] where T <: Int? + if (tpe.typeSymbol.isAbstractType) fail("tpe is an abstract type") + val erasure = + if (tpe.typeSymbol.isDerivedValueClass) tpe // [Eugene to Martin] is this correct? + else tpe.erasure.normalize // necessary to deal with erasures of HK types + val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe))) + Apply(factory, List(TypeApply(Ident(newTermName("classOf")), List(TypeTree(erasure))))) + } + } + try c.typeCheck(result) + catch { case terr @ c.TypeError(pos, msg) => fail(terr) } + } + } + + def materializeTypeTag(tpe: Type, requireConcreteTypeTag: Boolean): Tree = { + def prefix: Tree = ??? // todo. needs to be synthesized from c.prefix + materializeTypeTag(prefix, tpe, requireConcreteTypeTag) + } + + def materializeTypeTag(prefix: Tree, tpe: Type, requireConcreteTypeTag: Boolean): Tree = { + val tagModule = if (requireConcreteTypeTag) ConcreteTypeTagModule else TypeTagModule + val result = + tpe match { + case coreTpe if coreTags contains coreTpe => + Select(Select(prefix, tagModule.name), coreTags(coreTpe)) + case _ => + try c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireConcreteTypeTag = requireConcreteTypeTag) + catch { + case ex: Throwable => + // [Eugene] cannot pattern match on an abstract type, so had to do this + val ex1 = ex + if (ex.getClass.toString.endsWith("$ReificationError")) { + ex match { + case c.ReificationError(pos, msg) => + c.error(pos, msg) + EmptyTree + } + } else if (ex.getClass.toString.endsWith("$UnexpectedReificationError")) { + ex match { + case c.UnexpectedReificationError(pos, err, cause) => + if (cause != null) throw cause else throw ex + } + } else { + throw ex + } + } + } + try c.typeCheck(result) + catch { case terr @ c.TypeError(pos, msg) => fail(terr) } + } + + private def fail(reason: Any): Nothing = { + val Apply(TypeApply(fun, List(tpeTree)), _) = c.macroApplication + val tpe = tpeTree.tpe + val PolyType(_, MethodType(_, tagTpe)) = fun.tpe + val tagModule = tagTpe.typeSymbol.companionSymbol + if (c.compilerSettings.contains("-Xlog-implicits")) + c.echo(c.enclosingPosition, "cannot materialize " + tagModule.name + "[" + tpe + "] because:\n" + reason) + c.abort(c.enclosingPosition, "No %s available for %s".format(tagModule.name, tpe)) + } + } +} diff --git a/src/library/scala/reflect/api/Attachment.scala b/src/library/scala/reflect/api/Attachment.scala new file mode 100644 index 0000000000..dfd362ebe0 --- /dev/null +++ b/src/library/scala/reflect/api/Attachment.scala @@ -0,0 +1,16 @@ +package scala.reflect +package api + +/** Attachment is a generalisation of Position. + * Typically it stores a Position of a tree, but this can be extended to encompass arbitrary payloads. + * + * Attachments have to carry positions, because we don't want to introduce even a single additional field in Tree + * imposing an unnecessary memory tax because of something that will not be used in most cases. + */ +trait Attachment { + /** Gets the underlying position */ + def pos: Position + + /** Creates a copy of this attachment with its position updated */ + def withPos(pos: Position): Attachment +} diff --git a/src/library/scala/reflect/api/ClassLoaders.scala b/src/library/scala/reflect/api/ClassLoaders.scala new file mode 100644 index 0000000000..7be402d3df --- /dev/null +++ b/src/library/scala/reflect/api/ClassLoaders.scala @@ -0,0 +1,16 @@ +package scala.reflect +package api + +trait ClassLoaders { self: Universe => + + /** The symbol corresponding to the globally accessible class with the + * given fully qualified name `fullName`. + */ + def staticClass(fullName: String): Symbol + + /** The symbol corresponding to the globally accessible object with the + * given fully qualified name `fullName`. + */ + def staticModule(fullName: String): Symbol + +}
\ No newline at end of file diff --git a/src/library/scala/reflect/api/Exprs.scala b/src/library/scala/reflect/api/Exprs.scala new file mode 100644 index 0000000000..ff89a1cd48 --- /dev/null +++ b/src/library/scala/reflect/api/Exprs.scala @@ -0,0 +1,51 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2011 LAMP/EPFL + * @author Martin Odersky + */ + +package scala.reflect +package api +import language.implicitConversions + +trait Exprs { self: Universe => + + /** An expression tree tagged with its type */ + case class Expr[+T: TypeTag](tree: Tree) { + def tpe: Type = implicitly[TypeTag[T]].tpe + def eval: T = mkToolBox().runExpr(tree).asInstanceOf[T] + lazy val value: T = eval + override def toString = "Expr["+tpe+"]("+tree+")" + } + + // [Eugene] had to move this to the companion of Tree to make stuff compile. weirdo! +// object Expr { +// // would be great if in future this generated an Expr[Magic] +// // where Magic is a magic untyped type that propagates through the entire quasiquote +// // and turns off typechecking whenever it's involved +// // that'd allow us to splice trees into quasiquotes and still have these qqs to be partially typechecked +// // see some exploration of these ideas here: https://github.com/xeno-by/alphakeplerdemo +// implicit def tree2expr(tree: Tree): Expr[Nothing] = Expr[Nothing](tree) +// implicit def expr2tree(expr: Expr[_]): Tree = expr.tree +// +// // [Eugene] good idea? +// implicit def trees2exprs(trees: List[Tree]): List[Expr[Nothing]] = trees map tree2expr +// implicit def exprs2trees(exprs: List[Expr[_]]): List[Tree] = exprs map expr2tree +// } + + // [Eugene] even weirder - implicits didn't feel at home in Trees :( + + // would be great if in future this generated an Expr[Magic] + // where Magic is a magic untyped type that propagates through the entire quasiquote + // and turns off typechecking whenever it's involved + // that'd allow us to splice trees into quasiquotes and still have these qqs to be partially typechecked + // see some exploration of these ideas here: https://github.com/xeno-by/alphakeplerdemo + // [Martin] I have some doubts whether it's god to have implicit conversions. + implicit def tree2expr(tree: Tree): Expr[Nothing] = Expr[Nothing](tree)(TypeTag.Nothing) + implicit def expr2tree(expr: Expr[_]): Tree = expr.tree + + // [Eugene] good idea? + // [Martin] probably not. + implicit def trees2exprs(trees: List[Tree]): List[Expr[Nothing]] = trees map tree2expr + implicit def exprs2trees(exprs: List[Expr[_]]): List[Tree] = exprs map expr2tree +} + diff --git a/src/library/scala/reflect/api/FreeVars.scala b/src/library/scala/reflect/api/FreeVars.scala new file mode 100644 index 0000000000..0bef099a55 --- /dev/null +++ b/src/library/scala/reflect/api/FreeVars.scala @@ -0,0 +1,42 @@ +package scala.reflect +package api + +trait FreeVars { + self: Universe => + + /** Represents a free term captured by reification. + */ + type FreeTerm <: Symbol + + val FreeTerm: FreeTermExtractor + + abstract class FreeTermExtractor { + def unapply(freeTerm: FreeTerm): Option[(TermName, Type, Any, String)] + } + + /** Extracts free terms from a tree that is reified or contains reified subtrees. + */ + def freeTerms(tree: Tree): List[FreeTerm] + + /** Represents a free type captured by reification. + */ + type FreeType <: Symbol + + val FreeType: FreeTypeExtractor + + abstract class FreeTypeExtractor { + def unapply(freeType: FreeType): Option[(TypeName, Type, String)] + } + + /** Extracts free types from a tree that is reified or contains reified subtrees. + */ + def freeTypes(tree: Tree): List[FreeType] + + /** Substitutes free types in a reified tree. + */ + def substituteFreeTypes(tree: Tree, subs: Map[FreeType, Type]): Tree + + /** Substitutes free types in a reified type. + */ + def substituteFreeTypes(tpe: Type, subs: Map[FreeType, Type]): Type +} diff --git a/src/library/scala/reflect/api/Importers.scala b/src/library/scala/reflect/api/Importers.scala new file mode 100644 index 0000000000..1d8890b7db --- /dev/null +++ b/src/library/scala/reflect/api/Importers.scala @@ -0,0 +1,19 @@ +package scala.reflect +package api + +trait Importers { self: Universe => + + def mkImporter(from0: Universe): Importer { val from: from0.type } + + trait Importer { + val from: Universe + + val reverse: from.Importer { val from: self.type } + + def importSymbol(sym: from.Symbol): Symbol + + def importType(tpe: from.Type): Type + + def importTree(tree: from.Tree): Tree + } +}
\ No newline at end of file diff --git a/src/library/scala/reflect/api/Mirror.scala b/src/library/scala/reflect/api/Mirror.scala index cea9e1a37d..ed8ead7aaf 100644 --- a/src/library/scala/reflect/api/Mirror.scala +++ b/src/library/scala/reflect/api/Mirror.scala @@ -5,7 +5,22 @@ package api * runtime entities such as class names and object instances * with a reflexive universe. */ -trait Mirror extends Universe with RuntimeTypes with TreeBuildUtil { +trait Mirror extends Universe { + + /** Class loader that is a mastermind behind the reflexive mirror. + * + * By default it is set to system classloader (more precisely, to the classloader that loads the `scala.reflect.package` class). + * However, sometimes it is useful to have a mirror services by a custom classloader. + * + * There are two ways to customize the `classLoader`: + * 1) Create a new mirror using the `scala.reflect.mkMirror(classLoader: ClassLoader)` method + * 2) Set `classLoader` to the new value + * + * The first, immutable, way should be strongly preferred in most situation. + * However sometimes it is necessary to migrate the default reflexive mirror (`scala.reflect.mirror`) to a new classloader. + * In that and only that case, use the setter, but be very careful not to introduce inconsistencies. + */ + var classLoader: ClassLoader /** The Scala class symbol that has given fully qualified name * @param name The fully qualified name of the class to be returned diff --git a/src/library/scala/reflect/api/Names.scala b/src/library/scala/reflect/api/Names.scala index c72774dfc7..d92d056751 100755 --- a/src/library/scala/reflect/api/Names.scala +++ b/src/library/scala/reflect/api/Names.scala @@ -34,12 +34,12 @@ trait Names { def toTypeName: TypeName /** Replaces all occurrences of $op_names in this name by corresponding operator symbols. - * Example: `foo_+=` becomes `foo_$plus$eq`. + * Example: `foo_$plus$eq` becomes `foo_+=` */ def decoded: String /** Replaces all occurrences of operator symbols in this name by corresponding $op_names. - * Example: `foo_$plus$eq` becomes `foo_+=` + * Example: `foo_+=` becomes `foo_$plus$eq`. */ def encoded: String diff --git a/src/library/scala/reflect/api/Positions.scala b/src/library/scala/reflect/api/Positions.scala index 91f1081b4d..8f01e0ced1 100644 --- a/src/library/scala/reflect/api/Positions.scala +++ b/src/library/scala/reflect/api/Positions.scala @@ -1,21 +1,202 @@ package scala.reflect package api -trait Positions { self: Universe => - /** TreeAnnotation is a generalisation of Position. - * - * TreeAnnotation cannot be an upperbound of Position since the corresponding classes - * must live outside of the universe for backwards compatibility (see scala.tools.nsc.util.Position). - * Thus, represent subtyping as coercions. - * - * Typically, positionToAnnotation is the identity, and annotationToPosition returns annot.pos - */ - type TreeAnnotation // <: { def pos: Position } - def NoTreeAnnotation: TreeAnnotation - implicit def positionToAnnotation(pos: Position): TreeAnnotation // = pos - def annotationToPosition(annot: TreeAnnotation): Position // = annot.pos - def _checkSetAnnotation(tree: Tree, annot: TreeAnnotation): Unit = () // check that annot may overwrite tree.annot - - type Position // <: TreeAnnotation, but not practical to enforce this (would require moving Position, SourceFile, Reporter,... into the universe) +trait Positions { + self: Universe => + + // [Eugene] in quite a lot of situations (mostly related to error reporting) we need positions in the API + // however it seems that neither runtime compilation, nor macros need facilities to create positions from scratch + // both emit ASTs, which can be automatically transformed into synthetic sources and assigned with synthetic positions + // hence I added possibilities to inspect everything we can, but add any position factories + // this simplified a lot of things, the biggest of them is that we don't need to expose SourceFile/AbstractFile + type Position <: scala.reflect.api.Position val NoPosition: Position -}
\ No newline at end of file + + /** A position that wraps a set of trees. + * The point of the wrapping position is the point of the default position. + * If some of the trees are ranges, returns a range position enclosing all ranges + * Otherwise returns default position. + */ + def wrappingPos(default: Position, trees: List[Tree]): Position + + /** A position that wraps the non-empty set of trees. + * The point of the wrapping position is the point of the first trees' position. + * If all some the trees are non-synthetic, returns a range position enclosing the non-synthetic trees + * Otherwise returns a synthetic offset position to point. + */ + def wrappingPos(trees: List[Tree]): Position + + /** Ensure that given tree has no positions that overlap with + * any of the positions of `others`. This is done by + * shortening the range or assigning TransparentPositions + * to some of the nodes in `tree`. + */ + def ensureNonOverlapping(tree: Tree, others: List[Tree]) + + /** Assigns a given position to all position-less nodes of a given AST. + */ + def atPos[T <: Tree](pos: Position)(tree: T): T +} + +/** The Position class and its subclasses represent positions of ASTs and symbols. + * Except for NoPosition and FakePos, every position refers to a SourceFile + * and to an offset in the sourcefile (its `point`). For batch compilation, + * that's all. For interactive IDE's there are also RangePositions + * and TransparentPositions. A RangePosition indicates a start and an end + * in addition to its point. TransparentPositions are a subclass of RangePositions. + * Range positions that are not transparent are called opaque. + * Trees with RangePositions need to satisfy the following invariants. + * + * INV1: A tree with an offset position never contains a child + * with a range position + * INV2: If the child of a tree with a range position also has a range position, + * then the child's range is contained in the parent's range. + * INV3: Opaque range positions of children of the same node are non-overlapping + * (this means their overlap is at most a single point). + * + * The following tests are useful on positions: + * + * pos.isDefined true if position is not a NoPosition nor a FakePosition + * pos.isRange true if position is a range + * pos.isOpaqueRange true if position is an opaque range + * + * The following accessor methods are provided: + * + * pos.source The source file of the position, which must be defined + * pos.point The offset of the position's point, which must be defined + * pos.start The start of the position, which must be a range + * pos.end The end of the position, which must be a range + * + * There are also convenience methods, such as + * + * pos.startOrPoint + * pos.endOrPoint + * pos.pointOrElse(default) + * + * These are less strict about the kind of position on which they can be applied. + * + * The following conversion methods are often used: + * + * pos.focus converts a range position to an offset position, keeping its point; + * returns all other positions unchanged. + * pos.makeTransparent converts an opaque range position into a transparent one. + * returns all other positions unchanged. + */ +trait Position extends Attachment { + + /** Java file corresponding to the source file of this position. + */ + def fileInfo: java.io.File + + /** Content of the source file that contains this position. + */ + def fileContent: Array[Char] + + /** Is this position neither a NoPosition nor a FakePosition? + * If isDefined is true, offset and source are both defined. + */ + def isDefined: Boolean + + /** Is this position a transparent position? */ + def isTransparent: Boolean + + /** Is this position a range position? */ + def isRange: Boolean + + /** Is this position a non-transparent range position? */ + def isOpaqueRange: Boolean + + /** if opaque range, make this position transparent */ + def makeTransparent: Position + + /** The start of the position's range, error if not a range position */ + def start: Int + + /** The start of the position's range, or point if not a range position */ + def startOrPoint: Int + + /** The point (where the ^ is) of the position */ + def point: Int + + /** The point (where the ^ is) of the position, or else `default` if undefined */ + def pointOrElse(default: Int): Int + + /** The end of the position's range, error if not a range position */ + def end: Int + + /** The end of the position's range, or point if not a range position */ + def endOrPoint: Int + + /** The same position with a different start value (if a range) */ + def withStart(off: Int): Position + + /** The same position with a different end value (if a range) */ + def withEnd(off: Int): Position + + /** The same position with a different point value (if a range or offset) */ + def withPoint(off: Int): Position + + /** If this is a range, the union with the other range, with the point of this position. + * Otherwise, this position + */ + def union(pos: Position): Position + + /** If this is a range position, the offset position of its start. + * Otherwise the position itself + */ + def focusStart: Position + + /** If this is a range position, the offset position of its point. + * Otherwise the position itself + */ + def focus: Position + + /** If this is a range position, the offset position of its end. + * Otherwise the position itself + */ + def focusEnd: Position + + /** Does this position include the given position `pos`. + * This holds if `this` is a range position and its range [start..end] + * is the same or covers the range of the given position, which may or may not be a range position. + */ + def includes(pos: Position): Boolean + + /** Does this position properly include the given position `pos` ("properly" meaning their + * ranges are not the same)? + */ + def properlyIncludes(pos: Position): Boolean + + /** Does this position precede that position? + * This holds if both positions are defined and the end point of this position + * is not larger than the start point of the given position. + */ + def precedes(pos: Position): Boolean + + /** Does this position properly precede the given position `pos` ("properly" meaning their ranges + * do not share a common point). + */ + def properlyPrecedes(pos: Position): Boolean + + /** Does this position overlap with that position? + * This holds if both positions are ranges and there is an interval of + * non-zero length that is shared by both position ranges. + */ + def overlaps(pos: Position): Boolean + + /** Does this position cover the same range as that position? + * Holds only if both position are ranges + */ + def sameRange(pos: Position): Boolean + + def line: Int + + def column: Int + + /** Convert this to a position around `point` that spans a single source line */ + def toSingleLine: Position + + def lineContent: String + + def show: String +} diff --git a/src/library/scala/reflect/api/Reporters.scala b/src/library/scala/reflect/api/Reporters.scala new file mode 100644 index 0000000000..b7428e1599 --- /dev/null +++ b/src/library/scala/reflect/api/Reporters.scala @@ -0,0 +1,65 @@ +package scala.reflect +package api + +trait Reporters { self: Universe => + + trait Reporter { + object severity extends Enumeration + class Severity(val id: Int) extends severity.Value { + var count: Int = 0 + override def toString() = this match { + case INFO => "INFO" + case WARNING => "WARNING" + case ERROR => "ERROR" + case _ => "<unknown>" + } + } + val INFO = new Severity(0) + val WARNING = new Severity(1) + val ERROR = new Severity(2) + + case class Info(val pos: Position, val msg: String, val severity: Severity) + val infos = new collection.mutable.LinkedHashSet[Info] + + /** Handles incoming info */ + def log(pos: Position, msg: String, severity: Severity) { + infos += new Info(pos, msg, severity) + severity.count += 1 + display(infos.last) + } + + /** Displays incoming info */ + def display(info: Info): Unit + + /** Services a request to drop into interactive mode */ + def interactive(): Unit + + /** Refreshes the UI */ + def flush(): Unit = {} + + /** Resets the reporter */ + def reset(): Unit = { + INFO.count = 0 + WARNING.count = 0 + ERROR.count = 0 + infos.clear() + } + } + + class SilentReporter extends Reporter { + def display(info: Info) {} + def interactive() {} + } + + /** Creates a UI-less reporter that simply accumulates all the messages + */ + def mkSilentReporter(): Reporter = new SilentReporter() + + /** Creates a reporter that prints messages to the console according to the settings. + * + * ``minSeverity'' determines minimum severity of the messages to be printed. + * 0 stands for INFO, 1 stands for WARNING and 2 stands for ERROR. + */ + // todo. untangle warningsAsErrors from Reporters. I don't feel like moving this flag here! + def mkConsoleReporter(minSeverity: Int = 1): Reporter +}
\ No newline at end of file diff --git a/src/library/scala/reflect/api/RuntimeTypes.scala b/src/library/scala/reflect/api/RuntimeTypes.scala deleted file mode 100644 index f58b328868..0000000000 --- a/src/library/scala/reflect/api/RuntimeTypes.scala +++ /dev/null @@ -1,20 +0,0 @@ -package scala.reflect -package api - -/** A mirror establishes connections of - * runtime entities such as class names and object instances - * with a refexive universe. - */ -private[reflect] trait RuntimeTypes extends Universe { - - type InstanceRefSymbol >: Null <: Symbol - - val InstanceRefSymbol: InstanceRefSymbolExtractor - - private[reflect] def namedType(pre: Type, sym: Symbol, args: List[Type]): Type - - abstract class InstanceRefSymbolExtractor { - def apply(value: AnyRef): InstanceRefSymbol - def unapply(tpe: InstanceRefSymbol): Option[AnyRef] - } -} diff --git a/src/library/scala/reflect/api/Scopes.scala b/src/library/scala/reflect/api/Scopes.scala index d4e4e24f29..4a5702eadc 100755 --- a/src/library/scala/reflect/api/Scopes.scala +++ b/src/library/scala/reflect/api/Scopes.scala @@ -5,7 +5,12 @@ trait Scopes { self: Universe => type Scope <: Iterable[Symbol] - def newScope(): Scope -} + /** Create a new scope */ + def newScope: Scope + /** Create a new scope nested in another one with which it shares its elements */ + def newNestedScope(outer: Scope): Scope + /** Create a new scope with given initial elements */ + def newScopeWith(elems: Symbol*): Scope +}
\ No newline at end of file diff --git a/src/library/scala/reflect/api/StandardDefinitions.scala b/src/library/scala/reflect/api/StandardDefinitions.scala index c3d989f971..e457bb73e0 100755 --- a/src/library/scala/reflect/api/StandardDefinitions.scala +++ b/src/library/scala/reflect/api/StandardDefinitions.scala @@ -8,6 +8,23 @@ package api trait StandardDefinitions { self: Universe => + val ByteTpe: Type + val ShortTpe: Type + val CharTpe: Type + val IntTpe: Type + val LongTpe: Type + val FloatTpe: Type + val DoubleTpe: Type + val BooleanTpe: Type + val UnitTpe: Type + val AnyTpe: Type + val ObjectTpe: Type + val AnyValTpe: Type + val AnyRefTpe: Type + val NothingTpe: Type + val NullTpe: Type + val StringTpe: Type + val definitions: AbsDefinitions abstract class AbsDefinitions { @@ -15,7 +32,11 @@ trait StandardDefinitions { self: Universe => def RootPackage: Symbol def RootClass: Symbol def EmptyPackage: Symbol + def EmptyPackageClass: Symbol def ScalaPackage: Symbol + def ScalaPackageClass: Symbol + def JavaLangPackage: Symbol + def JavaLangPackageClass: Symbol // top types def AnyClass : Symbol @@ -37,6 +58,7 @@ trait StandardDefinitions { self: Universe => def FloatClass : Symbol def DoubleClass : Symbol def BooleanClass: Symbol + def ScalaPrimitiveValueClasses: List[Symbol] // fundamental reference classes def SymbolClass : Symbol @@ -48,13 +70,57 @@ trait StandardDefinitions { self: Universe => def ProductClass : Array[Symbol] def FunctionClass : Array[Symbol] - // fundamental modules + // Option classes + def OptionClass: Symbol + def SomeClass: Symbol + def NoneModule: Symbol + def SomeModule: Symbol + + // collections classes + def ConsClass: Symbol + def IterableClass: Symbol + def IteratorClass: Symbol + def ListClass: Symbol + def SeqClass: Symbol + def StringBuilderClass: Symbol + def TraversableClass: Symbol + + // collections modules def PredefModule: Symbol + def ListModule: Symbol + def List_apply: Symbol + def NilModule: Symbol + def SeqModule: Symbol + def IteratorModule: Symbol + def Iterator_apply: Symbol + + // arrays and their members + def ArrayModule: Symbol + def ArrayModule_overloadedApply: Symbol + def ArrayClass: Symbol + def Array_apply: Symbol + def Array_update: Symbol + def Array_length: Symbol + def Array_clone: Symbol + + // special parameter types + def ByNameParamClass: Symbol + def JavaRepeatedParamClass: Symbol + def RepeatedParamClass: Symbol + + // type tags + def ClassTagClass: Symbol + def ClassTagModule: Symbol + def TypeTagClass: Symbol + def TypeTagModule: Symbol + def ConcreteTypeTagClass: Symbol + def ConcreteTypeTagModule: Symbol /** Given a type T, returns the type corresponding to the VM's * representation: ClassClass's type constructor applied to `arg`. */ def vmClassType(arg: Type): Type // !!! better name? + // [Eugene] we already have arg.erasure, right? /** The string representation used by the given type in the VM. */ diff --git a/src/library/scala/reflect/api/StandardNames.scala b/src/library/scala/reflect/api/StandardNames.scala index 81517d2a6b..d2110ede75 100644 --- a/src/library/scala/reflect/api/StandardNames.scala +++ b/src/library/scala/reflect/api/StandardNames.scala @@ -8,14 +8,161 @@ package api trait StandardNames { self: Universe => + abstract class AbsNames { + type NameType <: Name + + val EMPTY: NameType + val ANON_FUN_NAME: NameType + val ANON_CLASS_NAME: NameType + val EMPTY_PACKAGE_NAME: NameType + val IMPORT: NameType + val MODULE_VAR_SUFFIX: NameType + val ROOT: NameType + val PACKAGE: NameType + val SPECIALIZED_SUFFIX: NameType + + val ERROR: NameType + val NO_NAME: NameType + val WILDCARD: NameType + + def flattenedName(segments: Name*): NameType + } + val nme: AbsTermNames - abstract class AbsTermNames { + abstract class AbsTermNames extends AbsNames { + val EXPAND_SEPARATOR_STRING: String + + val ANYNAME: TermName val CONSTRUCTOR: TermName + val FAKE_LOCAL_THIS: TermName + val INITIALIZER: TermName + val LAZY_LOCAL: TermName + val LOCAL_SUFFIX_STRING: String + val MIRROR_PREFIX: TermName + val MIRROR_SHORT: TermName + val MIRROR_FREE_PREFIX: TermName + val MIRROR_FREE_THIS_SUFFIX: TermName + val MIRROR_FREE_VALUE_SUFFIX: TermName + val MIXIN_CONSTRUCTOR: TermName + val MODULE_INSTANCE_FIELD: TermName + val OUTER: TermName + val OUTER_LOCAL: TermName + val OUTER_SYNTH: TermName + val SELECTOR_DUMMY: TermName + val SELF: TermName + val SPECIALIZED_INSTANCE: TermName + val STAR: TermName + val THIS: TermName + + val BITMAP_NORMAL: TermName + val BITMAP_TRANSIENT: TermName + val BITMAP_PRIVATE: TermName + val BITMAP_CHECKINIT: TermName + val BITMAP_CHECKINIT_TRANSIENT: TermName + + val INTERPRETER_IMPORT_WRAPPER: String + val INTERPRETER_LINE_PREFIX: String + val INTERPRETER_VAR_PREFIX: String + val INTERPRETER_WRAPPER_SUFFIX: String + + val ROOTPKG: TermName + + val ADD: TermName + val AND: TermName + val ASR: TermName + val DIV: TermName + val EQ: TermName + val EQL: TermName + val GE: TermName + val GT: TermName + val HASHHASH: TermName + val LE: TermName + val LSL: TermName + val LSR: TermName + val LT: TermName + val MINUS: TermName + val MOD: TermName + val MUL: TermName + val NE: TermName + val OR: TermName + val PLUS : TermName + val SUB: TermName + val XOR: TermName + val ZAND: TermName + val ZOR: TermName + + // [Eugene] this doesn't compile. why?! + val UNARY_~ : TermName + val UNARY_+ : TermName + val UNARY_- : TermName + val UNARY_! : TermName + + // [Eugene] this doesn't compile. why?! + val ??? : TermName + + val MODULE_SUFFIX_NAME: TermName + val NAME_JOIN_NAME: TermName + val IMPL_CLASS_SUFFIX: String + val LOCALDUMMY_PREFIX: String + val PROTECTED_PREFIX: String + val PROTECTED_SET_PREFIX: String + val SINGLETON_SUFFIX: String + val SUPER_PREFIX_STRING: String + val TRAIT_SETTER_SEPARATOR_STRING: String + val SETTER_SUFFIX: TermName + + def isConstructorName(name: Name): Boolean + def isExceptionResultName(name: Name): Boolean + def isImplClassName(name: Name): Boolean + def isLocalDummyName(name: Name): Boolean + def isLocalName(name: Name): Boolean + def isLoopHeaderLabel(name: Name): Boolean + def isProtectedAccessorName(name: Name): Boolean + def isSuperAccessorName(name: Name): Boolean + def isReplWrapperName(name: Name): Boolean + def isSetterName(name: Name): Boolean + def isTraitSetterName(name: Name): Boolean + def isSingletonName(name: Name): Boolean + def isModuleName(name: Name): Boolean + def isOpAssignmentName(name: Name): Boolean + + def segments(name: String, assumeTerm: Boolean): List[Name] + def originalName(name: Name): Name + def stripModuleSuffix(name: Name): Name + def unspecializedName(name: Name): Name + def splitSpecializedName(name: Name): (Name, String, String) + def dropLocalSuffix(name: Name): Name + + def expandedName(name: TermName, base: Symbol, separator: String = EXPAND_SEPARATOR_STRING): TermName + def expandedSetterName(name: TermName, base: Symbol): TermName + def protName(name: Name): TermName + def protSetterName(name: Name): TermName + def getterName(name: TermName): TermName + def getterToLocal(name: TermName): TermName + def getterToSetter(name: TermName): TermName + def localToGetter(name: TermName): TermName + def setterToGetter(name: TermName): TermName + def defaultGetterName(name: Name, pos: Int): TermName + def defaultGetterToMethod(name: Name): TermName + + def dropSingletonName(name: Name): TypeName + def singletonName(name: Name): TypeName + def implClassName(name: Name): TypeName + def interfaceName(implname: Name): TypeName + def localDummyName(clazz: Symbol): TermName + def superName(name: Name): TermName } val tpnme: AbsTypeNames - abstract class AbsTypeNames { + abstract class AbsTypeNames extends AbsNames { + val REFINE_CLASS_NAME: TypeName + val BYNAME_PARAM_CLASS_NAME: TypeName + val EQUALS_PATTERN_NAME: TypeName + val JAVA_REPEATED_PARAM_CLASS_NAME: TypeName + val LOCAL_CHILD: TypeName + val REPEATED_PARAM_CLASS_NAME: TypeName + val WILDCARD_STAR: TypeName } } diff --git a/src/library/scala/reflect/api/Symbols.scala b/src/library/scala/reflect/api/Symbols.scala index ab59a4a39a..a154e5f7a0 100755 --- a/src/library/scala/reflect/api/Symbols.scala +++ b/src/library/scala/reflect/api/Symbols.scala @@ -7,6 +7,10 @@ trait Symbols { self: Universe => abstract class AbsSymbol { this: Symbol => + /** The position of this symbol + */ + def pos: Position + /** The modifiers of this symbol */ def modifiers: Set[Modifier] @@ -47,6 +51,10 @@ trait Symbols { self: Universe => /** An id number which is unique for all symbols in this universe */ def id: Int + /** ... + */ + def orElse[T](alt: => Symbol): Symbol + /** * Set when symbol has a modifier of the form private[X], NoSymbol otherwise. * @@ -112,6 +120,20 @@ trait Symbols { self: Universe => */ def isTerm : Boolean + /** Does this symbol represent the definition of method? + * If yes, `isTerm` is also guaranteed to be true. + */ + def isMethod : Boolean + + /** Is this symbol an overloaded method? + */ + def isOverloaded : Boolean + + /** Does this symbol represent a free term captured by reification? + */ + // needed for ones who wish to inspect reified trees + def isFreeTerm : Boolean + /** Does this symbol represent the definition of type? * Note that every symbol is either a term or a type. * So for every symbol `sym`, either `sym.isTerm` is true @@ -124,6 +146,17 @@ trait Symbols { self: Universe => */ def isClass : Boolean + /** Does this symbol represent the definition of a primitive class? + * Namely, is it one of [[scala.Double]], [[scala.Float]], [[scala.Long]], [[scala.Int]], [[scala.Char]], + * [[scala.Short]], [[scala.Byte]], [[scala.Unit]] or [[scala.Boolean]]? + */ + def isPrimitiveValueClass: Boolean + + /** Does this symbol represent the definition of a custom value class? + * Namely, is AnyVal among its parent classes? + */ + def isDerivedValueClass: Boolean + /** Does this symbol represent the definition of a type alias? * If yes, `isType` is also guaranteed to be true. */ @@ -134,9 +167,28 @@ trait Symbols { self: Universe => */ def isAbstractType : Boolean - /** Is this symbol an overloaded method? + /** Does this symbol represent the definition of a skolem? + * Skolems are used during typechecking to represent type parameters viewed from inside their scopes. + * If yes, `isType` is also guaranteed to be true. */ - def isOverloaded: Boolean + def isSkolem : Boolean + + /** Does this symbol represent a free type captured by reification? + */ + // needed for ones who wish to inspect reified trees + def isFreeType : Boolean + + /** Is the type parameter represented by this symbol contravariant? + */ + def isContravariant : Boolean + + /** Is the type parameter represented by this symbol contravariant? + */ + def isCovariant : Boolean + + /** Does this symbol or its underlying type represent a typechecking error? + */ + def isErroneous : Boolean /** The type signature of this symbol. * Note if the symbol is a member of a class, one almost always is interested @@ -192,7 +244,7 @@ trait Symbols { self: Universe => /** A fresh symbol with given name `name`, position `pos` and flags `flags` that has * the current symbol as its owner. */ - def newNestedSymbol(name: Name, pos: Position, flags: Long, isClass: Boolean): Symbol // needed by LiftCode + def newNestedSymbol(name: Name, pos: Position, flags: Long, isClass: Boolean): Symbol // needed by LiftCode !!! not enough reason to have in the api /** Low-level operation to set the symbol's flags * @return the symbol itself @@ -207,6 +259,9 @@ trait Symbols { self: Universe => /** Set symbol's annotations to given annotations `annots`. */ def setAnnotations(annots: AnnotationInfo*): this.type // needed by LiftCode !!! not enough reason to have in the api + + /** The kind of this symbol; used for debugging */ + def kind: String } val NoSymbol: Symbol diff --git a/src/library/scala/reflect/api/ToolBoxes.scala b/src/library/scala/reflect/api/ToolBoxes.scala new file mode 100644 index 0000000000..387ef5163b --- /dev/null +++ b/src/library/scala/reflect/api/ToolBoxes.scala @@ -0,0 +1,90 @@ +package scala.reflect +package api + +trait ToolBoxes { self: Universe => + + type ToolBox <: AbsToolBox + + def mkToolBox(reporter: Reporter = mkSilentReporter(), options: String = ""): AbsToolBox + + // [Eugene] what do you think about the interface? namely about the ``freeTypes'' part. + trait AbsToolBox { + + /** UI of the toolbox. + * + * Accumulates and displays warnings and errors, can drop to interactive mode (if supported). + * The latter can be useful to study the typechecker or to debug complex macros. + */ + def reporter: Reporter + + /** Typechecks a tree using this ToolBox. + * This populates symbols and types of the tree and possibly transforms it to reflect certain desugarings. + * + * If the tree has unresolved type variables (represented as instances of ``FreeType'' symbols), + * then they might, might be partially or might not be specified in the ``freeTypes'' parameter. + * + * If ``silent'' is false, ``TypeError'' will be thrown in case of a typecheck error. + * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs. + * Such errors don't vanish and can be inspected by turning on -Ydebug. + * + * Typechecking can be steered with the following optional parameters: + * ``withImplicitViewsDisabled'' recursively prohibits implicit views (though, implicit vals will still be looked up and filled in), default value is false + * ``withMacrosDisabled'' recursively prohibits macro expansions and macro-based implicits, default value is false + */ + def typeCheck(tree: Tree, pt: Type = WildcardType, freeTypes: Map[FreeType, Type] = Map[FreeType, Type](), silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree + + /** Infers an implicit value of the expected type ``pt'' in the macro callsite context. + * + * If ``silent'' is false, ``TypeError'' will be thrown in case of an inference error. + * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs. + * Such errors don't vanish and can be inspected by turning on -Xlog-implicits. + * Unlike in ``typeCheck'', ``silent'' is true by default. + */ + def inferImplicitValue(pt: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false): Tree + + /** Infers an implicit view from the provided tree ``tree'' from the type ``from'' to the type ``to'' in the macro callsite context. + * + * Otional parameter, ``reportAmbiguous`` controls whether ambiguous implicit errors should be reported. + * If we search for a view simply to find out whether one type is coercible to another, it might be desirable to set this flag to ``false''. + * + * If ``silent'' is false, ``TypeError'' will be thrown in case of an inference error. + * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs. + * Such errors don't vanish and can be inspected by turning on -Xlog-implicits. + * Unlike in ``typeCheck'', ``silent'' is true by default. + */ + def inferImplicitView(tree: Tree, from: Type, to: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, reportAmbiguous: Boolean = true): Tree + + /** Recursively resets symbols and types in a given tree. + * + * Note that this does not revert the tree to its pre-typer shape. + * For more info, read up https://issues.scala-lang.org/browse/SI-5464. + */ + def resetAllAttrs[T <: Tree](tree: T): T + + /** Recursively resets locally defined symbols and types in a given tree. + * + * Note that this does not revert the tree to its pre-typer shape. + * For more info, read up https://issues.scala-lang.org/browse/SI-5464. + */ + def resetLocalAttrs[T <: Tree](tree: T): T + + /** Compiles and runs a tree using this ToolBox. + * + * If the tree has unresolved type variables (represented as instances of ``FreeType'' symbols), + * then they all have to be specified in the ``freeTypes'' parameter or an error occurs. + * + * This spawns the compiler at the Namer phase, and pipelines the tree through that compiler. + * Currently ``runExpr'' does not accept trees that already typechecked, because typechecking isn't idempotent. + * For more info, take a look at https://issues.scala-lang.org/browse/SI-5464. + */ + def runExpr(tree: Tree, freeTypes: Map[FreeType, Type] = Map[FreeType, Type]()): Any + + /** Represents an error during toolboxing + */ + type ToolBoxError <: Throwable + val ToolBoxError: ToolBoxErrorExtractor + abstract class ToolBoxErrorExtractor { + def unapply(error: ToolBoxError): Option[(ToolBox, String)] + } + } +}
\ No newline at end of file diff --git a/src/library/scala/reflect/api/TreeBuildUtil.scala b/src/library/scala/reflect/api/TreeBuildUtil.scala index f28008bc21..32d7eefa5b 100644 --- a/src/library/scala/reflect/api/TreeBuildUtil.scala +++ b/src/library/scala/reflect/api/TreeBuildUtil.scala @@ -1,46 +1,127 @@ -package scala.reflect.api +package scala.reflect +package api -trait TreeBuildUtil extends Universe { +trait TreeBuildUtil { self: Universe => - /** The symbol corresponding to the globally accessible class with the - * given fully qualified name `fullName`. + /** The symbol corresponding to the globally accessible class with the given fully qualified name `fullName`. + * Unlike `staticClassIfDefined`, throws `MissingRequirementError` is requested class cannot be found. */ def staticClass(fullName: String): Symbol - /** The symbol corresponding to the globally accessible object with the - * given fully qualified name `fullName`. + /** The symbol corresponding to the globally accessible class with the given fully qualified name `fullName`. + * Unlike `staticClass`, doesn't throw `MissingRequirementError` (returns NoSymbol) is requested class cannot be found. + */ + def staticClassIfDefined(fullName: String): Symbol + + /** The symbol corresponding to the globally accessible object with the given fully qualified name `fullName`. + * Unlike `staticModuleIfDefined`, throws `MissingRequirementError` is requested object cannot be found. */ def staticModule(fullName: String): Symbol + /** The symbol corresponding to the globally accessible object with the given fully qualified name `fullName`. + * Unlike `staticModule`, doesn't throw `MissingRequirementError` (returns NoSymbol) is requested object cannot be found. + */ + def staticModuleIfDefined(fullName: String): Symbol + /** The this-ptype of the globally accessible object with the * given fully qualified name `fullName`. */ def thisModuleType(fullName: String): Type /** Selects type symbol with given simple name `name` from the defined members of `owner`. + * Unlike `selectTypeIfDefined`, throws `MissingRequirementError` is requested type symbol cannot be found. */ def selectType(owner: Symbol, name: String): Symbol + /** Selects type symbol with given simple name `name` from the defined members of `owner`. + * Unlike `selectType`, doesn't throw `MissingRequirementError` (returns NoSymbol) is requested type symbol cannot be found. + */ + def selectTypeIfDefined(owner: Symbol, name: String): Symbol + /** Selects term symbol with given name and type from the defined members of prefix type - * @pre The prefix type - * @name The name of the selected member + * Unlike `selectTermIfDefined`, throws `MissingRequirementError` is requested term symbol cannot be found. */ def selectTerm(owner: Symbol, name: String): Symbol - def selectOverloadedMethod(owner: Symbol, name: String, index: Int): Symbol + /** Selects term symbol with given name and type from the defined members of prefix type + * Unlike `selectTerm`, doesn't throw `MissingRequirementError` (returns NoSymbol) is requested term symbol cannot be found. + */ + def selectTermIfDefined(owner: Symbol, name: String): Symbol - def selectParam(owner: Symbol, idx: Int): Symbol + /** Selects overloaded method symbol with given name and index + * Unlike `selectOverloadedMethodIfDefined`, throws `MissingRequirementError` is requested overloaded method cannot be found. + */ + def selectOverloadedMethod(owner: Symbol, name: String, index: Int): Symbol - def newScopeWith(decls: Symbol*): Scope + /** Selects overloaded method symbol with given name and index + * Unlike `selectOverloadedMethod`, doesn't throw `MissingRequirementError` (returns NoSymbol) is requested overloaded method cannot be found. + */ + def selectOverloadedMethodIfDefined(owner: Symbol, name: String, index: Int): Symbol - /** Create a fresh free variable symbol. + /** Create a fresh free term symbol. * @param name the name of the free variable - * @param tsig the type signature of the free variable + * @param info the type signature of the free variable * @param value the value of the free variable at runtime + * @param origin debug information that tells where this symbol comes from */ - def newFreeVar(name: String, info: Type, value: Any): Symbol + def newFreeTerm(name: String, info: Type, value: => Any, origin: String): Symbol + + /** Create a fresh free type symbol. + * @param name the name of the free variable + * @param info the type signature of the free variable + * @param value a type tag that captures the value of the free variable + * is completely phantom, since the captured type cannot be propagated to the runtime + * if it could be, we wouldn't be creating a free type to begin with + * the only usage for it is preserving the captured symbol for compile-time analysis + * @param origin debug information that tells where this symbol comes from + */ + def newFreeType(name: String, info: Type, value: => Any, origin: String): Symbol /** Create a Modiiers structure given internal flags, qualifier, annotations */ def modifiersFromInternalFlags(flags: Long, privateWithin: Name, annotations: List[Tree]): Modifiers -}
\ No newline at end of file + val gen: TreeGen { val global: TreeBuildUtil.this.type } + + type TreeGen <: AbsTreeGen +} + +// [Eugene to Paul] we need to expose some of the functionality provided by TreeGen +// I added some stuff that was necessary for typetag materialization macros +// but we should think it over and pick other generally useful stuff +// same goes for tree traversers/transformers, type maps, etc +// and once we expose all that, there's another question: how do we stay in sync? +trait AbsTreeGen { + val global: Universe + + import global._ + import definitions._ + + /** Builds a reference to value whose type is given stable prefix. + * The type must be suitable for this. For example, it + * must not be a TypeRef pointing to an abstract type variable. + */ + def mkAttributedQualifier(tpe: Type): Tree + + /** Builds a reference to value whose type is given stable prefix. + * If the type is unsuitable, e.g. it is a TypeRef for an + * abstract type variable, then an Ident will be made using + * termSym as the Ident's symbol. In that case, termSym must + * not be NoSymbol. + */ + def mkAttributedQualifier(tpe: Type, termSym: Symbol): Tree + + /** Builds a typed reference to given symbol with given stable prefix. */ + def mkAttributedRef(pre: Type, sym: Symbol): Tree + + /** Builds a typed reference to given symbol. */ + def mkAttributedRef(sym: Symbol): Tree + + /** Builds a typed This reference to given symbol. */ + def mkAttributedThis(sym: Symbol): Tree + + /** Builds a typed Ident with an underlying symbol. */ + def mkAttributedIdent(sym: Symbol): Tree + + /** Builds a typed Select with an underlying symbol. */ + def mkAttributedSelect(qual: Tree, sym: Symbol): Tree +} diff --git a/src/library/scala/reflect/api/TreePrinters.scala b/src/library/scala/reflect/api/TreePrinters.scala index 43865915d3..3d64ec8e40 100644 --- a/src/library/scala/reflect/api/TreePrinters.scala +++ b/src/library/scala/reflect/api/TreePrinters.scala @@ -29,17 +29,21 @@ trait TreePrinters { self: Universe => def newTreePrinter(out: PrintWriter): TreePrinter // emits more or less verbatim representation of the provided tree - // todo. when LiftCode becomes a macro, throw this code away and use that macro class RawTreePrinter(out: PrintWriter) extends TreePrinter { + val EmptyValDef = self.emptyValDef def print(args: Any*): Unit = args foreach { case EmptyTree => print("EmptyTree") + case EmptyValDef => + print("emptyValDef") case tree @ TypeTree() => print("TypeTree()") if (tree.tpe != null) print(".setType(", tree.tpe, ")") else if (tree.original != null) print(".setOriginal(", tree.original, ")") + case Literal(Constant(s: String)) => + print("Literal(Constant(\"" + s + "\"))") case tree: Tree => print(tree.printingPrefix+"(") val it = tree.productIterator diff --git a/src/library/scala/reflect/api/Trees.scala b/src/library/scala/reflect/api/Trees.scala index d8180fe029..d659a9e9eb 100644 --- a/src/library/scala/reflect/api/Trees.scala +++ b/src/library/scala/reflect/api/Trees.scala @@ -14,6 +14,7 @@ trait Trees { self: Universe => private[scala] var nodeCount = 0 type Modifiers >: Null <: AbsModifiers + val NoMods: Modifiers abstract class AbsModifiers { def modifiers: Set[Modifier] @@ -80,18 +81,14 @@ trait Trees { self: Universe => */ def printingPrefix = productPrefix - def pos: Position = annotationToPosition(rawannot) - def pos_=(pos: Position): Unit = annotation = pos + def pos: Position = rawatt.pos.asInstanceOf[Position] // [Eugene] how do we get rid of this cast? + def pos_=(pos: Position): Unit = rawatt = (rawatt withPos pos) // the "withPos" part is crucial to robustness def setPos(newpos: Position): this.type = { pos = newpos; this } - private[this] var rawannot: TreeAnnotation = NoTreeAnnotation - def annotation: TreeAnnotation = rawannot - def annotation_=(annot: TreeAnnotation): Unit = { - _checkSetAnnotation(this, annot) - rawannot = annot - } - - def setAnnotation(annot: TreeAnnotation): this.type = { annotation = annot; this } + private[this] var rawatt: Attachment = NoPosition + def attachment: Attachment = rawatt + def attachment_=(att: Attachment): Unit = rawatt = att + def setAttachment(att: Attachment): this.type = { rawatt = att; this } private[this] var rawtpe: Type = _ @@ -143,6 +140,7 @@ trait Trees { self: Universe => def hasSymbol = false def isDef = false def isEmpty = false + def orElse(alt: => Tree) = if (!isEmpty) this else alt def hasSymbolWhich(f: Symbol => Boolean) = hasSymbol && f(symbol) @@ -179,6 +177,13 @@ trait Trees { self: Universe => } def filter(f: Tree => Boolean): List[Tree] = withFilter(f) + /** Apply `pf' to each subtree on which the function is defined */ + def collect[T](pf: PartialFunction[Tree, T]): List[T] = { + val ctt = new CollectTreeTraverser[T](pf) + ctt.traverse(this) + ctt.results.toList + } + /** Returns optionally first tree (in a preorder traversal) which satisfies predicate `p`, * or None if none exists. */ @@ -188,9 +193,12 @@ trait Trees { self: Universe => ft.result } - /** Is there part of this tree which satisfies predicate `p`? */ + /** Is there exists a part of this tree which satisfies predicate `p`? */ def exists(p: Tree => Boolean): Boolean = !find(p).isEmpty + /** Do all parts of this tree satisfy predicate `p`? */ + def forAll(p: Tree => Boolean): Boolean = find(!p(_)).isEmpty + def equalsStructure(that : Tree) = equalsStructure0(that)(_ eq _) def equalsStructure0(that: Tree)(f: (Tree,Tree) => Boolean): Boolean = f(this, that) || ((this.productArity == that.productArity) && { @@ -230,7 +238,7 @@ trait Trees { self: Universe => duplicateTree(this).asInstanceOf[this.type] private[scala] def copyAttrs(tree: Tree): this.type = { - annotation = tree.annotation + attachment = tree.attachment tpe = tree.tpe if (hasSymbol) symbol = tree.symbol this @@ -241,6 +249,34 @@ trait Trees { self: Universe => override def equals(that: Any) = this eq that.asInstanceOf[AnyRef] } + // [Eugene] uh-oh + // locker.comp: + // [mkdir] Created dir: C:\Projects\Kepler\build\locker\classes\compiler + // [scalacfork] Compiling 471 files to C:\Projects\Kepler\build\locker\classes\compiler + // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree + // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree + // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree + // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree + // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree + // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree + // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree + // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree + // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree + // [scalacfork] amb prefix: Importers.this.type#class Tree Importer.this.from.type#class Tree +// object Tree { +// // would be great if in future this generated an Expr[Magic] +// // where Magic is a magic untyped type that propagates through the entire quasiquote +// // and turns off typechecking whenever it's involved +// // that'd allow us to splice trees into quasiquotes and still have these qqs to be partially typechecked +// // see some exploration of these ideas here: https://github.com/xeno-by/alphakeplerdemo +// implicit def tree2expr(tree: Tree): Expr[Nothing] = Expr[Nothing](tree) +// implicit def expr2tree(expr: Expr[_]): Tree = expr.tree +// +// // [Eugene] good idea? +// implicit def trees2exprs(trees: List[Tree]): List[Expr[Nothing]] = trees map tree2expr +// implicit def exprs2trees(exprs: List[Expr[_]]): List[Tree] = exprs map expr2tree +// } + /** A tree for a term. Not all terms are TermTrees; use isTerm * to reliably identify terms. */ @@ -258,18 +294,24 @@ trait Trees { self: Universe => override var symbol: Symbol = NoSymbol } + /** A tree with a name - effectively, a DefTree or RefTree. + */ + trait NameTree extends Tree { + def name: Name + } + /** A tree which references a symbol-carrying entity. * References one, as opposed to defining one; definitions * are in DefTrees. */ - trait RefTree extends SymTree { + trait RefTree extends SymTree with NameTree { def qualifier: Tree // empty for Idents def name: Name } /** A tree which defines a symbol-carrying entity. */ - abstract class DefTree extends SymTree { + abstract class DefTree extends SymTree with NameTree { def name: Name override def isDef = true } @@ -319,12 +361,23 @@ trait Trees { self: Universe => case class ClassDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], impl: Template) extends ImplDef + /** @param sym the class symbol + * @return the implementation template + */ + def ClassDef(sym: Symbol, impl: Template): ClassDef + /** An object definition, e.g. `object Foo`. Internally, objects are * quite frequently called modules to reduce ambiguity. */ case class ModuleDef(mods: Modifiers, name: TermName, impl: Template) extends ImplDef + /** + * @param sym the class symbol + * @param impl the implementation template + */ + def ModuleDef(sym: Symbol, impl: Template): ModuleDef + /** A common base class for ValDefs and DefDefs. */ abstract class ValOrDefDef extends MemberDef { @@ -343,17 +396,37 @@ trait Trees { self: Universe => */ case class ValDef(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree) extends ValOrDefDef + def ValDef(sym: Symbol, rhs: Tree): ValDef + + def ValDef(sym: Symbol): ValDef + /** A method or macro definition. * @param name The name of the method or macro. Can be a type name in case this is a type macro */ case class DefDef(mods: Modifiers, name: Name, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree) extends ValOrDefDef + def DefDef(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree): DefDef + + def DefDef(sym: Symbol, vparamss: List[List[ValDef]], rhs: Tree): DefDef + + def DefDef(sym: Symbol, mods: Modifiers, rhs: Tree): DefDef + + def DefDef(sym: Symbol, rhs: Tree): DefDef + + def DefDef(sym: Symbol, rhs: List[List[Symbol]] => Tree): DefDef + /** An abstract type, a type parameter, or a type alias. */ case class TypeDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], rhs: Tree) extends MemberDef + /** A TypeDef node which defines given `sym` with given tight hand side `rhs`. */ + def TypeDef(sym: Symbol, rhs: Tree): TypeDef + + /** A TypeDef node which defines abstract type or type parameter for given `sym` */ + def TypeDef(sym: Symbol): TypeDef + /** A labelled expression. Not expressible in language syntax, but * generated by the compiler to simulate while/do-while loops, and * also by the pattern matcher. @@ -371,6 +444,8 @@ trait Trees { self: Universe => case class LabelDef(name: TermName, params: List[Ident], rhs: Tree) extends DefTree with TermTree + def LabelDef(sym: Symbol, params: List[Symbol], rhs: Tree): LabelDef + /** Import selector * * Representation of an imported name its optional rename and their optional positions @@ -415,12 +490,19 @@ trait Trees { self: Universe => case class Block(stats: List[Tree], expr: Tree) extends TermTree + /** Block factory that flattens directly nested blocks. + */ + def Block(stats: Tree*): Block + /** Case clause in a pattern match, eliminated during explicitouter * (except for occurrences in switch statements) */ case class CaseDef(pat: Tree, guard: Tree, body: Tree) extends Tree + /** casedef shorthand */ + def CaseDef(pat: Tree, body: Tree): CaseDef + /** Alternatives of patterns, eliminated by explicitouter, except for * occurrences in encoded Switch stmt (=remaining Match(CaseDef(...)) */ @@ -439,6 +521,8 @@ trait Trees { self: Universe => case class Bind(name: Name, body: Tree) extends DefTree + def Bind(sym: Symbol, body: Tree): Bind + case class UnApply(fun: Tree, args: List[Tree]) extends TermTree @@ -489,10 +573,14 @@ trait Trees { self: Universe => case class Try(block: Tree, catches: List[CaseDef], finalizer: Tree) extends TermTree + def Try(body: Tree, cases: (Tree, Tree)*): Try + /** Throw expression */ case class Throw(expr: Tree) extends TermTree + def Throw(tpe: Type, args: Tree*): Throw + /** Object instantiation * One should always use factory method below to build a user level new. * @@ -503,14 +591,13 @@ trait Trees { self: Universe => /** Factory method for object creation `new tpt(args_1)...(args_n)` * A `New(t, as)` is expanded to: `(new t).<init>(as)` */ - def New(tpt: Tree, argss: List[List[Tree]]): Tree = argss match { - case Nil => new ApplyConstructor(tpt, Nil) - case xs :: rest => rest.foldLeft(new ApplyConstructor(tpt, xs): Tree)(Apply) - } + def New(tpt: Tree, argss: List[List[Tree]]): Tree + /** 0-1 argument list new, based on a type. */ - def New(tpe: Type, args: Tree*): Tree = - new ApplyConstructor(TypeTree(tpe), args.toList) + def New(tpe: Type, args: Tree*): Tree + + def New(sym: Symbol, args: Tree*): Tree /** Type annotation, eliminated by explicit outer */ case class Typed(expr: Tree, tpt: Tree) @@ -545,6 +632,8 @@ trait Trees { self: Universe => override def symbol_=(sym: Symbol) { fun.symbol = sym } } + def Apply(sym: Symbol, args: Tree*): Tree + class ApplyToImplicitArgs(fun: Tree, args: List[Tree]) extends Apply(fun, args) class ApplyImplicitView(fun: Tree, args: List[Tree]) extends Apply(fun, args) @@ -563,7 +652,9 @@ trait Trees { self: Universe => extends TermTree with SymTree // The symbol of an ApplyDynamic is the function symbol of `qual`, or NoSymbol, if there is none. - /** Super reference, qual = corresponding this reference */ + /** Super reference, qual = corresponding this reference + * A super reference C.super[M] is represented as Super(This(C), M). + */ case class Super(qual: Tree, mix: TypeName) extends TermTree { // The symbol of a Super is the class _from_ which the super reference is made. // For instance in C.super(...), it would be C. @@ -571,38 +662,47 @@ trait Trees { self: Universe => override def symbol_=(sym: Symbol) { qual.symbol = sym } } + def Super(sym: Symbol, mix: TypeName): Tree + /** Self reference */ case class This(qual: TypeName) extends TermTree with SymTree // The symbol of a This is the class to which the this refers. // For instance in C.this, it would be C. - def This(sym: Symbol): Tree = - This(sym.name.toTypeName) setSymbol sym + def This(sym: Symbol): Tree /** Designator <qualifier> . <name> */ case class Select(qualifier: Tree, name: Name) extends RefTree - def Select(qualifier: Tree, name: String): Select = - Select(qualifier, newTermName(name)) + def Select(qualifier: Tree, name: String): Select - def Select(qualifier: Tree, sym: Symbol): Select = - Select(qualifier, sym.name) setSymbol sym + def Select(qualifier: Tree, sym: Symbol): Select /** Identifier <name> */ case class Ident(name: Name) extends RefTree { def qualifier: Tree = EmptyTree } - def Ident(name: String): Ident = - Ident(newTermName(name)) + def Ident(name: String): Ident - def Ident(sym: Symbol): Ident = - Ident(sym.name) setSymbol sym + def Ident(sym: Symbol): Ident class BackQuotedIdent(name: Name) extends Ident(name) + /** Marks underlying reference to id as boxed. + * @pre: id must refer to a captured variable + * A reference such marked will refer to the boxed entity, no dereferencing + * with `.elem` is done on it. + * This tree node can be emitted by macros such as reify that call referenceCapturedVariable. + * It is eliminated in LambdaLift, where the boxing conversion takes place. + */ + case class ReferenceToBoxed(ident: Ident) extends TermTree { + override def symbol: Symbol = ident.symbol + override def symbol_=(sym: Symbol) { ident.symbol = sym } + } + /** Literal */ case class Literal(value: Constant) extends TermTree { @@ -873,6 +973,8 @@ trait Trees { self: Universe => traverse(qualifier) case Ident(_) => ; + case ReferenceToBoxed(idt) => + traverse(idt) case Literal(_) => ; case TypeTree() => @@ -958,6 +1060,7 @@ trait Trees { self: Universe => def This(tree: Tree, qual: Name): This def Select(tree: Tree, qualifier: Tree, selector: Name): Select def Ident(tree: Tree, name: Name): Ident + def ReferenceToBoxed(tree: Tree, idt: Ident): ReferenceToBoxed def Literal(tree: Tree, value: Constant): Literal def TypeTree(tree: Tree): TypeTree def Annotated(tree: Tree, annot: Tree, arg: Tree): Annotated @@ -1040,6 +1143,8 @@ trait Trees { self: Universe => new Select(qualifier, selector).copyAttrs(tree) def Ident(tree: Tree, name: Name) = new Ident(name).copyAttrs(tree) + def ReferenceToBoxed(tree: Tree, idt: Ident) = + new ReferenceToBoxed(idt).copyAttrs(tree) def Literal(tree: Tree, value: Constant) = new Literal(value).copyAttrs(tree) def TypeTree(tree: Tree) = @@ -1228,6 +1333,11 @@ trait Trees { self: Universe => if name0 == name => t case _ => treeCopy.Ident(tree, name) } + def ReferenceToBoxed(tree: Tree, idt: Ident) = tree match { + case t @ ReferenceToBoxed(idt0) + if (idt0 == idt) => t + case _ => this.treeCopy.ReferenceToBoxed(tree, idt) + } def Literal(tree: Tree, value: Constant) = tree match { case t @ Literal(value0) if value0 == value => t @@ -1372,6 +1482,8 @@ trait Trees { self: Universe => treeCopy.Select(tree, transform(qualifier), selector) case Ident(name) => treeCopy.Ident(tree, name) + case ReferenceToBoxed(idt) => + treeCopy.ReferenceToBoxed(tree, transform(idt) match { case idt1: Ident => idt1 }) case Literal(value) => treeCopy.Literal(tree, value) case TypeTree() => @@ -1413,7 +1525,7 @@ trait Trees { self: Universe => def transformStats(stats: List[Tree], exprOwner: Symbol): List[Tree] = stats mapConserve (stat => if (exprOwner != currentOwner && stat.isTerm) atOwner(exprOwner)(transform(stat)) - else transform(stat)) filter (EmptyTree !=) + else transform(stat)) filter (EmptyTree != _) def transformModifiers(mods: Modifiers): Modifiers = mods.mapAnnotations(transformTrees) @@ -1443,6 +1555,14 @@ trait Trees { self: Universe => } } + class CollectTreeTraverser[T](pf: PartialFunction[Tree, T]) extends Traverser { + val results = new ListBuffer[T] + override def traverse(t: Tree) { + if (pf.isDefinedAt(t)) results += pf(t) + super.traverse(t) + } + } + class FindTreeTraverser(p: Tree => Boolean) extends Traverser { var result: Option[Tree] = None override def traverse(t: Tree) { @@ -1535,7 +1655,7 @@ trait Trees { self: Universe => case ApplyDynamic(qual, args) (introduced by erasure, eliminated by cleanup) // fun(args) case Super(qual, mix) => - // qual.super[mix] if qual and/or mix is empty, ther are tpnme.EMPTY + // qual.super[mix] qual is always This(something), if mix is empty, it is tpnme.EMPTY case This(qual) => // qual.this case Select(qualifier, selector) => @@ -1544,6 +1664,10 @@ trait Trees { self: Universe => // name // note: type checker converts idents that refer to enclosing fields or methods // to selects; name ==> this.name + case ReferenceToBoxed(ident) => (created by typer, eliminated by lambdalift) + // synthetic node emitted by macros to reference capture vars directly without going through ``elem'' + // var x = ...; fun { x } will emit Ident(x), which gets transformed to Select(Ident(x), "elem") + // if ReferenceToBoxed were used instead of Ident, no transformation would be performed case Literal(value) => // value case TypeTree() => (introduced by refcheck) diff --git a/src/library/scala/reflect/api/TypeTags.scala b/src/library/scala/reflect/api/TypeTags.scala new file mode 100644 index 0000000000..4ffabe1c36 --- /dev/null +++ b/src/library/scala/reflect/api/TypeTags.scala @@ -0,0 +1,195 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2011 LAMP/EPFL + * @author Martin Odersky + */ + +package scala.reflect +package api + +import scala.reflect.{ mirror => rm } +import language.implicitConversions + +/** + * Type tags encapsulate a representation of type T. + * They are supposed to replace the pre-2.10 concept of a [[scala.reflect.Manifest]]. + * TypeTags are much better integrated with reflection than manifests are, and are consequently much simpler. + * + * Type tags are organized in a hierarchy of two classes: + * [[scala.reflect.api.Universe#TypeTag]] and [[scala.reflect.api.Universe#ConcreteTypeTag]]. + * A [[scala.reflect.api.Universe#TypeTag]] value wraps a full Scala type in its tpe field. + * A [[scala.reflect.api.Universe#ConcreteTypeTag]] value is a type tag that is guaranteed not to contain any references to type parameters or abstract types. + * + * It is also possible to capture Java classes by using a different kind of tag. + * A [[scala.reflect.ClassTag]] value wraps a Java class, which can be accessed via the erasure method. + * + * TypeTags correspond loosely to Manifests. More precisely: + * The previous notion of a [[scala.reflect.ClassManifest]] corresponds to a scala.reflect.ClassTag, + * The previous notion of a [[scala.reflect.Manifest]] corresponds to scala.reflect.mirror.ConcreteTypeTag, + * Whereas scala.reflect.mirror.TypeTag is approximated by the previous notion of [[scala.reflect.OptManifest]]. + * + * Implicit in the contract for all Tag classes is that the reified type tpe represents the type parameter T. + * Tags are typically created by the compiler, which makes sure that this contract is kept. + * + * An example that illustrates the TypeTag embedding, consider the following function: + * + * import reflect.mirror._ + * def f[T: TypeTag, U] = { + * type L = T => U + * implicitly[TypeTag[L]] + * } + * + * Then a call of f[String, Int] will yield a result of the form + * + * TypeTag(<[ String => U ]>). + * + * Note that T has been replaced by String, because it comes with a TypeTag in f, whereas U was left as a type parameter. + */ +trait TypeTags { self: Universe => + + /** + * If an implicit value of type u.TypeTag[T] is required, the compiler will make one up on demand. + * The implicitly created value contains in its tpe field a value of type u.Type that is a reflective representation of T. + * In that value, any occurrences of type parameters or abstract types U + * which come themselves with a TypeTag are represented by the type referenced by that TypeTag. + * + * @see [[scala.reflect.api.TypeTags]] + */ + @annotation.implicitNotFound(msg = "No TypeTag available for ${T}") + abstract case class TypeTag[T](tpe: Type) { + // it's unsafe to use assert here, because we might run into deadlocks with Predef + // also see comments in ClassTags.scala + // assert(tpe != null) + + def sym = tpe.typeSymbol + + def isConcrete = !isNotConcrete + def isNotConcrete = tpe exists (_.typeSymbol.isAbstractType) + def toConcrete: ConcreteTypeTag[T] = ConcreteTypeTag[T](tpe) + + override def toString = { + var prefix = if (isConcrete) "ConcreteTypeTag" else "TypeTag" + if (prefix != this.productPrefix) prefix = "*" + prefix + prefix + "[" + tpe + "]" + } + } + + object TypeTag { + val Byte : TypeTag[scala.Byte] = ConcreteTypeTag.Byte + val Short : TypeTag[scala.Short] = ConcreteTypeTag.Short + val Char : TypeTag[scala.Char] = ConcreteTypeTag.Char + val Int : TypeTag[scala.Int] = ConcreteTypeTag.Int + val Long : TypeTag[scala.Long] = ConcreteTypeTag.Long + val Float : TypeTag[scala.Float] = ConcreteTypeTag.Float + val Double : TypeTag[scala.Double] = ConcreteTypeTag.Double + val Boolean : TypeTag[scala.Boolean] = ConcreteTypeTag.Boolean + val Unit : TypeTag[scala.Unit] = ConcreteTypeTag.Unit + val Any : TypeTag[scala.Any] = ConcreteTypeTag.Any + val Object : TypeTag[java.lang.Object] = ConcreteTypeTag.Object + val AnyVal : TypeTag[scala.AnyVal] = ConcreteTypeTag.AnyVal + val AnyRef : TypeTag[scala.AnyRef] = ConcreteTypeTag.AnyRef + val Nothing : TypeTag[scala.Nothing] = ConcreteTypeTag.Nothing + val Null : TypeTag[scala.Null] = ConcreteTypeTag.Null + val String : TypeTag[java.lang.String] = ConcreteTypeTag.String + + def apply[T](tpe: Type): TypeTag[T] = + tpe match { + case ByteTpe => TypeTag.Byte.asInstanceOf[TypeTag[T]] + case ShortTpe => TypeTag.Short.asInstanceOf[TypeTag[T]] + case CharTpe => TypeTag.Char.asInstanceOf[TypeTag[T]] + case IntTpe => TypeTag.Int.asInstanceOf[TypeTag[T]] + case LongTpe => TypeTag.Long.asInstanceOf[TypeTag[T]] + case FloatTpe => TypeTag.Float.asInstanceOf[TypeTag[T]] + case DoubleTpe => TypeTag.Double.asInstanceOf[TypeTag[T]] + case BooleanTpe => TypeTag.Boolean.asInstanceOf[TypeTag[T]] + case UnitTpe => TypeTag.Unit.asInstanceOf[TypeTag[T]] + case AnyTpe => TypeTag.Any.asInstanceOf[TypeTag[T]] + case ObjectTpe => TypeTag.Object.asInstanceOf[TypeTag[T]] + case AnyValTpe => TypeTag.AnyVal.asInstanceOf[TypeTag[T]] + case AnyRefTpe => TypeTag.AnyRef.asInstanceOf[TypeTag[T]] + case NothingTpe => TypeTag.Nothing.asInstanceOf[TypeTag[T]] + case NullTpe => TypeTag.Null.asInstanceOf[TypeTag[T]] + case StringTpe => TypeTag.String.asInstanceOf[TypeTag[T]] + case _ => new TypeTag[T](tpe) {} + } + } + + /** + * If an implicit value of type u.ConcreteTypeTag[T] is required, the compiler will make one up on demand following the same procedure as for TypeTags. + * However, if the resulting type still contains references to type parameters or abstract types, a static error results. + * + * @see [[scala.reflect.api.TypeTags]] + */ + @annotation.implicitNotFound(msg = "No ConcreteTypeTag available for ${T}") + class ConcreteTypeTag[T](tpe: Type) extends TypeTag[T](tpe) { + // it's unsafe to use assert here, because we might run into deadlocks with Predef + // also see comments in ClassTags.scala + //assert(isConcrete, tpe) + if (isNotConcrete) throw new Error("%s (%s) is not concrete and cannot be used to construct a concrete type tag".format(tpe, tpe.kind)) + override def productPrefix = "ConcreteTypeTag" + } + + object ConcreteTypeTag { + val Byte : ConcreteTypeTag[scala.Byte] = new ConcreteTypeTag[scala.Byte](ByteTpe) { private def readResolve() = ConcreteTypeTag.Byte } + val Short : ConcreteTypeTag[scala.Short] = new ConcreteTypeTag[scala.Short](ShortTpe) { private def readResolve() = ConcreteTypeTag.Short } + val Char : ConcreteTypeTag[scala.Char] = new ConcreteTypeTag[scala.Char](CharTpe) { private def readResolve() = ConcreteTypeTag.Char } + val Int : ConcreteTypeTag[scala.Int] = new ConcreteTypeTag[scala.Int](IntTpe) { private def readResolve() = ConcreteTypeTag.Int } + val Long : ConcreteTypeTag[scala.Long] = new ConcreteTypeTag[scala.Long](LongTpe) { private def readResolve() = ConcreteTypeTag.Long } + val Float : ConcreteTypeTag[scala.Float] = new ConcreteTypeTag[scala.Float](FloatTpe) { private def readResolve() = ConcreteTypeTag.Float } + val Double : ConcreteTypeTag[scala.Double] = new ConcreteTypeTag[scala.Double](DoubleTpe) { private def readResolve() = ConcreteTypeTag.Double } + val Boolean : ConcreteTypeTag[scala.Boolean] = new ConcreteTypeTag[scala.Boolean](BooleanTpe) { private def readResolve() = ConcreteTypeTag.Boolean } + val Unit : ConcreteTypeTag[scala.Unit] = new ConcreteTypeTag[scala.Unit](UnitTpe) { private def readResolve() = ConcreteTypeTag.Unit } + val Any : ConcreteTypeTag[scala.Any] = new ConcreteTypeTag[scala.Any](AnyTpe) { private def readResolve() = ConcreteTypeTag.Any } + val Object : ConcreteTypeTag[java.lang.Object] = new ConcreteTypeTag[java.lang.Object](ObjectTpe) { private def readResolve() = ConcreteTypeTag.Object } + val AnyVal : ConcreteTypeTag[scala.AnyVal] = new ConcreteTypeTag[scala.AnyVal](AnyValTpe) { private def readResolve() = ConcreteTypeTag.AnyVal } + val AnyRef : ConcreteTypeTag[scala.AnyRef] = new ConcreteTypeTag[scala.AnyRef](AnyRefTpe) { private def readResolve() = ConcreteTypeTag.AnyRef } + val Nothing : ConcreteTypeTag[scala.Nothing] = new ConcreteTypeTag[scala.Nothing](NothingTpe) { private def readResolve() = ConcreteTypeTag.Nothing } + val Null : ConcreteTypeTag[scala.Null] = new ConcreteTypeTag[scala.Null](NullTpe) { private def readResolve() = ConcreteTypeTag.Null } + val String : ConcreteTypeTag[java.lang.String] = new ConcreteTypeTag[java.lang.String](StringTpe) { private def readResolve() = ConcreteTypeTag.String } + + def apply[T](tpe: Type): ConcreteTypeTag[T] = + tpe match { + case ByteTpe => ConcreteTypeTag.Byte.asInstanceOf[ConcreteTypeTag[T]] + case ShortTpe => ConcreteTypeTag.Short.asInstanceOf[ConcreteTypeTag[T]] + case CharTpe => ConcreteTypeTag.Char.asInstanceOf[ConcreteTypeTag[T]] + case IntTpe => ConcreteTypeTag.Int.asInstanceOf[ConcreteTypeTag[T]] + case LongTpe => ConcreteTypeTag.Long.asInstanceOf[ConcreteTypeTag[T]] + case FloatTpe => ConcreteTypeTag.Float.asInstanceOf[ConcreteTypeTag[T]] + case DoubleTpe => ConcreteTypeTag.Double.asInstanceOf[ConcreteTypeTag[T]] + case BooleanTpe => ConcreteTypeTag.Boolean.asInstanceOf[ConcreteTypeTag[T]] + case UnitTpe => ConcreteTypeTag.Unit.asInstanceOf[ConcreteTypeTag[T]] + case AnyTpe => ConcreteTypeTag.Any.asInstanceOf[ConcreteTypeTag[T]] + case ObjectTpe => ConcreteTypeTag.Object.asInstanceOf[ConcreteTypeTag[T]] + case AnyValTpe => ConcreteTypeTag.AnyVal.asInstanceOf[ConcreteTypeTag[T]] + case AnyRefTpe => ConcreteTypeTag.AnyRef.asInstanceOf[ConcreteTypeTag[T]] + case NothingTpe => ConcreteTypeTag.Nothing.asInstanceOf[ConcreteTypeTag[T]] + case NullTpe => ConcreteTypeTag.Null.asInstanceOf[ConcreteTypeTag[T]] + case StringTpe => ConcreteTypeTag.String.asInstanceOf[ConcreteTypeTag[T]] + case _ => new ConcreteTypeTag[T](tpe) {} + } + + def unapply[T](ttag: TypeTag[T]): Option[Type] = if (ttag.isConcrete) Some(ttag.tpe) else None + + implicit def toClassTag[T](ttag: rm.ConcreteTypeTag[T]): ClassTag[T] = ClassTag[T](rm.typeToClass(ttag.tpe.erasure)) + + implicit def toDeprecatedManifestApis[T](ttag: rm.ConcreteTypeTag[T]): DeprecatedManifestApis[T] = new DeprecatedManifestApis[T](ttag) + + // this class should not be used directly in client code + class DeprecatedManifestApis[T](ttag: rm.ConcreteTypeTag[T]) extends DeprecatedClassManifestApis[T](toClassTag(ttag)) { + @deprecated("Use `tpe` to analyze the underlying type", "2.10.0") + def <:<(that: Manifest[_]): Boolean = ttag.tpe <:< that.tpe + + @deprecated("Use `tpe` to analyze the underlying type", "2.10.0") + def >:>(that: Manifest[_]): Boolean = that <:< ttag + + @deprecated("Use `tpe` to analyze the type arguments", "2.10.0") + override def typeArguments: List[Manifest[_]] = ttag.tpe.typeArguments map (targ => rm.ConcreteTypeTag(targ)) + } + } + + // incantations for summoning + // moved to Context, since rm.tags have their own incantations in Predef, and these guys are only useful in macros +// def tag[T](implicit ttag: TypeTag[T]) = ttag +// def typeTag[T](implicit ttag: TypeTag[T]) = ttag +// def concreteTag[T](implicit gttag: ConcreteTypeTag[T]) = cttag +// def concreteTypeTag[T](implicit gttag: ConcreteTypeTag[T]) = cttag +} diff --git a/src/library/scala/reflect/api/Types.scala b/src/library/scala/reflect/api/Types.scala index 0371e2c5df..12aad453b1 100755 --- a/src/library/scala/reflect/api/Types.scala +++ b/src/library/scala/reflect/api/Types.scala @@ -105,7 +105,8 @@ trait Types { self: Universe => /** The erased type corresponding to this type after * all transformations from Scala to Java have been performed. */ - def erasedType: Type // !!! "erasedType", compare with "widen" (so "erase") or "underlying" (so "erased") + def erasure: Type // !!! "erasedType", compare with "widen" (so "erase") or "underlying" (so "erased") + // why not name it "erasure"? /** Apply `f` to each part of this type, returning * a new type. children get mapped before their parents */ @@ -146,6 +147,33 @@ trait Types { self: Universe => * <o.x.type>.widen = o.C */ def widen: Type + + /** The kind of this type; used for debugging */ + def kind: String + } + + /** An object representing an unknown type, used during type inference. + * If you see WildcardType outside of inference it is almost certainly a bug. + */ + val WildcardType: Type + + /** BoundedWildcardTypes, used only during type inference, are created in + * two places that I can find: + * + * 1. If the expected type of an expression is an existential type, + * its hidden symbols are replaced with bounded wildcards. + * 2. When an implicit conversion is being sought based in part on + * the name of a method in the converted type, a HasMethodMatching + * type is created: a MethodType with parameters typed as + * BoundedWildcardTypes. + */ + type BoundedWildcardType >: Null <: Type + + val BoundedWildcardType: BoundedWildcardTypeExtractor + + abstract class BoundedWildcardTypeExtractor { + def apply(bounds: TypeBounds): BoundedWildcardType + def unapply(tpe: BoundedWildcardType): Option[TypeBounds] } /** The type of Scala types, and also Scala type signatures. @@ -424,5 +452,66 @@ trait Types { self: Universe => /** The greatest lower bound wrt <:< of a list of types */ def glb(ts: List[Type]): Type + + // Creators --------------------------------------------------------------- + // too useful and too non-trivial to be left out of public API + // [Eugene to Paul] needs review! + + /** The canonical creator for single-types */ + def singleType(pre: Type, sym: Symbol): Type + + /** the canonical creator for a refined type with a given scope */ + def refinedType(parents: List[Type], owner: Symbol, decls: Scope, pos: Position): Type + + /** The canonical creator for a refined type with an initially empty scope. + * + * @param parents ... + * @param owner ... + * @return ... + */ + def refinedType(parents: List[Type], owner: Symbol): Type + + /** The canonical creator for typerefs + */ + def typeRef(pre: Type, sym: Symbol, args: List[Type]): Type + + /** A creator for intersection type where intersections of a single type are + * replaced by the type itself. */ + def intersectionType(tps: List[Type]): Type + + /** A creator for intersection type where intersections of a single type are + * replaced by the type itself, and repeated parent classes are merged. + * + * !!! Repeated parent classes are not merged - is this a bug in the + * comment or in the code? + */ + def intersectionType(tps: List[Type], owner: Symbol): Type + + /** A creator for type applications */ + def appliedType(tycon: Type, args: List[Type]): Type + + /** A creator for type parameterizations that strips empty type parameter lists. + * Use this factory method to indicate the type has kind * (it's a polymorphic value) + * until we start tracking explicit kinds equivalent to typeFun (except that the latter requires tparams nonEmpty). + */ + def polyType(tparams: List[Symbol], tpe: Type): Type + + /** A creator for existential types. This generates: + * + * tpe1 where { tparams } + * + * where `tpe1` is the result of extrapolating `tpe` wrt to `tparams`. + * Extrapolating means that type variables in `tparams` occurring + * in covariant positions are replaced by upper bounds, (minus any + * SingletonClass markers), type variables in `tparams` occurring in + * contravariant positions are replaced by upper bounds, provided the + * resulting type is legal wrt to stability, and does not contain any type + * variable in `tparams`. + * + * The abstraction drops all type parameters that are not directly or + * indirectly referenced by type `tpe1`. If there are no remaining type + * parameters, simply returns result type `tpe`. + */ + def existentialAbstraction(tparams: List[Symbol], tpe0: Type): Type } diff --git a/src/library/scala/reflect/api/Universe.scala b/src/library/scala/reflect/api/Universe.scala index a3cec3271b..d1f546608e 100755 --- a/src/library/scala/reflect/api/Universe.scala +++ b/src/library/scala/reflect/api/Universe.scala @@ -1,19 +1,89 @@ package scala.reflect package api +import language.experimental.macros abstract class Universe extends Symbols + with FreeVars with Types with Constants with Scopes with Names with Trees - with Positions - with TreePrinters with AnnotationInfos + with Positions + with Exprs with StandardDefinitions - with StandardNames { - type Position - val NoPosition: Position + with TypeTags + with TreePrinters + with StandardNames + with ClassLoaders + with TreeBuildUtil + with ToolBoxes + with Reporters + with Importers { + /** Given an expression, generate a tree that when compiled and executed produces the original tree. + * The produced tree will be bound to the Universe it was called from. + * + * For instance, given the abstract syntax tree representation of the <[ x + 1 ]> expression: + * + * Apply(Select(Ident("x"), "+"), List(Literal(Constant(1)))) + * + * The reifier transforms it to the following expression: + * + * <[ + * val $mr: scala.reflect.api.Universe = <reference to the Universe that calls the reify> + * $mr.Expr[Int]($mr.Apply($mr.Select($mr.Ident($mr.newFreeVar("x", <Int>, x), "+"), List($mr.Literal($mr.Constant(1)))))) + * ]> + * + * Reification performs expression splicing (when processing Expr.eval and Expr.value) + * and type splicing (for every type T that has a TypeTag[T] implicit in scope): + * + * val two = mirror.reify(2) // Literal(Constant(2)) + * val four = mirror.reify(two.eval + two.eval) // Apply(Select(two.tree, newTermName("$plus")), List(two.tree)) + * + * def macroImpl[T](c: Context) = { + * ... + * // T here is just a type parameter, so the tree produced by reify won't be of much use in a macro expansion + * // however, if T were annotated with c.TypeTag (which would declare an implicit parameter for macroImpl) + * // then reification would subtitute T with the TypeTree that was used in a TypeApply of this particular macro invocation + * val factory = c.reify{ new Queryable[T] } + * ... + * } + * + * The transformation looks mostly straightforward, but it has its tricky parts: + * * Reifier retains symbols and types defined outside the reified tree, however + * locally defined entities get erased and replaced with their original trees + * * Free variables are detected and wrapped in symbols of the type FreeVar + * * Mutable variables that are accessed from a local function are wrapped in refs + * * Since reified trees can be compiled outside of the scope they've been created in, + * special measures are taken to ensure that all members accessed in the reifee remain visible + */ + def reify[T](expr: T): Expr[T] = macro Universe.reify[T] } +object Universe { + def reify[T](cc: scala.reflect.makro.Context{ type PrefixType = Universe })(expr: cc.Expr[T]): cc.Expr[cc.prefix.value.Expr[T]] = { + import cc.mirror._ + try cc.reifyTree(cc.prefix, expr) + catch { + case ex: Throwable => + // [Eugene] cannot pattern match on an abstract type, so had to do this + val ex1 = ex + if (ex.getClass.toString.endsWith("$ReificationError")) { + ex match { + case cc.ReificationError(pos, msg) => + cc.error(pos, msg) + EmptyTree + } + } else if (ex.getClass.toString.endsWith("$UnexpectedReificationError")) { + ex match { + case cc.UnexpectedReificationError(pos, err, cause) => + if (cause != null) throw cause else throw ex + } + } else { + throw ex + } + } + } +} diff --git a/src/library/scala/reflect/macro/Context.scala b/src/library/scala/reflect/macro/Context.scala deleted file mode 100644 index 2fd9bb6484..0000000000 --- a/src/library/scala/reflect/macro/Context.scala +++ /dev/null @@ -1,36 +0,0 @@ -package scala.reflect -package macro - -trait Context extends api.Universe { - - /** Mark a variable as captured; i.e. force boxing in a *Ref type. - */ - def captureVariable(vble: Symbol): Unit - - /** Mark given identifier as a reference to a captured variable itself - * suppressing dereferencing with the `elem` field. - */ - def referenceCapturedVariable(id: Ident): Tree - - /** Given a tree or type, generate a tree that when executed at runtime produces the original tree or type. - * For instance, given the abstract syntax tree representation of the `x + 1` expression: - * - * Apply(Select(Ident("x"), "+"), List(Literal(Constant(1)))) - * - * The reifier transforms it to the following tree: - * - * $mr.Apply($mr.Select($mr.Ident($mr.newFreeVar("x", <Int>, x), "+"), List($mr.Literal($mr.Constant(1)))))) - * - * The transformation looks mostly straightforward, but it has its tricky parts: - * * Reifier retains symbols and types defined outside the reified tree, however - * locally defined entities get erased and replaced with their original trees - * * Free variables are detected and wrapped in symbols of the type FreeVar - * * Mutable variables that are accessed from a local function are wrapped in refs - * * Since reified trees can be compiled outside of the scope they've been created in, - * special measures are taken to ensure that all freeVars remain visible - * - * Typical usage of this function is to retain some of the trees received/created by a macro - * into the form that can be inspected (via pattern matching) or compiled/run (by a reflective ToolBox) during the runtime. - */ - def reify(tree: Tree): Tree -} diff --git a/src/library/scala/reflect/makro/Aliases.scala b/src/library/scala/reflect/makro/Aliases.scala new file mode 100644 index 0000000000..38b1065a40 --- /dev/null +++ b/src/library/scala/reflect/makro/Aliases.scala @@ -0,0 +1,26 @@ +package scala.reflect.makro + +trait Aliases { + self: Context => + + /** Aliases of mirror types */ + type Symbol = mirror.Symbol + type Type = mirror.Type + type Name = mirror.Name + type Tree = mirror.Tree + type Position = mirror.Position + type Scope = mirror.Scope + type Modifiers = mirror.Modifiers + type Expr[+T] = mirror.Expr[T] + type TypeTag[T] = mirror.TypeTag[T] + + /** Creator/extractor objects for Expr and TypeTag values */ + val TypeTag = mirror.TypeTag + val Expr = mirror.Expr + + /** incantations for summoning tags */ + def tag[T](implicit ttag: TypeTag[T]) = ttag + def typeTag[T](implicit ttag: TypeTag[T]) = ttag + def concreteTag[T](implicit cttag: ConcreteTypeTag[T]) = cttag + def concreteTypeTag[T](implicit cttag: ConcreteTypeTag[T]) = cttag +} diff --git a/src/library/scala/reflect/makro/CapturedVariables.scala b/src/library/scala/reflect/makro/CapturedVariables.scala new file mode 100644 index 0000000000..6ce832b2b3 --- /dev/null +++ b/src/library/scala/reflect/makro/CapturedVariables.scala @@ -0,0 +1,20 @@ +package scala.reflect.makro + +trait CapturedVariables { + self: Context => + + import mirror._ + + /** Mark a variable as captured; i.e. force boxing in a *Ref type. + */ + def captureVariable(vble: Symbol): Unit + + /** Mark given identifier as a reference to a captured variable itself + * suppressing dereferencing with the `elem` field. + */ + def referenceCapturedVariable(vble: Symbol): Tree + + /** Convert type of a captured variable to *Ref type. + */ + def capturedVariableType(vble: Symbol): Type +}
\ No newline at end of file diff --git a/src/library/scala/reflect/makro/Context.scala b/src/library/scala/reflect/makro/Context.scala new file mode 100644 index 0000000000..5ce801e2e6 --- /dev/null +++ b/src/library/scala/reflect/makro/Context.scala @@ -0,0 +1,61 @@ +package scala.reflect.makro + +import language.experimental.macros + +// todo. introduce context hierarchy +// the most lightweight context should just expose the stuff from the SIP +// the full context should include all traits from scala.reflect.makro (and probably reside in scala-compiler.jar) + +trait Context extends Aliases + with CapturedVariables + with Enclosures + with Infrastructure + with Names + with Reifiers + with Reporters + with Settings + with Symbols + with Typers + with Util { + + /** The mirror that corresponds to the compile-time universe */ + val mirror: scala.reflect.api.Universe + + /** The type of the prefix tree from which the macro is selected */ + type PrefixType + + /** The prefix tree from which the macro is selected */ + val prefix: Expr[PrefixType] + + /** Alias to the underlying mirror's reify */ + def reify[T](expr: T): Expr[T] = macro Context.reify[T] +} + +object Context { + def reify[T](cc: Context{ type PrefixType = Context })(expr: cc.Expr[T]): cc.Expr[cc.prefix.value.Expr[T]] = { + import cc.mirror._ + // [Eugene] how do I typecheck this without undergoing this tiresome (and, in general, incorrect) procedure? + val prefix: Tree = Select(cc.prefix, newTermName("mirror")) + val prefixTpe = cc.typeCheck(TypeApply(Select(prefix, newTermName("asInstanceOf")), List(SingletonTypeTree(prefix)))).tpe + prefix setType prefixTpe + try cc.reifyTree(prefix, expr) + catch { + case ex: Throwable => + // [Eugene] cannot pattern match on an abstract type, so had to do this + if (ex.getClass.toString.endsWith("$ReificationError")) { + ex match { + case cc.ReificationError(pos, msg) => + cc.error(pos, msg) + EmptyTree + } + } else if (ex.getClass.toString.endsWith("$UnexpectedReificationError")) { + ex match { + case cc.UnexpectedReificationError(pos, err, cause) => + if (cause != null) throw cause else throw ex + } + } else { + throw ex + } + } + } +} diff --git a/src/library/scala/reflect/makro/Enclosures.scala b/src/library/scala/reflect/makro/Enclosures.scala new file mode 100644 index 0000000000..136d39498e --- /dev/null +++ b/src/library/scala/reflect/makro/Enclosures.scala @@ -0,0 +1,53 @@ +package scala.reflect.makro + +trait Enclosures { + self: Context => + + /** The tree that undergoes macro expansion. + * Can be useful to get an offset or a range position of the entire tree being processed. + */ + val macroApplication: Tree + + /** Contexts that represent macros in-flight, including the current one. Very much like a stack trace, but for macros only. + * Can be useful for interoperating with other macros and for imposing compiler-friendly limits on macro expansion. + * + * Is also priceless for emitting sane error messages for macros that are called by other macros on synthetic (i.e. position-less) trees. + * In that dire case navigate the ``enclosingMacros'' stack, and it will most likely contain at least one macro with a position-ful macro application. + * See ``enclosingPosition'' for a default implementation of this logic. + * + * Unlike `openMacros`, this is a val, which means that it gets initialized when the context is created + * and always stays the same regardless of whatever happens during macro expansion. + */ + val enclosingMacros: List[Context] + + /** Types along with corresponding trees for which implicit arguments are currently searched. + * Can be useful to get information about an application with an implicit parameter that is materialized during current macro expansion. + * + * Unlike `openImplicits`, this is a val, which means that it gets initialized when the context is created + * and always stays the same regardless of whatever happens during macro expansion. + */ + val enclosingImplicits: List[(Type, Tree)] + + /** Tries to guess a position for the enclosing application. + * But that is simple, right? Just dereference ``pos'' of ``macroApplication''? Not really. + * If we're in a synthetic macro expansion (no positions), we must do our best to infer the position of something that triggerd this expansion. + * Surprisingly, quite often we can do this by navigation the ``enclosingMacros'' stack. + */ + val enclosingPosition: Position + + /** Tree that corresponds to the enclosing application, or EmptyTree if not applicable. + */ + val enclosingApplication: Tree + + /** Tree that corresponds to the enclosing method, or EmptyTree if not applicable. + */ + val enclosingMethod: Tree + + /** Tree that corresponds to the enclosing class, or EmptyTree if not applicable. + */ + val enclosingClass: Tree + + /** Compilation unit that contains this macro application. + */ + val enclosingUnit: CompilationUnit +}
\ No newline at end of file diff --git a/src/library/scala/reflect/makro/Infrastructure.scala b/src/library/scala/reflect/makro/Infrastructure.scala new file mode 100644 index 0000000000..2bf49dca77 --- /dev/null +++ b/src/library/scala/reflect/makro/Infrastructure.scala @@ -0,0 +1,73 @@ +package scala.reflect.makro + +trait Infrastructure { + self: Context => + + /** Determines whether the compiler expanding a macro targets JVM. + */ + val forJVM: Boolean + + /** Determines whether the compiler expanding a macro targets CLR. + */ + val forMSIL: Boolean + + /** Determines whether the compiler expanding a macro is a presentation compiler. + */ + val forInteractive: Boolean + + /** Determines whether the compiler expanding a macro is a Scaladoc compiler. + */ + val forScaladoc: Boolean + + /** Exposes current compilation run. + */ + val currentRun: Run + + /** As seen by macro API, compilation run is an opaque type that can be deconstructed into: + * 1) Current compilation unit + * 2) List of all compilation units that comprise the run + */ + type Run + + val Run: RunExtractor + + abstract class RunExtractor { + def unapply(run: Run): Option[(CompilationUnit, List[CompilationUnit])] + } + + /** As seen by macro API, compilation unit is an opaque type that can be deconstructed into: + * 1) File that corresponds to the unit (if not applicable, null) + * 2) Content of the file (if not applicable, empty array) + * 3) Body, i.e. the AST that represents the compilation unit + */ + type CompilationUnit + + val CompilationUnit: CompilationUnitExtractor + + abstract class CompilationUnitExtractor { + def unapply(compilationUnit: CompilationUnit): Option[(java.io.File, Array[Char], Tree)] + } + + /** Returns a macro definition which triggered this macro expansion. + */ + val currentMacro: Symbol + + // todo. redo caches as discussed on Reflecting Meeting 2012/03/29 + // https://docs.google.com/document/d/1oUZGQpdt2qwioTlJcSt8ZFQwVLTvpxn8xa67P8OGVpU/edit + + /** A cache shared by all invocations of all macros across all compilation runs. + * + * Needs to be used with extreme care, since memory leaks here will swiftly crash the presentation compiler. + * For example, Scala IDE typically launches a compiler run on every edit action so there might be hundreds of runs per minute. + */ + val globalCache: collection.mutable.Map[Any, Any] + + /** A cache shared by all invocations of the same macro within a single compilation run. + * + * This cache is cleared automatically after a compilation run is completed or abandoned. + * It is also specific to a particular macro definition. + * + * To share data between different macros and/or different compilation runs, use ``globalCache''. + */ + val cache: collection.mutable.Map[Any, Any] +} diff --git a/src/library/scala/reflect/makro/Names.scala b/src/library/scala/reflect/makro/Names.scala new file mode 100644 index 0000000000..8a823d19cb --- /dev/null +++ b/src/library/scala/reflect/makro/Names.scala @@ -0,0 +1,14 @@ +package scala.reflect.makro + +trait Names { + self: Context => + + /** Creates a fresh string */ + def fresh(): String + + /** Creates a fresh string from the provided string */ + def fresh(name: String): String + + /** Creates a fresh name from the provided name */ + def fresh(name: Name): Name +} diff --git a/src/library/scala/reflect/makro/Reifiers.scala b/src/library/scala/reflect/makro/Reifiers.scala new file mode 100644 index 0000000000..d690df6aee --- /dev/null +++ b/src/library/scala/reflect/makro/Reifiers.scala @@ -0,0 +1,82 @@ +package scala.reflect.makro + +trait Reifiers { + self: Context => + + /** Reification prefix that refers to the standard reflexive mirror, ``scala.reflect.mirror''. + * Providing it for the ``prefix'' parameter of ``reifyTree'' or ``reifyType'' will create a tree that can be inspected at runtime. + */ + val reflectMirrorPrefix: Tree + + /** Given a tree, generate a tree that when compiled and executed produces the original tree. + * The produced tree will be bound to the mirror specified by ``prefix'' (also see ``reflectMirrorPrefix''). + * For more information and examples see the documentation for ``Universe.reify''. + * + * This function is deeply connected to ``Universe.reify'', a macro that reifies arbitrary expressions into runtime trees. + * They do very similar things (``Universe.reify'' calls ``Context.reifyTree'' to implement itself), but they operate on different metalevels (see below). + * + * Let's study the differences between ``Context.reifyTree'' and ``Universe.reify'' on an example of using them inside a ``fooMacro'' macro: + * + * * Since reify itself is a macro, it will be executed when fooMacro is being compiled (metalevel -1) + * and will produce a tree that when evaluated during macro expansion of fooMacro (metalevel 0) will recreate the input tree. + * + * This provides a facility analogous to quasi-quoting. Writing "reify{ expr }" will generate an AST that represents expr. + * Afterwards this AST (or its parts) can be used to construct the return value of fooMacro. + * + * * reifyTree is evaluated during macro expansion (metalevel 0) + * and will produce a tree that when evaluated during the runtime of the program (metalevel 1) will recreate the input tree. + * + * This provides a way to retain certain trees from macro expansion time to be inspected later, in the runtime. + * For example, DSL authors may find it useful to capture DSL snippets into ASTs that are then processed at runtime in a domain-specific way. + * + * Also note the difference between universes of the runtime trees produced by two reifies: + * + * * The result of compiling and running the result of reify will be bound to the Universe that called reify. + * This is possible because it's a macro, so it can generate whatever code it wishes. + * + * * The result of compiling and running the result of reifyTree will be the ``prefix'' that needs to be passed explicitly. + * This happens because the Universe of the evaluated result is from a different metalevel than the Context the called reify. + * + * Typical usage of this function is to retain some of the trees received/created by a macro + * into the form that can be inspected (via pattern matching) or compiled/run (by a reflective ToolBox) during the runtime. + */ + def reifyTree(prefix: Tree, tree: Tree): Tree + + /** Given a type, generate a tree that when compiled and executed produces the original type. + * The produced tree will be bound to the mirror specified by ``prefix'' (also see ``reflectMirrorPrefix''). + * For more information and examples see the documentation for ``Context.reifyTree'' and ``Universe.reify''. + */ + def reifyType(prefix: Tree, tpe: Type, dontSpliceAtTopLevel: Boolean = false, requireConcreteTypeTag: Boolean = false): Tree + + /** Undoes reification of a tree. + * + * This reversion doesn't simply restore the original tree (that would lose the context of reification), + * but does something more involved that conforms to the following laws: + * + * 1) unreifyTree(reifyTree(tree)) != tree // unreified tree is tree + saved context + * // in current implementation, the result of unreify is opaque + * // i.e. there's no possibility to inspect underlying tree/context + * + * 2) reifyTree(unreifyTree(reifyTree(tree))) == reifyTree(tree) // the result of reifying a tree in its original context equals to + * // the result of reifying a tree along with its saved context + * + * 3) compileAndEval(unreifyTree(reifyTree(tree))) ~ compileAndEval(tree) // at runtime original and unreified trees are behaviorally equivalent + */ + def unreifyTree(tree: Tree): Tree + + /** Represents an error during reification + */ + type ReificationError <: Throwable + val ReificationError: ReificationErrorExtractor + abstract class ReificationErrorExtractor { + def unapply(error: ReificationError): Option[(Position, String)] + } + + /** Wraps an unexpected error during reification + */ + type UnexpectedReificationError <: Throwable + val UnexpectedReificationError: UnexpectedReificationErrorExtractor + abstract class UnexpectedReificationErrorExtractor { + def unapply(error: UnexpectedReificationError): Option[(Position, String, Throwable)] + } +} diff --git a/src/library/scala/reflect/makro/Reporters.scala b/src/library/scala/reflect/makro/Reporters.scala new file mode 100644 index 0000000000..7341b0e0b7 --- /dev/null +++ b/src/library/scala/reflect/makro/Reporters.scala @@ -0,0 +1,39 @@ +package scala.reflect.makro + +trait Reporters { + self: Context => + + import mirror._ + + /** Exposes means to control the compiler UI */ + def reporter: Reporter + def setReporter(reporter: Reporter): this.type + def withReporter[T](reporter: Reporter)(op: => T): T + + /** For sending a message which should not be labeled as a warning/error, + * but also shouldn't require -verbose to be visible. + * Use ``enclosingPosition'' if you're in doubt what position to pass to ``pos''. + */ + def echo(pos: Position, msg: String): Unit + + /** Informational messages, suppressed unless -verbose or force=true. + * Use ``enclosingPosition'' if you're in doubt what position to pass to ``pos''. + */ + def info(pos: Position, msg: String, force: Boolean): Unit + + /** Warnings and errors. + * Use ``enclosingPosition'' if you're in doubt what position to pass to ``pos''. + */ + def hasWarnings: Boolean + def hasErrors: Boolean + def warning(pos: Position, msg: String): Unit + def error(pos: Position, msg: String): Unit + + /** Abruptly terminates current macro expansion leaving a note about what happened. + * Use ``enclosingPosition'' if you're in doubt what position to pass to ``pos''. + */ + def abort(pos: Position, msg: String): Nothing + + /** Drops into interactive mode if supported by the compiler UI */ + def interactive(): Unit +}
\ No newline at end of file diff --git a/src/library/scala/reflect/makro/Settings.scala b/src/library/scala/reflect/makro/Settings.scala new file mode 100644 index 0000000000..c4a8ebd1b5 --- /dev/null +++ b/src/library/scala/reflect/makro/Settings.scala @@ -0,0 +1,38 @@ +package scala.reflect.makro + +trait Settings { + self: Context => + + /** Exposes macro-specific settings as a list of strings. + * These settings are passed to the compiler via the "-Xmacro-settings:setting1,setting2...,settingN" command-line option. + */ + def settings: List[String] + + /** Exposes current compiler settings as a list of options. + * Use `scalac -help`, `scalac -X` and `scalac -Y` to learn about currently supported options. + */ + // [Eugene] ugly? yes, but I don't really fancy copy/pasting all our settings here and keep it synchronized at all times + // why all settings? because macros need to be in full control of the stuff going on + // maybe later we can implement a gettable/settable list of important settings, but for now let's leave it like that + def compilerSettings: List[String] + + /** Updates current compiler settings with an option string. + * Use `scalac -help`, `scalac -X` and `scalac -Y` to learn about currently supported options. + */ + def setCompilerSettings(options: String): this.type + + /** Updates current compiler settings with a list of options. + * Use `scalac -help`, `scalac -X` and `scalac -Y` to learn about currently supported options. + */ + def setCompilerSettings(options: List[String]): this.type + + /** Temporary sets compiler settings to a given option string and executes a given closure. + * Use `scalac -help`, `scalac -X` and `scalac -Y` to learn about currently supported options. + */ + def withCompilerSettings[T](options: String)(op: => T): T + + /** Temporary sets compiler settings to a given list of options and executes a given closure. + * Use `scalac -help`, `scalac -X` and `scalac -Y` to learn about currently supported options. + */ + def withCompilerSettings[T](options: List[String])(op: => T): T +}
\ No newline at end of file diff --git a/src/library/scala/reflect/makro/Symbols.scala b/src/library/scala/reflect/makro/Symbols.scala new file mode 100644 index 0000000000..91a5f6d8a5 --- /dev/null +++ b/src/library/scala/reflect/makro/Symbols.scala @@ -0,0 +1,17 @@ +package scala.reflect.makro + +trait Symbols { + self: Context => + + /** Can this symbol be loaded by a reflective mirror? + * + * Scalac relies on `ScalaSignature' annotation to retain symbols across compilation runs. + * Such annotations (also called "pickles") are applied on top-level classes and include information + * about all symbols reachable from the annotee. However, local symbols (e.g. classes or definitions local to a block) + * are typically unreachable and information about them gets lost. + * + * This method is useful for macro writers who wish to save certain ASTs to be used at runtime. + * With `isLocatable' it's possible to check whether a tree can be retained as is, or it needs special treatment. + */ + def isLocatable(sym: Symbol): Boolean +}
\ No newline at end of file diff --git a/src/library/scala/reflect/makro/Typers.scala b/src/library/scala/reflect/makro/Typers.scala new file mode 100644 index 0000000000..1ced2daccd --- /dev/null +++ b/src/library/scala/reflect/makro/Typers.scala @@ -0,0 +1,85 @@ +package scala.reflect.makro + +trait Typers { + self: Context => + + import mirror._ + + /** Contexts that represent macros in-flight, including the current one. Very much like a stack trace, but for macros only. + * Can be useful for interoperating with other macros and for imposing compiler-friendly limits on macro expansion. + * + * Is also priceless for emitting sane error messages for macros that are called by other macros on synthetic (i.e. position-less) trees. + * In that dire case navigate the ``openMacros'' stack, and it will most likely contain at least one macro with a position-ful macro application. + * See ``enclosingPosition'' for a default implementation of this logic. + * + * Unlike `enclosingMacros`, this is a def, which means that it gets recalculated on every invocation, + * so it might change depending on what is going on during macro expansion. + */ + def openMacros: List[Context] + + /** Types along with corresponding trees for which implicit arguments are currently searched. + * Can be useful to get information about an application with an implicit parameter that is materialized during current macro expansion. + * + * Unlike `enclosingImplicits`, this is a def, which means that it gets recalculated on every invocation, + * so it might change depending on what is going on during macro expansion. + */ + def openImplicits: List[(Type, Tree)] + + /** Typechecks the provided tree against the expected type ``pt'' in the macro callsite context. + * + * If ``silent'' is false, ``TypeError'' will be thrown in case of a typecheck error. + * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs. + * Such errors don't vanish and can be inspected by turning on -Ymacro-debug. + * Unlike in ``inferImplicitValue'' and ``inferImplicitView'', ``silent'' is false by default. + * + * Typechecking can be steered with the following optional parameters: + * ``withImplicitViewsDisabled'' recursively prohibits implicit views (though, implicit vals will still be looked up and filled in), default value is false + * ``withMacrosDisabled'' recursively prohibits macro expansions and macro-based implicits, default value is false + */ + def typeCheck(tree: Tree, pt: Type = WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree + + /** Infers an implicit value of the expected type ``pt'' in the macro callsite context. + * Optional ``pos'' parameter provides a position that will be associated with the implicit search. + * + * If ``silent'' is false, ``TypeError'' will be thrown in case of an inference error. + * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs. + * Such errors don't vanish and can be inspected by turning on -Xlog-implicits. + * Unlike in ``typeCheck'', ``silent'' is true by default. + */ + def inferImplicitValue(pt: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: Position = enclosingPosition): Tree + + /** Infers an implicit view from the provided tree ``tree'' from the type ``from'' to the type ``to'' in the macro callsite context. + * + * Optional ``pos'' parameter provides a position that will be associated with the implicit search. + * Another optional parameter, ``reportAmbiguous`` controls whether ambiguous implicit errors should be reported. + * If we search for a view simply to find out whether one type is coercible to another, it might be desirable to set this flag to ``false''. + * + * If ``silent'' is false, ``TypeError'' will be thrown in case of an inference error. + * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs. + * Such errors don't vanish and can be inspected by turning on -Xlog-implicits. + * Unlike in ``typeCheck'', ``silent'' is true by default. + */ + def inferImplicitView(tree: Tree, from: Type, to: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, reportAmbiguous: Boolean = true, pos: Position = enclosingPosition): Tree + + /** Recursively resets symbols and types in a given tree. + * + * Note that this does not revert the tree to its pre-typer shape. + * For more info, read up https://issues.scala-lang.org/browse/SI-5464. + */ + def resetAllAttrs[T <: Tree](tree: T): T + + /** Recursively resets locally defined symbols and types in a given tree. + * + * Note that this does not revert the tree to its pre-typer shape. + * For more info, read up https://issues.scala-lang.org/browse/SI-5464. + */ + def resetLocalAttrs[T <: Tree](tree: T): T + + /** Represents an error during typechecking + */ + type TypeError <: Throwable + val TypeError: TypeErrorExtractor + abstract class TypeErrorExtractor { + def unapply(error: TypeError): Option[(Position, String)] + } +}
\ No newline at end of file diff --git a/src/library/scala/reflect/makro/Util.scala b/src/library/scala/reflect/makro/Util.scala new file mode 100644 index 0000000000..16eb2395a9 --- /dev/null +++ b/src/library/scala/reflect/makro/Util.scala @@ -0,0 +1,31 @@ +package scala.reflect.makro + +trait Util { + self: Context => + + def literalNull: Expr[Null] + + def literalUnit: Expr[Unit] + + def literalTrue: Expr[Boolean] + + def literalFalse: Expr[Boolean] + + def literal(x: Boolean): Expr[Boolean] + + def literal(x: Byte): Expr[Byte] + + def literal(x: Short): Expr[Short] + + def literal(x: Int): Expr[Int] + + def literal(x: Long): Expr[Long] + + def literal(x: Float): Expr[Float] + + def literal(x: Double): Expr[Double] + + def literal(x: String): Expr[String] + + def literal(x: Char): Expr[Char] +} diff --git a/src/library/scala/reflect/makro/internal/Utils.scala b/src/library/scala/reflect/makro/internal/Utils.scala new file mode 100644 index 0000000000..db658fd637 --- /dev/null +++ b/src/library/scala/reflect/makro/internal/Utils.scala @@ -0,0 +1,135 @@ +package scala.reflect.makro + +import scala.reflect.api.Universe +import language.implicitConversions +import language.experimental.macros + +/** This package is required by the compiler and <b>should not be used in client code</b>. */ +package object internal { + /** This method is required by the compiler and <b>should not be used in client code</b>. */ + def materializeClassTag[T](u: Universe): ClassTag[T] = macro materializeClassTag_impl[T] + + /** This method is required by the compiler and <b>should not be used in client code</b>. */ + def materializeClassTag_impl[T: c.TypeTag](c: Context)(u: c.Expr[Universe]): c.Expr[ClassTag[T]] = + c.Expr[Nothing](c.materializeClassTag(u.tree, implicitly[c.TypeTag[T]].tpe))(c.TypeTag.Nothing) + + /** This method is required by the compiler and <b>should not be used in client code</b>. */ + def materializeTypeTag[T](u: Universe): u.TypeTag[T] = macro materializeTypeTag_impl[T] + + /** This method is required by the compiler and <b>should not be used in client code</b>. */ + def materializeTypeTag_impl[T: c.TypeTag](c: Context)(u: c.Expr[Universe]): c.Expr[u.value.TypeTag[T]] = + c.Expr[Nothing](c.materializeTypeTag(u.tree, implicitly[c.TypeTag[T]].tpe, requireConcreteTypeTag = false))(c.TypeTag.Nothing) + + /** This method is required by the compiler and <b>should not be used in client code</b>. */ + def materializeConcreteTypeTag[T](u: Universe): u.ConcreteTypeTag[T] = macro materializeConcreteTypeTag_impl[T] + + /** This method is required by the compiler and <b>should not be used in client code</b>. */ + def materializeConcreteTypeTag_impl[T: c.TypeTag](c: Context)(u: c.Expr[Universe]): c.Expr[u.value.ConcreteTypeTag[T]] = + c.Expr[Nothing](c.materializeTypeTag(u.tree, implicitly[c.TypeTag[T]].tpe, requireConcreteTypeTag = true))(c.TypeTag.Nothing) + + /** This method is required by the compiler and <b>should not be used in client code</b>. */ + private[scala] implicit def context2utils(c0: Context) : Utils { val c: c0.type } = new { val c: c0.type = c0 } with Utils +} + +package internal { + private[scala] abstract class Utils { + val c: Context + + import c.mirror._ + import definitions._ + + val coreTags = Map( + ByteClass.asType -> newTermName("Byte"), + ShortClass.asType -> newTermName("Short"), + CharClass.asType -> newTermName("Char"), + IntClass.asType -> newTermName("Int"), + LongClass.asType -> newTermName("Long"), + FloatClass.asType -> newTermName("Float"), + DoubleClass.asType -> newTermName("Double"), + BooleanClass.asType -> newTermName("Boolean"), + UnitClass.asType -> newTermName("Unit"), + AnyClass.asType -> newTermName("Any"), + ObjectClass.asType -> newTermName("Object"), + AnyValClass.asType -> newTermName("AnyVal"), + AnyRefClass.asType -> newTermName("AnyRef"), + NothingClass.asType -> newTermName("Nothing"), + NullClass.asType -> newTermName("Null")) + + def materializeClassTag(prefix: Tree, tpe: Type): Tree = { + val typetagInScope = c.inferImplicitValue(appliedType(typeRef(prefix.tpe, ConcreteTypeTagClass, Nil), List(tpe))) + def typetagIsSynthetic(tree: Tree) = tree.isInstanceOf[Block] || (tree exists (sub => sub.symbol == TypeTagModule || sub.symbol == ConcreteTypeTagModule)) + typetagInScope match { + case success if !success.isEmpty && !typetagIsSynthetic(success) => + val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe))) + Apply(factory, List(Select(typetagInScope, newTermName("tpe")))) + case _ => + val result = + tpe match { + case coreTpe if coreTags contains coreTpe => + Select(Ident(ClassTagModule), coreTags(coreTpe)) + case _ => + if (tpe.typeSymbol == ArrayClass) { + val componentTpe = tpe.typeArguments(0) + val classtagInScope = c.inferImplicitValue(appliedType(typeRef(NoPrefix, ClassTagClass, Nil), List(componentTpe))) + val componentTag = classtagInScope orElse materializeClassTag(prefix, componentTpe) + Select(componentTag, newTermName("wrap")) + } else { + // [Eugene] what's the intended behavior? there's no spec on ClassManifests + // for example, should we ban Array[T] or should we tag them with Array[AnyRef]? + // if its the latter, what should be the result of tagging Array[T] where T <: Int? + if (tpe.typeSymbol.isAbstractType) fail("tpe is an abstract type") + val erasure = + if (tpe.typeSymbol.isDerivedValueClass) tpe // [Eugene to Martin] is this correct? + else tpe.erasure.normalize // necessary to deal with erasures of HK types + val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe))) + Apply(factory, List(TypeApply(Ident(newTermName("classOf")), List(TypeTree(erasure))))) + } + } + try c.typeCheck(result) + catch { case terr @ c.TypeError(pos, msg) => fail(terr) } + } + } + + def materializeTypeTag(prefix: Tree, tpe: Type, requireConcreteTypeTag: Boolean): Tree = { + val tagModule = if (requireConcreteTypeTag) ConcreteTypeTagModule else TypeTagModule + val result = + tpe match { + case coreTpe if coreTags contains coreTpe => + Select(Select(prefix, tagModule.name), coreTags(coreTpe)) + case _ => + try c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireConcreteTypeTag = requireConcreteTypeTag) + catch { + case ex: Throwable => + // [Eugene] cannot pattern match on an abstract type, so had to do this + val ex1 = ex + if (ex.getClass.toString.endsWith("$ReificationError")) { + ex match { + case c.ReificationError(pos, msg) => + c.error(pos, msg) + EmptyTree + } + } else if (ex.getClass.toString.endsWith("$UnexpectedReificationError")) { + ex match { + case c.UnexpectedReificationError(pos, err, cause) => + if (cause != null) throw cause else throw ex + } + } else { + throw ex + } + } + } + try c.typeCheck(result) + catch { case terr @ c.TypeError(pos, msg) => fail(terr) } + } + + private def fail(reason: Any): Nothing = { + val Apply(TypeApply(fun, List(tpeTree)), _) = c.macroApplication + val tpe = tpeTree.tpe + val PolyType(_, MethodType(_, tagTpe)) = fun.tpe + val tagModule = tagTpe.typeSymbol.companionSymbol + if (c.compilerSettings.contains("-Xlog-implicits")) + c.echo(c.enclosingPosition, "cannot materialize " + tagModule.name + "[" + tpe + "] because:\n" + reason) + c.abort(c.enclosingPosition, "No %s available for %s".format(tagModule.name, tpe)) + } + } +} diff --git a/src/library/scala/reflect/makro/internal/macroImpl.scala b/src/library/scala/reflect/makro/internal/macroImpl.scala new file mode 100644 index 0000000000..86600ba0a1 --- /dev/null +++ b/src/library/scala/reflect/makro/internal/macroImpl.scala @@ -0,0 +1,5 @@ +package scala.reflect.makro +package internal + +/** This type is required by the compiler and <b>should not be used in client code</b>. */ +class macroImpl(val referenceToMacroImpl: Any) extends StaticAnnotation diff --git a/src/library/scala/reflect/package.scala b/src/library/scala/reflect/package.scala index 1c3e618520..1738642932 100644 --- a/src/library/scala/reflect/package.scala +++ b/src/library/scala/reflect/package.scala @@ -2,21 +2,28 @@ package scala package object reflect { + import ReflectionUtils._ + // !!! This was a val; we can't throw exceptions that aggressively without breaking // non-standard environments, e.g. google app engine. I made it a lazy val, but // I think it would be better yet to throw the exception somewhere else - not during // initialization, but in response to a doomed attempt to utilize it. - lazy val mirror: api.Mirror = { + + // todo. default mirror (a static object) might become a source for memory leaks (because it holds a strong reference to a classloader)! + lazy val mirror: api.Mirror = mkMirror(defaultReflectionClassLoader) + + def mkMirror(classLoader: ClassLoader): api.Mirror = { // we use (Java) reflection here so that we can keep reflect.runtime and reflect.internals in a seperate jar - ReflectionUtils.singletonInstanceOpt("scala.reflect.runtime.Mirror") collect { case x: api.Mirror => x } getOrElse { - throw new UnsupportedOperationException("Scala reflection not available on this platform") + // note that we must instantiate the mirror with current classloader, otherwise we won't be able to cast it to api.Mirror + // that's not a problem, though, because mirror can service classes from arbitrary classloaders + val instance = invokeFactoryOpt(getClass.getClassLoader, "scala.reflect.runtime.package", "mkMirror", classLoader) + instance match { + case Some(x: api.Mirror) => x + case Some(_) => throw new UnsupportedOperationException("Available scala reflection implementation is incompatible with this interface") + case None => throw new UnsupportedOperationException("Scala reflection not available on this platform") } } - type Symbol = mirror.Symbol - type Type = mirror.Type - type Tree = mirror.Tree - @deprecated("Use `@scala.beans.BeanDescription` instead", "2.10.0") type BeanDescription = scala.beans.BeanDescription @deprecated("Use `@scala.beans.BeanDisplayName` instead", "2.10.0") @@ -31,4 +38,26 @@ package object reflect { type BooleanBeanProperty = scala.beans.BooleanBeanProperty @deprecated("Use `@scala.beans.ScalaBeanInfo` instead", "2.10.0") type ScalaBeanInfo = scala.beans.ScalaBeanInfo + + @deprecated("Use `@scala.reflect.ClassTag` instead", "2.10.0") + type ClassManifest[T] = ClassTag[T] + @deprecated("OptManifest is no longer supported, and using it may lead to incorrect results, Use `@scala.reflect.TypeTag` instead", "2.10.0") + type OptManifest[T] = TypeTag[T] + @deprecated("Use `@scala.reflect.ConcreteTypeTag` instead", "2.10.0") + type Manifest[T] = ConcreteTypeTag[T] + + @deprecated("Use `@scala.reflect.ClassTag` instead", "2.10.0") + val ClassManifest = ClassTag + @deprecated("Use `@scala.reflect.ConcreteTypeTag` instead", "2.10.0") + lazy val Manifest = ConcreteTypeTag + @deprecated("NoManifest is no longer supported, and using it may lead to incorrect results, Use `@scala.reflect.TypeTag` instead", "2.10.0") + object NoManifest extends OptManifest[Nothing](scala.reflect.mirror.definitions.NothingClass.asType) with Serializable + + // ClassTag class is defined separately from the mirror + type TypeTag[T] = scala.reflect.mirror.TypeTag[T] + type ConcreteTypeTag[T] = scala.reflect.mirror.ConcreteTypeTag[T] + + // ClassTag object is defined separately from the mirror + lazy val TypeTag = scala.reflect.mirror.TypeTag + lazy val ConcreteTypeTag = scala.reflect.mirror.ConcreteTypeTag } diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala index 8bc63ae3a0..7a932c21bc 100644 --- a/src/library/scala/runtime/ScalaRunTime.scala +++ b/src/library/scala/runtime/ScalaRunTime.scala @@ -31,7 +31,7 @@ object ScalaRunTime { clazz.isArray && (atLevel == 1 || isArrayClass(clazz.getComponentType, atLevel - 1)) def isValueClass(clazz: Class[_]) = clazz.isPrimitive() - def isTuple(x: Any) = tupleNames(x.getClass.getName) + def isTuple(x: Any) = x != null && tupleNames(x.getClass.getName) def isAnyVal(x: Any) = x match { case _: Byte | _: Short | _: Char | _: Int | _: Long | _: Float | _: Double | _: Boolean | _: Unit => true case _ => false @@ -329,14 +329,14 @@ object ScalaRunTime { case null => "null" case "" => "\"\"" case x: String => if (x.head.isWhitespace || x.last.isWhitespace) "\"" + x + "\"" else x - case x if useOwnToString(x) => x toString + case x if useOwnToString(x) => x.toString case x: AnyRef if isArray(x) => arrayToString(x) case x: collection.Map[_, _] => x.iterator take maxElements map mapInner mkString (x.stringPrefix + "(", ", ", ")") case x: Iterable[_] => x.iterator take maxElements map inner mkString (x.stringPrefix + "(", ", ", ")") case x: Traversable[_] => x take maxElements map inner mkString (x.stringPrefix + "(", ", ", ")") case x: Product1[_] if isTuple(x) => "(" + inner(x._1) + ",)" // that special trailing comma case x: Product if isTuple(x) => x.productIterator map inner mkString ("(", ",", ")") - case x => x toString + case x => x.toString } // The try/catch is defense against iterables which aren't actually designed diff --git a/src/library/scala/sys/BooleanProp.scala b/src/library/scala/sys/BooleanProp.scala index e940990785..45fc6f5897 100644 --- a/src/library/scala/sys/BooleanProp.scala +++ b/src/library/scala/sys/BooleanProp.scala @@ -8,6 +8,8 @@ package scala.sys +import language.implicitConversions + /** A few additional conveniences for Boolean properties. */ trait BooleanProp extends Prop[Boolean] { diff --git a/src/library/scala/sys/SystemProperties.scala b/src/library/scala/sys/SystemProperties.scala index 52e0ac230b..4853da3495 100644 --- a/src/library/scala/sys/SystemProperties.scala +++ b/src/library/scala/sys/SystemProperties.scala @@ -11,6 +11,8 @@ package scala.sys import scala.collection.{ mutable, Iterator } import scala.collection.JavaConverters._ import java.security.AccessControlException +import language.implicitConversions + /** A bidirectional map wrapping the java System properties. * Changes to System properties will be immediately visible in the map, diff --git a/src/library/scala/sys/process/Process.scala b/src/library/scala/sys/process/Process.scala index c2a61af936..d56c6f2c9d 100644 --- a/src/library/scala/sys/process/Process.scala +++ b/src/library/scala/sys/process/Process.scala @@ -11,6 +11,7 @@ package process import processInternal._ import ProcessBuilder._ +import language.implicitConversions /** Represents a process that is running or has finished running. * It may be a compound process with several underlying native processes (such as `a #&& b`). diff --git a/src/library/scala/testing/Show.scala b/src/library/scala/testing/Show.scala index 7570bf705c..5ab46b8985 100644 --- a/src/library/scala/testing/Show.scala +++ b/src/library/scala/testing/Show.scala @@ -27,17 +27,17 @@ package scala.testing */ trait Show { - /** The result class of wrapper `symApply`. + /** An implicit definition that adds an apply method to Symbol which forwards to `test`. * Prints out diagnostics of method applications. */ - class SymApply(f: Symbol) { + implicit class SymApply(f: Symbol) { def apply[A](args: A*) { println(test(f, args: _*)) } } - /** An implicit definition that adds an apply method to Symbol which forwards to `test`. */ - implicit def symApply(sym: Symbol) = new SymApply(sym) + @deprecated("use SymApply instead", "2.10") + def symApply(sym: Symbol): SymApply = new SymApply(sym) /** Apply method with name of given symbol `f` to given arguments and return * a result diagnostics. diff --git a/src/library/scala/util/Marshal.scala b/src/library/scala/util/Marshal.scala index daeaf4c53b..c2269cde45 100644 --- a/src/library/scala/util/Marshal.scala +++ b/src/library/scala/util/Marshal.scala @@ -35,7 +35,8 @@ object Marshal { def load[A](buffer: Array[Byte])(implicit expected: ClassManifest[A]): A = { val in = new ObjectInputStream(new ByteArrayInputStream(buffer)) val found = in.readObject.asInstanceOf[ClassManifest[_]] - if (found <:< expected) { + // todo. [Eugene] needs review, since ClassManifests no longer capture typeArguments + if (found.tpe <:< expected.tpe) { val o = in.readObject.asInstanceOf[A] in.close() o diff --git a/src/library/scala/util/Random.scala b/src/library/scala/util/Random.scala index 791582c9ec..17c356801b 100644 --- a/src/library/scala/util/Random.scala +++ b/src/library/scala/util/Random.scala @@ -11,6 +11,7 @@ package scala.util import collection.mutable.ArrayBuffer import collection.generic.CanBuildFrom import scala.collection.immutable.{ List, Stream } +import language.{implicitConversions, higherKinds} /** * @author Stephane Micheloud @@ -117,18 +118,9 @@ class Random(val self: java.util.Random) { swap(n - 1, k) } - bf(xs) ++= buf result + (bf(xs) ++= buf).result } -} - -/** The object `Random` offers a default implementation - * of scala.util.Random and random-related convenience methods. - * - * @since 2.8 - */ -object Random extends Random { - /** Returns a Stream of pseudorandomly chosen alphanumeric characters, * equally chosen from A-Z, a-z, and 0-9. * @@ -141,3 +133,14 @@ object Random extends Random { } } + +/** The object `Random` offers a default implementation + * of scala.util.Random and random-related convenience methods. + * + * @since 2.8 + */ +object Random extends Random { + + implicit def javaRandomToRandom(r: java.util.Random): Random = new Random(r) + +} diff --git a/src/library/scala/util/automata/BaseBerrySethi.scala b/src/library/scala/util/automata/BaseBerrySethi.scala index 18f36f9496..c78b2d0790 100644 --- a/src/library/scala/util/automata/BaseBerrySethi.scala +++ b/src/library/scala/util/automata/BaseBerrySethi.scala @@ -78,7 +78,7 @@ abstract class BaseBerrySethi { * @return ... */ protected def compFollow1(fol1: Set[Int], r: RegExp): Set[Int] = r match { - case x: Alt => Set(x.rs reverseMap (compFollow1(fol1, _)) flatten: _*) + case x: Alt => Set((x.rs reverseMap (compFollow1(fol1, _))).flatten: _*) case x: Meta => compFollow1(fol1, x.r) case x: Star => compFollow1(fol1 ++ compFirst(x.r), x.r) case x: Sequ => diff --git a/src/library/scala/util/automata/NondetWordAutom.scala b/src/library/scala/util/automata/NondetWordAutom.scala index fbc05de7fd..b09e82ca11 100644 --- a/src/library/scala/util/automata/NondetWordAutom.scala +++ b/src/library/scala/util/automata/NondetWordAutom.scala @@ -50,8 +50,8 @@ abstract class NondetWordAutom[T <: AnyRef] { override def toString = { val finalString = Map(finalStates map (j => j -> finals(j)) : _*).toString - val deltaString = (0 until nstates) . - map (i => " %d->%s\n _>%s\n".format(i, delta(i), default(i))) mkString + val deltaString = (0 until nstates) + .map(i => " %d->%s\n _>%s\n".format(i, delta(i), default(i))).mkString "[NondetWordAutom nstates=%d finals=%s delta=\n%s".format(nstates, finalString, deltaString) } diff --git a/src/library/scala/util/automata/SubsetConstruction.scala b/src/library/scala/util/automata/SubsetConstruction.scala index 8049d10d88..81805fce2f 100644 --- a/src/library/scala/util/automata/SubsetConstruction.scala +++ b/src/library/scala/util/automata/SubsetConstruction.scala @@ -14,7 +14,7 @@ class SubsetConstruction[T <: AnyRef](val nfa: NondetWordAutom[T]) { import nfa.labels def selectTag(Q: immutable.BitSet, finals: Array[Int]) = - Q map finals filter (_ > 0) min + (Q map finals filter (_ > 0)).min def determinize: DetWordAutom[T] = { // for assigning numbers to bitsets diff --git a/src/library/scala/util/automata/WordBerrySethi.scala b/src/library/scala/util/automata/WordBerrySethi.scala index 84b78d8dd8..a7ad92e648 100644 --- a/src/library/scala/util/automata/WordBerrySethi.scala +++ b/src/library/scala/util/automata/WordBerrySethi.scala @@ -139,7 +139,7 @@ abstract class WordBerrySethi extends BaseBerrySethi { finals = finals.updated(0, finalTag) val delta1 = immutable.Map(deltaq.zipWithIndex map (_.swap): _*) - val finalsArr = 0 until pos map (k => finals.getOrElse(k, 0)) toArray // 0 == not final + val finalsArr = (0 until pos map (k => finals.getOrElse(k, 0))).toArray // 0 == not final val initialsArr = initials.toArray val deltaArr: Array[mutable.Map[_labelT, immutable.BitSet]] = @@ -147,7 +147,7 @@ abstract class WordBerrySethi extends BaseBerrySethi { mutable.HashMap(delta1(x).toSeq map { case (k, v) => k -> immutable.BitSet(v: _*) } : _*) }).toArray - val defaultArr = 0 until pos map (k => immutable.BitSet(defaultq(k): _*)) toArray + val defaultArr = (0 until pos map (k => immutable.BitSet(defaultq(k): _*))).toArray new NondetWordAutom[_labelT] { val nstates = pos @@ -161,4 +161,4 @@ abstract class WordBerrySethi extends BaseBerrySethi { automatonFrom(Sequ(z.asInstanceOf[this.lang._regexpT]), finalTag) } } -}
\ No newline at end of file +} diff --git a/src/library/scala/util/control/Exception.scala b/src/library/scala/util/control/Exception.scala index 20a179a884..1cae8088f5 100644 --- a/src/library/scala/util/control/Exception.scala +++ b/src/library/scala/util/control/Exception.scala @@ -10,6 +10,8 @@ package scala.util.control import collection.immutable.List import java.lang.reflect.InvocationTargetException +import language.implicitConversions + /** Classes representing the components of exception handling. * Each class is independently composable. Some example usages: diff --git a/src/library/scala/util/parsing/ast/Binders.scala b/src/library/scala/util/parsing/ast/Binders.scala index 0646f57064..09ad5ce2ab 100644 --- a/src/library/scala/util/parsing/ast/Binders.scala +++ b/src/library/scala/util/parsing/ast/Binders.scala @@ -10,6 +10,7 @@ package scala.util.parsing.ast import scala.collection.AbstractIterable import scala.collection.mutable +import language.implicitConversions //DISCLAIMER: this code is highly experimental! diff --git a/src/library/scala/util/parsing/combinator/ImplicitConversions.scala b/src/library/scala/util/parsing/combinator/ImplicitConversions.scala index e993628e88..270ac680a9 100644 --- a/src/library/scala/util/parsing/combinator/ImplicitConversions.scala +++ b/src/library/scala/util/parsing/combinator/ImplicitConversions.scala @@ -9,6 +9,8 @@ package scala.util.parsing.combinator +import language.implicitConversions + /** This object contains implicit conversions that come in handy when using the `^^` combinator. * * Refer to [[scala.util.parsing.combinator.Parsers]] to construct an AST from the concrete syntax. diff --git a/src/library/scala/util/parsing/combinator/PackratParsers.scala b/src/library/scala/util/parsing/combinator/PackratParsers.scala index ea856efc3a..9516df0093 100644 --- a/src/library/scala/util/parsing/combinator/PackratParsers.scala +++ b/src/library/scala/util/parsing/combinator/PackratParsers.scala @@ -11,6 +11,7 @@ package scala.util.parsing.combinator import scala.util.parsing.combinator._ import scala.util.parsing.input.{ Reader, Position } import scala.collection.mutable +import language.implicitConversions /** * `PackratParsers` is a component that extends the parser combinators diff --git a/src/library/scala/util/parsing/combinator/Parsers.scala b/src/library/scala/util/parsing/combinator/Parsers.scala index 9aaf0aeb54..e5458f89af 100644 --- a/src/library/scala/util/parsing/combinator/Parsers.scala +++ b/src/library/scala/util/parsing/combinator/Parsers.scala @@ -12,6 +12,7 @@ import scala.util.parsing.input._ import scala.collection.mutable.ListBuffer import scala.annotation.tailrec import annotation.migration +import language.implicitConversions // TODO: better error handling (labelling like parsec's <?>) diff --git a/src/library/scala/util/parsing/combinator/RegexParsers.scala b/src/library/scala/util/parsing/combinator/RegexParsers.scala index 86eecd03c4..d685329ef1 100644 --- a/src/library/scala/util/parsing/combinator/RegexParsers.scala +++ b/src/library/scala/util/parsing/combinator/RegexParsers.scala @@ -13,6 +13,7 @@ import java.util.regex.Pattern import scala.util.matching.Regex import scala.util.parsing.input._ import scala.collection.immutable.PagedSeq +import language.implicitConversions /** The ''most important'' differences between `RegexParsers` and * [[scala.util.parsing.combinator.Parsers]] are: diff --git a/src/library/scala/util/parsing/combinator/lexical/Lexical.scala b/src/library/scala/util/parsing/combinator/lexical/Lexical.scala index 9979a420d6..6c3bc52c1a 100644 --- a/src/library/scala/util/parsing/combinator/lexical/Lexical.scala +++ b/src/library/scala/util/parsing/combinator/lexical/Lexical.scala @@ -32,7 +32,7 @@ abstract class Lexical extends Scanners with Tokens { def digit = elem("digit", _.isDigit) /** A character-parser that matches any character except the ones given in `cs` (and returns it).*/ - def chrExcept(cs: Char*) = elem("", ch => (cs forall (ch !=))) + def chrExcept(cs: Char*) = elem("", ch => (cs forall (ch != _))) /** A character-parser that matches a white-space character (and returns it).*/ def whitespaceChar = elem("space char", ch => ch <= ' ' && ch != EofCh) diff --git a/src/library/scala/util/parsing/combinator/syntactical/StandardTokenParsers.scala b/src/library/scala/util/parsing/combinator/syntactical/StandardTokenParsers.scala index e494a69cf0..215b8b792f 100644 --- a/src/library/scala/util/parsing/combinator/syntactical/StandardTokenParsers.scala +++ b/src/library/scala/util/parsing/combinator/syntactical/StandardTokenParsers.scala @@ -13,6 +13,7 @@ package syntactical import token._ import lexical.StdLexical +import language.implicitConversions /** This component provides primitive parsers for the standard tokens defined in `StdTokens`. * diff --git a/src/library/scala/util/parsing/combinator/syntactical/StdTokenParsers.scala b/src/library/scala/util/parsing/combinator/syntactical/StdTokenParsers.scala index 0901f9bbd0..7aa6178df9 100644 --- a/src/library/scala/util/parsing/combinator/syntactical/StdTokenParsers.scala +++ b/src/library/scala/util/parsing/combinator/syntactical/StdTokenParsers.scala @@ -14,6 +14,7 @@ package syntactical import token._ import scala.collection.mutable +import language.implicitConversions /** This component provides primitive parsers for the standard tokens defined in `StdTokens`. * diff --git a/src/library/scala/util/parsing/combinator/testing/RegexTest.scala b/src/library/scala/util/parsing/combinator/testing/RegexTest.scala index 299736046e..255730e5db 100644 --- a/src/library/scala/util/parsing/combinator/testing/RegexTest.scala +++ b/src/library/scala/util/parsing/combinator/testing/RegexTest.scala @@ -3,6 +3,7 @@ package scala.util.parsing.combinator.testing import scala.util.parsing.combinator._ import scala.util.parsing.input._ +import language.postfixOps case class Ident(s: String) case class Number(n: Int) diff --git a/src/library/scala/xml/Elem.scala b/src/library/scala/xml/Elem.scala index 5b6b9f2bb9..f140fd1e07 100755 --- a/src/library/scala/xml/Elem.scala +++ b/src/library/scala/xml/Elem.scala @@ -107,5 +107,5 @@ extends Node with Serializable /** Returns concatenation of `text(n)` for each child `n`. */ - override def text = child map (_.text) mkString + override def text = (child map (_.text)).mkString } diff --git a/src/library/scala/xml/MetaData.scala b/src/library/scala/xml/MetaData.scala index c516747bae..b44a817499 100644 --- a/src/library/scala/xml/MetaData.scala +++ b/src/library/scala/xml/MetaData.scala @@ -167,7 +167,7 @@ extends AbstractIterable[MetaData] /** Returns a Map containing the attributes stored as key/value pairs. */ def asAttrMap: Map[String, String] = - iterator map (x => (x.prefixedKey, x.value.text)) toMap + (iterator map (x => (x.prefixedKey, x.value.text))).toMap /** returns Null or the next MetaData item */ def next: MetaData diff --git a/src/library/scala/xml/NodeSeq.scala b/src/library/scala/xml/NodeSeq.scala index ff5618645f..f0be338fcf 100644 --- a/src/library/scala/xml/NodeSeq.scala +++ b/src/library/scala/xml/NodeSeq.scala @@ -11,6 +11,7 @@ package scala.xml import collection.{ mutable, immutable, generic, SeqLike, AbstractSeq } import mutable.{ Builder, ListBuffer } import generic.{ CanBuildFrom } +import language.implicitConversions /** This object ... * @@ -152,5 +153,5 @@ abstract class NodeSeq extends AbstractSeq[Node] with immutable.Seq[Node] with S override def toString(): String = theSeq.mkString - def text: String = this map (_.text) mkString + def text: String = (this map (_.text)).mkString } diff --git a/src/library/scala/xml/Utility.scala b/src/library/scala/xml/Utility.scala index 9f944c0e92..062a62e240 100755 --- a/src/library/scala/xml/Utility.scala +++ b/src/library/scala/xml/Utility.scala @@ -10,6 +10,7 @@ package scala.xml import scala.collection.mutable import parsing.XhtmlEntities +import language.implicitConversions /** * The `Utility` object provides utility functions for processing instances @@ -20,6 +21,8 @@ import parsing.XhtmlEntities object Utility extends AnyRef with parsing.TokenTests { final val SU = '\u001A' + // [Martin] This looks dubious. We don't convert StringBuilders to + // Strings anywhere else, why do it here? implicit def implicitSbToString(sb: StringBuilder) = sb.toString() // helper for the extremely oft-repeated sequence of creating a @@ -137,7 +140,7 @@ object Utility extends AnyRef with parsing.TokenTests { * @return `'''null'''` if `ref` was not a predefined entity. */ final def unescape(ref: String, s: StringBuilder): StringBuilder = - (unescMap get ref) map (s append _) orNull + ((unescMap get ref) map (s append _)).orNull /** * Returns a set of all namespaces used in a sequence of nodes diff --git a/src/library/scala/xml/dtd/ContentModel.scala b/src/library/scala/xml/dtd/ContentModel.scala index 1e9a3a4b58..a5d2a6bd7e 100644 --- a/src/library/scala/xml/dtd/ContentModel.scala +++ b/src/library/scala/xml/dtd/ContentModel.scala @@ -36,8 +36,8 @@ object ContentModel extends WordExp { def traverse(r: RegExp): Set[String] = r match { // !!! check for match translation problem case Letter(ElemName(name)) => Set(name) case Star( x @ _ ) => traverse( x ) // bug if x@_* - case Sequ( xs @ _* ) => Set(xs map traverse flatten: _*) - case Alt( xs @ _* ) => Set(xs map traverse flatten: _*) + case Sequ( xs @ _* ) => Set(xs flatMap traverse: _*) + case Alt( xs @ _* ) => Set(xs flatMap traverse: _*) } traverse(r) diff --git a/src/library/scala/xml/parsing/ConstructingParser.scala b/src/library/scala/xml/parsing/ConstructingParser.scala index 5571c9844d..471cde056e 100644 --- a/src/library/scala/xml/parsing/ConstructingParser.scala +++ b/src/library/scala/xml/parsing/ConstructingParser.scala @@ -16,10 +16,10 @@ import scala.io.Source object ConstructingParser { def fromFile(inp: File, preserveWS: Boolean) = - new ConstructingParser(Source.fromFile(inp), preserveWS) initialize + new ConstructingParser(Source.fromFile(inp), preserveWS).initialize def fromSource(inp: Source, preserveWS: Boolean) = - new ConstructingParser(inp, preserveWS) initialize + new ConstructingParser(inp, preserveWS).initialize } /** An xml parser. parses XML and invokes callback methods of a MarkupHandler. |