summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2012-04-22 18:49:09 +0200
committerEugene Burmako <xeno.by@gmail.com>2012-04-23 17:55:26 +0200
commitf54e5c8bbdd719b5c9375c64c2f66b841984456e (patch)
tree975475778e6102c8f2dbbff0f25a2f114204cbbb /src
parent0f0144c74088e396fc1440166bed5a7c6d5f44f4 (diff)
downloadscala-f54e5c8bbdd719b5c9375c64c2f66b841984456e.tar.gz
scala-f54e5c8bbdd719b5c9375c64c2f66b841984456e.tar.bz2
scala-f54e5c8bbdd719b5c9375c64c2f66b841984456e.zip
resurrects manifests in their pre-2.10 glory
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/reflect/internal/Definitions.scala7
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeGen.scala16
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala107
-rw-r--r--src/library/scala/Predef.scala11
-rw-r--r--src/library/scala/collection/mutable/WrappedArray.scala2
-rw-r--r--src/library/scala/reflect/ClassManifest.scala242
-rw-r--r--src/library/scala/reflect/Manifest.scala259
-rw-r--r--src/library/scala/reflect/NoManifest.scala16
-rw-r--r--src/library/scala/reflect/OptManifest.scala18
-rw-r--r--src/library/scala/reflect/package.scala14
10 files changed, 667 insertions, 25 deletions
diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala
index 29eb573b64..6cb935edad 100644
--- a/src/compiler/scala/reflect/internal/Definitions.scala
+++ b/src/compiler/scala/reflect/internal/Definitions.scala
@@ -485,6 +485,13 @@ trait Definitions extends reflect.api.StandardDefinitions {
// [Eugene] is this a good place for ReflectMirrorPrefix?
def ReflectMirrorPrefix = gen.mkAttributedRef(ReflectMirror) setType singleType(ReflectMirror.owner.thisPrefix, ReflectMirror)
+ lazy val PartialManifestClass = getRequiredClass("scala.reflect.ClassManifest")
+ lazy val PartialManifestModule = getRequiredModule("scala.reflect.ClassManifest")
+ lazy val FullManifestClass = getRequiredClass("scala.reflect.Manifest")
+ lazy val FullManifestModule = getRequiredModule("scala.reflect.Manifest")
+ lazy val OptManifestClass = getRequiredClass("scala.reflect.OptManifest")
+ lazy val NoManifest = getRequiredModule("scala.reflect.NoManifest")
+
lazy val ExprClass = getMember(getRequiredClass("scala.reflect.api.Exprs"), tpnme.Expr)
def ExprTree = getMemberClass(ExprClass, nme.tree)
def ExprTpe = getMemberClass(ExprClass, nme.tpe)
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
index d3e64811d3..978d83616b 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
@@ -177,6 +177,22 @@ abstract class TreeGen extends reflect.internal.TreeGen with TreeDSL {
def mkSysErrorCall(message: String): Tree =
mkMethodCall(Sys_error, List(Literal(Constant(message))))
+ /** A creator for a call to a scala.reflect.Manifest or ClassManifest factory method.
+ *
+ * @param full full or partial manifest (target will be Manifest or ClassManifest)
+ * @param constructor name of the factory method (e.g. "classType")
+ * @param tparg the type argument
+ * @param args value arguments
+ * @return the tree
+ */
+ def mkManifestFactoryCall(full: Boolean, constructor: String, tparg: Type, args: List[Tree]): Tree =
+ mkMethodCall(
+ if (full) FullManifestModule else PartialManifestModule,
+ newTermName(constructor),
+ List(tparg),
+ args
+ )
+
/** Make a synchronized block on 'monitor'. */
def mkSynchronized(monitor: Tree, body: Tree): Tree =
Apply(Select(monitor, Object_synchronized), List(body))
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index 3f4e941ec6..fadb691cb6 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -1129,7 +1129,10 @@ trait Implicits {
ConcreteTypeTagClass -> MacroInternal_materializeConcreteTypeTag
)
- def tagOfType(pre: Type, tp: Type, tagClass: Symbol): SearchResult = {
+ /** Creates a tree will produce a tag of the requested flavor.
+ * An EmptyTree is returned if materialization fails.
+ */
+ private def tagOfType(pre: Type, tp: Type, tagClass: Symbol): SearchResult = {
def success(arg: Tree) =
try {
val tree1 = typed(atPos(pos.focus)(arg))
@@ -1171,9 +1174,111 @@ trait Implicits {
else failure(materializer, "macros are disabled")
}
+ private val ManifestSymbols = Set[Symbol](PartialManifestClass, FullManifestClass, OptManifestClass)
+
+ /** Creates a tree that calls the relevant factory method in object
+ * reflect.Manifest for type 'tp'. An EmptyTree is returned if
+ * no manifest is found. todo: make this instantiate take type params as well?
+ */
+ private def manifestOfType(tp: Type, full: Boolean): SearchResult = {
+
+ /** Creates a tree that calls the factory method called constructor in object reflect.Manifest */
+ def manifestFactoryCall(constructor: String, tparg: Type, args: Tree*): Tree =
+ if (args contains EmptyTree) EmptyTree
+ else typedPos(tree.pos.focus) {
+ val mani = gen.mkManifestFactoryCall(full, constructor, tparg, args.toList)
+ if (settings.debug.value) println("generated manifest: "+mani) // DEBUG
+ mani
+ }
+
+ /** Creates a tree representing one of the singleton manifests.*/
+ def findSingletonManifest(name: String) = typedPos(tree.pos.focus) {
+ Select(gen.mkAttributedRef(FullManifestModule), name)
+ }
+
+ /** Re-wraps a type in a manifest before calling inferImplicit on the result */
+ def findManifest(tp: Type, manifestClass: Symbol = if (full) FullManifestClass else PartialManifestClass) =
+ inferImplicit(tree, appliedType(manifestClass, tp), true, false, context).tree
+
+ def findSubManifest(tp: Type) = findManifest(tp, if (full) FullManifestClass else OptManifestClass)
+ def mot(tp0: Type, from: List[Symbol], to: List[Type]): SearchResult = {
+ implicit def wrapResult(tree: Tree): SearchResult =
+ if (tree == EmptyTree) SearchFailure else new SearchResult(tree, if (from.isEmpty) EmptyTreeTypeSubstituter else new TreeTypeSubstituter(from, to))
+
+ val tp1 = tp0.normalize
+ tp1 match {
+ case ThisType(_) | SingleType(_, _) =>
+ // can't generate a reference to a value that's abstracted over by an existential
+ if (containsExistential(tp1)) EmptyTree
+ else manifestFactoryCall("singleType", tp, gen.mkAttributedQualifier(tp1))
+ case ConstantType(value) =>
+ manifestOfType(tp1.deconst, full)
+ case TypeRef(pre, sym, args) =>
+ if (isPrimitiveValueClass(sym) || isPhantomClass(sym)) {
+ findSingletonManifest(sym.name.toString)
+ } else if (sym == ObjectClass || sym == AnyRefClass) {
+ findSingletonManifest("Object")
+ } else if (sym == RepeatedParamClass || sym == ByNameParamClass) {
+ EmptyTree
+ } else if (sym == ArrayClass && args.length == 1) {
+ manifestFactoryCall("arrayType", args.head, findManifest(args.head))
+ } else if (sym.isClass) {
+ val classarg0 = gen.mkClassOf(tp1)
+ val classarg = tp match {
+ case _: ExistentialType => gen.mkCast(classarg0, ClassType(tp))
+ case _ => classarg0
+ }
+ val suffix = classarg :: (args map findSubManifest)
+ manifestFactoryCall(
+ "classType", tp,
+ (if ((pre eq NoPrefix) || pre.typeSymbol.isStaticOwner) suffix
+ else findSubManifest(pre) :: suffix): _*)
+ } else if (sym.isExistentiallyBound && full) {
+ manifestFactoryCall("wildcardType", tp,
+ findManifest(tp.bounds.lo), findManifest(tp.bounds.hi))
+ }
+ // looking for a manifest of a type parameter that hasn't been inferred by now,
+ // can't do much, but let's not fail
+ else if (undetParams contains sym) {
+ // #3859: need to include the mapping from sym -> NothingClass.tpe in the SearchResult
+ mot(NothingClass.tpe, sym :: from, NothingClass.tpe :: to)
+ } else {
+ // a manifest should have been found by normal searchImplicit
+ EmptyTree
+ }
+ case RefinedType(parents, decls) => // !!! not yet: if !full || decls.isEmpty =>
+ // refinement is not generated yet
+ if (hasLength(parents, 1)) findManifest(parents.head)
+ else if (full) manifestFactoryCall("intersectionType", tp, parents map findSubManifest: _*)
+ else mot(erasure.intersectionDominator(parents), from, to)
+ case ExistentialType(tparams, result) =>
+ mot(tp1.skolemizeExistential, from, to)
+ case _ =>
+ EmptyTree
+/* !!! the following is almost right, but we have to splice nested manifest
+ * !!! types into this type. This requires a substantial extension of
+ * !!! reifiers.
+ val reifier = new Reifier()
+ val rtree = reifier.reifyTopLevel(tp1)
+ manifestFactoryCall("apply", tp, rtree)
+*/
+ }
+ }
+
+ mot(tp, Nil, Nil)
+ }
+
+ def wrapResult(tree: Tree): SearchResult =
+ if (tree == EmptyTree) SearchFailure else new SearchResult(tree, EmptyTreeTypeSubstituter)
+
/** The tag corresponding to type `pt`, provided `pt` is a flavor of a tag.
*/
private def implicitTagOrOfExpectedType(pt: Type): SearchResult = pt.dealias match {
+ case TypeRef(pre, sym, arg :: Nil) if ManifestSymbols(sym) =>
+ manifestOfType(arg, sym == FullManifestClass) match {
+ case SearchFailure if sym == OptManifestClass => wrapResult(gen.mkAttributedRef(NoManifest))
+ case result => result
+ }
case TypeRef(pre, sym, arg :: Nil) if TagSymbols(sym) =>
tagOfType(pre, arg, sym)
case tp@TypeRef(_, sym, _) if sym.isAbstractType =>
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