All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scala.reflect.ClassManifest.scala Maven / Gradle / Ivy

/*                     __                                               *\
**     ________ ___   / /  ___     Scala API                            **
**    / __/ __// _ | / /  / _ |    (c) 2007-2010, LAMP/EPFL             **
**  __\ \/ /__/ __ |/ /__/ __ |    http://scala-lang.org/               **
** /____/\___/_/ |_/____/_/ | |                                         **
**                          |/                                          **
\*                                                                      */



package scala.reflect

import scala.runtime._
import scala.collection.immutable.{List, Nil}
import scala.collection.mutable.{WrappedArray, ArrayBuilder}

/** 

* A ClassManifest[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. *

*/ @serializable trait ClassManifest[T] extends OptManifest[T] with Equals { /** 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[_] /** 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: ClassManifest[_]): 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))) } def subargs(args1: List[OptManifest[_]], args2: List[OptManifest[_]]): Boolean = { (args1 zip args2) forall { case (x: ClassManifest[_], y: ClassManifest[_]) => x <:< y // !!! [Martin] this is wrong, need to take variance into account case (NoManifest, NoManifest) => true case _ => false } } import Manifest.{ AnyVal, Nothing, Null } that match { // All types which conform to AnyVal will override <:<. case _: AnyValManifest[_] => false // Anything which conforms to a bottom type will override <:<. case AnyVal | Nothing | Null => false case _ => (this.erasure == that.erasure || subtype(this.erasure, that.erasure)) && subargs(this.typeArguments, that.typeArguments) } } /** 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: 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. 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: ClassManifest[_] if m canEqual this => this.erasure == m.erasure case _ => false } override def hashCode = this.erasure.## protected def arrayClass[T](tp: Predef.Class[_]): Predef.Class[Array[T]] = java.lang.reflect.Array.newInstance(tp, 0).getClass.asInstanceOf[Predef.Class[Array[T]]] def arrayManifest: ClassManifest[Array[T]] = ClassManifest.classType[Array[T]](arrayClass[T](erasure)) 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 "" } /**

* This object is used by the compiler and should not be used in client * code. 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 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: Predef.Class[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: Predef.Class[_]): 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: Predef.Class[_], 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: Predef.Class[_], args: OptManifest[_]*): ClassManifest[T] = new ClassTypeManifest[T](Some(prefix), clazz, args.toList) /** Manifest for the class type `clazz[args]', where `clazz' is * a top-level or static class. */ @serializable private class ClassTypeManifest[T <: AnyRef](prefix: Option[OptManifest[_]], val erasure: Predef.Class[_], 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 } 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: Predef.Class[_], args: OptManifest[_]*): ClassManifest[T] = new (ClassManifest[T] @serializable) { 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] @serializable) { def erasure = upperbound.erasure override val typeArguments = args.toList override def toString = prefix.toString+"#"+name+argString } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy