summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-03-09 16:28:48 -0500
committerPaul Phillips <paulp@improving.org>2012-03-09 18:51:48 -0500
commitf1c39dd9816fd48663064307c39e2d9c8c936cd5 (patch)
tree68cec6bd3ab035fec3fa48da2fe664bbddcee8cb /src
parent42f90593538a16a285a9bb605da9fd9116e71a57 (diff)
downloadscala-f1c39dd9816fd48663064307c39e2d9c8c936cd5.tar.gz
scala-f1c39dd9816fd48663064307c39e2d9c8c936cd5.tar.bz2
scala-f1c39dd9816fd48663064307c39e2d9c8c936cd5.zip
Add symbol to Manifests.
Phantom types were vanishing during the erasure which takes place from manifest -> class object -> tpe.
Diffstat (limited to 'src')
-rw-r--r--src/library/scala/reflect/ClassManifest.scala4
-rw-r--r--src/library/scala/reflect/Manifest.scala25
2 files changed, 22 insertions, 7 deletions
diff --git a/src/library/scala/reflect/ClassManifest.scala b/src/library/scala/reflect/ClassManifest.scala
index 466b57dea7..d393ac47fa 100644
--- a/src/library/scala/reflect/ClassManifest.scala
+++ b/src/library/scala/reflect/ClassManifest.scala
@@ -46,7 +46,9 @@ trait ClassManifest[T] extends OptManifest[T] with Equals with Serializable {
/** The Scala type described by this manifest.
*/
- lazy val tpe: mirror.Type = reflect.mirror.classToType(erasure)
+ 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 = {
diff --git a/src/library/scala/reflect/Manifest.scala b/src/library/scala/reflect/Manifest.scala
index 6c02878b19..e5df487be9 100644
--- a/src/library/scala/reflect/Manifest.scala
+++ b/src/library/scala/reflect/Manifest.scala
@@ -76,6 +76,8 @@ abstract class AnyValManifest[T <: AnyVal](override val toString: String) extend
* in client code.
*/
object Manifest {
+ import mirror.{ definitions => mdefs }
+
def valueManifests: List[AnyValManifest[_]] =
List(Byte, Short, Char, Int, Long, Float, Double, Boolean, Unit)
@@ -152,34 +154,40 @@ object Manifest {
}
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 tpe = mirror.SingleType(mirror.NoPrefix, InstanceRefSymbol(value)) // todo: change to freevar
+ 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"
}
@@ -208,8 +216,12 @@ object Manifest {
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 def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef]
+ 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)
}
@@ -218,13 +230,13 @@ object Manifest {
private class ClassTypeManifest[T](prefix: Option[Manifest[_]],
val erasure: Predef.Class[_],
override val typeArguments: List[Manifest[_]]) extends Manifest[T] {
+
override lazy val tpe = {
- val clazz = classToSymbol(erasure)
val pre = prefix match {
case Some(pm) => pm.tpe
- case None => clazz.owner.thisPrefix
+ case None => symbol.owner.thisPrefix
}
- namedType(pre, clazz, typeArguments map (_.tpe))
+ namedType(pre, symbol, typeArguments map (_.tpe))
}
override def toString =
@@ -282,8 +294,9 @@ object Manifest {
* 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 erasure = mirror.typeToClass(_tpe.erasedType)
override def toString = _tpe.toString
}
}