diff options
author | Eugene Burmako <xeno.by@gmail.com> | 2012-04-22 18:49:09 +0200 |
---|---|---|
committer | Eugene Burmako <xeno.by@gmail.com> | 2012-04-23 17:55:26 +0200 |
commit | f54e5c8bbdd719b5c9375c64c2f66b841984456e (patch) | |
tree | 975475778e6102c8f2dbbff0f25a2f114204cbbb /src/library | |
parent | 0f0144c74088e396fc1440166bed5a7c6d5f44f4 (diff) | |
download | scala-f54e5c8bbdd719b5c9375c64c2f66b841984456e.tar.gz scala-f54e5c8bbdd719b5c9375c64c2f66b841984456e.tar.bz2 scala-f54e5c8bbdd719b5c9375c64c2f66b841984456e.zip |
resurrects manifests in their pre-2.10 glory
Diffstat (limited to 'src/library')
-rw-r--r-- | src/library/scala/Predef.scala | 11 | ||||
-rw-r--r-- | src/library/scala/collection/mutable/WrappedArray.scala | 2 | ||||
-rw-r--r-- | src/library/scala/reflect/ClassManifest.scala | 242 | ||||
-rw-r--r-- | src/library/scala/reflect/Manifest.scala | 259 | ||||
-rw-r--r-- | src/library/scala/reflect/NoManifest.scala | 16 | ||||
-rw-r--r-- | src/library/scala/reflect/OptManifest.scala | 18 | ||||
-rw-r--r-- | src/library/scala/reflect/package.scala | 14 |
7 files changed, 538 insertions, 24 deletions
diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index 093f972f72..d2aa3a8b34 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -100,19 +100,12 @@ 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] - @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 - // [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 + val Manifest = scala.reflect.Manifest + val NoManifest = scala.reflect.NoManifest def manifest[T](implicit m: Manifest[T]) = m def classManifest[T](implicit m: ClassManifest[T]) = m diff --git a/src/library/scala/collection/mutable/WrappedArray.scala b/src/library/scala/collection/mutable/WrappedArray.scala index 5e20f4ec61..9d170b2832 100644 --- a/src/library/scala/collection/mutable/WrappedArray.scala +++ b/src/library/scala/collection/mutable/WrappedArray.scala @@ -45,7 +45,7 @@ extends AbstractSeq[T] def elemTag: ArrayTag[T] @deprecated("use elemTag instead", "2.10.0") - def elemManifest: ClassManifest[T] = ClassManifest[T](arrayElementClass(elemTag)) + def elemManifest: ClassManifest[T] = ClassManifest.fromClass[T](arrayElementClass(elemTag).asInstanceOf[Class[T]]) /** The length of the array */ def length: Int diff --git a/src/library/scala/reflect/ClassManifest.scala b/src/library/scala/reflect/ClassManifest.scala new file mode 100644 index 0000000000..43e043fd40 --- /dev/null +++ b/src/library/scala/reflect/ClassManifest.scala @@ -0,0 +1,242 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +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. + */ +@deprecated("Use `@scala.reflect.ClassTag` instead", "2.10.0") +trait ClassManifest[T] extends OptManifest[T] with ClassTag[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[_] + + 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 + + override 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) + + override 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. + */ +@deprecated("Use `@scala.reflect.ClassTag` instead", "2.10.0") +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 <: AnyRef](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 <: AnyRef](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 <: AnyRef](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 */ +private class ClassTypeManifest[T <: AnyRef]( + 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 +}
\ No newline at end of file diff --git a/src/library/scala/reflect/Manifest.scala b/src/library/scala/reflect/Manifest.scala new file mode 100644 index 0000000000..da029f046d --- /dev/null +++ b/src/library/scala/reflect/Manifest.scala @@ -0,0 +1,259 @@ +/* __ *\ +** ________ ___ / / ___ 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}.") +@deprecated("Use `@scala.reflect.ConcreteTypeTag` instead", "2.10.0") +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.## +} + +@deprecated("Use type tags and manually check the corresponding class or type instead", "2.10.0") +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. + */ +@deprecated("Use `@scala.reflect.ConcreteTypeTag` instead", "2.10.0") +object Manifest { + 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 <:<(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 <:<(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 <:<(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 <:<(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 <:<(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 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) + + private abstract class PhantomManifest[T](override val toString: String) extends ClassTypeManifest[T](None, classOf[java.lang.Object], Nil) { + override def equals(that: Any): Boolean = 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 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 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 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 def toString = parents.mkString(" with ") + } +}
\ No newline at end of file diff --git a/src/library/scala/reflect/NoManifest.scala b/src/library/scala/reflect/NoManifest.scala new file mode 100644 index 0000000000..7b8037272c --- /dev/null +++ b/src/library/scala/reflect/NoManifest.scala @@ -0,0 +1,16 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala.reflect + +/** One of the branches of an [[scala.reflect.OptManifest]]. + */ +@deprecated("Use `@scala.reflect.TypeTag` instead", "2.10.0") +object NoManifest extends OptManifest[Nothing] with Serializable { + override def toString = "<?>" +}
\ No newline at end of file diff --git a/src/library/scala/reflect/OptManifest.scala b/src/library/scala/reflect/OptManifest.scala new file mode 100644 index 0000000000..46f23c4e22 --- /dev/null +++ b/src/library/scala/reflect/OptManifest.scala @@ -0,0 +1,18 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala.reflect + +/** A `OptManifest[T]` is an optional [[scala.reflect.Manifest]]. + * + * It is either a `Manifest` or the value `NoManifest`. + * + * @author Martin Odersky + */ +@deprecated("Use `@scala.reflect.TypeTag` instead", "2.10.0") +trait OptManifest[+T] extends Serializable
\ No newline at end of file diff --git a/src/library/scala/reflect/package.scala b/src/library/scala/reflect/package.scala index 640cad6c21..0e6350183f 100644 --- a/src/library/scala/reflect/package.scala +++ b/src/library/scala/reflect/package.scala @@ -53,20 +53,6 @@ package object reflect { @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") - lazy val NoManifest = TypeTag.Nothing - // ArrayTag trait is defined separately from the mirror // ErasureTag trait is defined separately from the mirror // ConcreteErasureTag trait is defined separately from the mirror |