summaryrefslogtreecommitdiff
path: root/src/library
diff options
context:
space:
mode:
authorGilles Dubochet <gilles.dubochet@epfl.ch>2008-04-24 15:52:13 +0000
committerGilles Dubochet <gilles.dubochet@epfl.ch>2008-04-24 15:52:13 +0000
commit05b846b94dc6820563e5154dd323884530f4c255 (patch)
treeb7c4a9aa74cbbc1c6ddcbdc5585867d59836c090 /src/library
parent04387ad63b82bf79cd89bfacdeaa9f0a2636e578 (diff)
downloadscala-05b846b94dc6820563e5154dd323884530f4c255.tar.gz
scala-05b846b94dc6820563e5154dd323884530f4c255.tar.bz2
scala-05b846b94dc6820563e5154dd323884530f4c255.zip
Manifests are generated when required by an imp...
Manifests are generated when required by an implicit. The generated Manifests are quite simple (for now) and only provide an entry point to the underlying erased type (a java.lang.Class).
Diffstat (limited to 'src/library')
-rw-r--r--src/library/scala/reflect/Manifest.scala141
1 files changed, 106 insertions, 35 deletions
diff --git a/src/library/scala/reflect/Manifest.scala b/src/library/scala/reflect/Manifest.scala
index 14329e9526..09a5655f27 100644
--- a/src/library/scala/reflect/Manifest.scala
+++ b/src/library/scala/reflect/Manifest.scala
@@ -1,56 +1,127 @@
/* __ *\
** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2007, LAMP/EPFL **
+** / __/ __// _ | / / / _ | (c) 2002-2008, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
package scala.reflect
+/** A Manifest[T] is an opaque descriptor for type T. Currently, its only
+ * use is to give access to the erasure of the type as a Class instance.
+ * BE AWARE: The different type-relation operators are all forwarded to
+ * the erased type as an approximation of the final semantics where
+ * these operators should be on the unerased type. */
+trait Manifest[T] {
-/** This type is required by the compiler and <b>should not be used in client code</b>.
- * A Manifest[T] is a descriptor for the type T.
- * The object `Manifest' defines factory methods for manifests which still need to be implemented.
- * Also still to be done are manifests for refinement types.
- */
+ /** 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: Predef.Class[U] forSome { type U }
+
+ /** Tests whether the type represented by this manifest is a subtype of
+ * the type represented by `that' manifest. BE AWARE: the current
+ * implementation is an approximation, as the test is done on the
+ * erasure of the type. */
+ def <:<(that: Manifest[_]): Boolean = {
+ def subtype(sub: Predef.Class[_], sup: Predef.Class[_]): Boolean = {
+ val subSuperClass = sub.getSuperclass
+ val subSuperInterfaces = sub.getInterfaces.toList
+ val subSuper =
+ (if (subSuperClass == null) Nil else List(subSuperClass)) ::: subSuperInterfaces
+ (subSuper contains sup) || (subSuper exists (subtype(_, sup)))
+ }
+ this.erasure == that.erasure || subtype(this.erasure, that.erasure)
+ }
+
+ /** Tests whether the type represented by this manifest is a supertype
+ * of the type represented by `that' manifest. BE AWARE: the current
+ * implementation is an approximation, as the test is done on the
+ * erasure of the type. */
+ def >:>(that: Manifest[_]): Boolean =
+ that <:< this
+
+ /** Tests whether the type represented by this manifest is equal to the
+ * type represented by `that' manifest. BE AWARE: the current
+ * implementation is an approximation, as the test is done on the
+ * erasure of the type. */
+ override def equals(that: Any): Boolean = that match {
+ case m:Manifest[_] => this.erasure == m.erasure
+ case _ => false
+ }
+
+}
+
+/** This object is used by the compiler and <b>should not be used in
+ * client code</b>. The object `Manifest' defines factory methods for
+ * manifests. BE AWARE: The factory for refinement types is missing and
+ * will be implemented in a later version of this class. */
object Manifest {
- /** Manifest for the singleton type `value.type'
- */
- def singleType[T](value: Any): Manifest[T] = null
+ /** Manifest for the singleton type `value.type'. */
+ def singleType[T](value: Any): Manifest[T] =
+ new Manifest[T] {
+ lazy val erasure =
+ value match {
+ case anyRefValue: AnyRef => anyRefValue.getClass
+ case anyValue => error("There is no singleton type for AnyVal values")
+ }
+ override lazy val toString = value.toString + ".type"
+ }
/** Manifest for the class type `clazz', where `clazz' is
- * a top-level or static class
- */
- def classType[T](clazz: Predef.Class[_]): Manifest[T] = null
+ * a top-level or static class. */
+ def classType[T](clazz: Predef.Class[T]): Manifest[T] =
+ new Manifest[T] {
+ val erasure = clazz
+ override lazy val toString = erasure.getName
+ }
/** Manifest for the class type `clazz[args]', where `clazz' is
- * a top-level or static class
- */
- def classType[T](clazz: Predef.Class[_], args: Manifest[_]*): Manifest[T] = null
-
- /** Manifest for the class type `prefix # clazz'
- */
- def classType[T](prefix: Manifest[_], clazz: Predef.Class[_]): Manifest[T] = null
+ * a top-level or static class. */
+ def classType[T](clazz: Predef.Class[_], args: Manifest[_]*): Manifest[T] =
+ new Manifest[T] {
+ val erasure = clazz
+ val typeArguments: Seq[Manifest[_]] = args
+ override lazy val toString = erasure.getName + typeArguments.mkString("[", ", ", "]")
+ }
- /** Manifest for the class type `prefix # clazz[args]'
- */
- def classType[T](prefix: Manifest[_], clazz: Predef.Class[_], args: Manifest[_]*): Manifest[T] = null
+ /** Manifest for the class type `prefix # clazz'. */
+ def classType[T](prefix: Manifest[_], clazz: Predef.Class[_]): Manifest[T] =
+ new Manifest[T] {
+ val erasure = clazz
+ override lazy val toString = prefix.toString + "#" + clazz.getName
+ }
- /** Manifest for the abstract type `prefix # name'
- */
- def abstractType[T](prefix: Manifest[_], name: String): Manifest[T] = null
+ /** Manifest for the class type `prefix # clazz[args]'. */
+ def classType[T](prefix: Manifest[_], clazz: Predef.Class[_], args: Manifest[_]*): Manifest[T] =
+ new Manifest[T] {
+ val erasure = clazz
+ val typeArguments: Seq[Manifest[_]] = args
+ override lazy val toString = prefix.toString + "#" + clazz.getName + typeArguments.mkString("[", ", ", "]")
+ }
- /** Manifest for the abstract type `prefix # name[args]'
- */
- def abstractType[T](prefix: Manifest[_], name: String, args: Manifest[_]*): Manifest[T] = null
+ /** 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: Manifest[_]): Manifest[T] =
+ new Manifest[T] {
+ lazy val erasure = upperBound.erasure
+ override lazy val toString = prefix.toString + "#" + name
+ }
- /** Manifest for the intersection type `parents_0 with ... with parents_n'
- */
- def intersectionType[T](parents: Manifest[_]*): Manifest[T] = null
-}
+ /** Manifest for the abstract type `prefix # name[args]'. */
+ def abstractType[T](prefix: Manifest[_], name: String, upperBound: Manifest[_], args: Manifest[_]*): Manifest[T] =
+ new Manifest[T] {
+ lazy val erasure = upperBound.erasure
+ val typeArguments: Seq[Manifest[_]] = args
+ override lazy val toString = prefix.toString + "#" + name + typeArguments.mkString("[", ", ", "]")
+ }
-/** This type is required by the compiler and <b>should not be used in client code</b>.
- * A Manifest[T] is a descriptor for the type T. */
-abstract class Manifest[T]
+ /** Manifest for the intersection type `parents_0 with ... with parents_n'. */
+ def intersectionType[T](parents: Manifest[_]*): Manifest[T] =
+ new Manifest[T] {
+ lazy val erasure = parents.first.erasure
+ override lazy val toString = parents.mkString(" with ")
+ }
+}