summaryrefslogtreecommitdiff
path: root/src/library/scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/library/scala')
-rw-r--r--src/library/scala/reflect/ClassTag.scala4
-rw-r--r--src/library/scala/reflect/DynamicProxy.scala20
-rw-r--r--src/library/scala/reflect/TagMaterialization.scala49
-rwxr-xr-xsrc/library/scala/reflect/api/Symbols.scala10
-rw-r--r--src/library/scala/reflect/api/TreeBuildUtil.scala20
-rw-r--r--src/library/scala/reflect/api/TypeTags.scala43
-rwxr-xr-xsrc/library/scala/reflect/api/Types.scala14
-rw-r--r--src/library/scala/reflect/makro/Reifiers.scala4
-rw-r--r--src/library/scala/reflect/makro/internal/Utils.scala45
-rw-r--r--src/library/scala/reflect/package.scala2
10 files changed, 96 insertions, 115 deletions
diff --git a/src/library/scala/reflect/ClassTag.scala b/src/library/scala/reflect/ClassTag.scala
index 7138837f0d..fe8a16a484 100644
--- a/src/library/scala/reflect/ClassTag.scala
+++ b/src/library/scala/reflect/ClassTag.scala
@@ -117,6 +117,10 @@ object ClassTag {
case _ => apply[T](rm.typeToClass(tpe.erasure))
}
+ def apply[T](ttag: rm.ConcreteTypeTag[T]): ClassTag[T] =
+ if (ttag.erasure != null) ClassTag[T](ttag.erasure)
+ else ClassTag[T](ttag.tpe)
+
implicit def toDeprecatedClassManifestApis[T](ctag: ClassTag[T]): DeprecatedClassManifestApis[T] = new DeprecatedClassManifestApis[T](ctag)
}
diff --git a/src/library/scala/reflect/DynamicProxy.scala b/src/library/scala/reflect/DynamicProxy.scala
index ffd1e7a39f..02872977f5 100644
--- a/src/library/scala/reflect/DynamicProxy.scala
+++ b/src/library/scala/reflect/DynamicProxy.scala
@@ -2,13 +2,13 @@ package scala.reflect
/**
* A dynamic proxy which redirects method calls and attribute access to a given
* target object at runtime using reflection.
- *
+ *
* Usage example:
- *
+ *
* object x{ def hello = "hello world" }
* val d = new DynamicProxy{ val dynamicProxyTarget = x }
* assert( d.hello == "hello world" )
- *
+ *
* Not supported (yet):
* - implicit conversions and parameters
* - multiple arguments lists
@@ -26,7 +26,7 @@ trait DynamicProxy extends Dynamic{
object DynamicReflectBoxed{
implicit def box[@specialized T]( v:T ) = DynamicReflectBoxed( v.getClass, v )
}
-
+
def selectDynamic( method:String ) = {
val symbol = classToType( dynamicProxyTarget.getClass ).member( newTermName(method).encodedName )
invoke( dynamicProxyTarget, symbol )()
@@ -38,7 +38,7 @@ trait DynamicProxy extends Dynamic{
}
def applyDynamic( method:String )( args:DynamicReflectBoxed* ) : Any
- = applyDynamicNamed( method )( args.map( value => ("",value) ) :_* )
+ = applyDynamicNamed( method )( args.map( value => ("",value) ) :_* )
def applyDynamicNamed( method:String )( args:(String,DynamicReflectBoxed)* ) : Any = {
val class_ = dynamicProxyTarget.getClass
@@ -48,27 +48,27 @@ trait DynamicProxy extends Dynamic{
if(args.size == 0){
invoke( dynamicProxyTarget, symbol )()
} else {
- val call =
+ val call =
Apply(
Select(
TypeApply(
Select(
Select(
- Ident(newFreeTerm("__this", symbolForName("scala.reflect.DynamicProxy").asType, this, null))
+ Ident(newFreeTerm("__this", symbolForName("scala.reflect.DynamicProxy").asType, this))
, newTermName("dynamicProxyTarget")
- ),
+ ),
newTermName("asInstanceOf") )
, List(TypeTree().setType(classToType(class_)))
)
,newTermName(method).encodedName
)
,args.map{ case(name,box) =>
- val value = Ident(newFreeTerm("__arg"+({i+=1;i}.toString), classToType(box.class_), box.value, null))
+ val value = Ident(newFreeTerm("__arg"+({i+=1;i}.toString), classToType(box.class_), box.value))
if( name == "" ) value
else AssignOrNamedArg( Ident(name), value )
}.toList
)
toolbox.runExpr( call )
- }
+ }
}
}
diff --git a/src/library/scala/reflect/TagMaterialization.scala b/src/library/scala/reflect/TagMaterialization.scala
index aede00020f..a7237223f1 100644
--- a/src/library/scala/reflect/TagMaterialization.scala
+++ b/src/library/scala/reflect/TagMaterialization.scala
@@ -65,59 +65,22 @@ object TagMaterialization {
val ConcreteTypeTagClass = selectType(TypeTagsClass, "ConcreteTypeTag")
val ConcreteTypeTagModule = selectTerm(TypeTagsClass, "ConcreteTypeTag")
- def materializeClassTag(tpe: Type): Tree = {
- val prefix = gen.mkAttributedRef(Reflect_mirror) setType singleType(Reflect_mirror.owner.thisPrefix, Reflect_mirror)
- materializeClassTag(prefix, tpe)
- }
-
- def materializeClassTag(prefix: Tree, tpe: Type): Tree = {
- val typetagInScope = c.inferImplicitValue(appliedType(typeRef(prefix.tpe, ConcreteTypeTagClass, Nil), List(tpe)))
- def typetagIsSynthetic(tree: Tree) = tree.isInstanceOf[Block] || (tree exists (sub => sub.symbol == TypeTagModule || sub.symbol == ConcreteTypeTagModule))
- typetagInScope match {
- case success if !success.isEmpty && !typetagIsSynthetic(success) =>
- val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe)))
- Apply(factory, List(Select(typetagInScope, newTermName("tpe"))))
- case _ =>
- val result =
- tpe match {
- case coreTpe if coreTags contains coreTpe =>
- Select(Ident(ClassTagModule), coreTags(coreTpe))
- case _ =>
- if (tpe.typeSymbol == ArrayClass) {
- val componentTpe = tpe.typeArguments(0)
- val classtagInScope = c.inferImplicitValue(appliedType(typeRef(NoPrefix, ClassTagClass, Nil), List(componentTpe)))
- val componentTag = classtagInScope orElse materializeClassTag(prefix, componentTpe)
- Select(componentTag, newTermName("wrap"))
- } else {
- // [Eugene] what's the intended behavior? there's no spec on ClassManifests
- // for example, should we ban Array[T] or should we tag them with Array[AnyRef]?
- // if its the latter, what should be the result of tagging Array[T] where T <: Int?
- if (tpe.typeSymbol.isAbstractType) fail("tpe is an abstract type")
- val erasure =
- if (tpe.typeSymbol.isDerivedValueClass) tpe // [Eugene to Martin] is this correct?
- else tpe.erasure.normalize // necessary to deal with erasures of HK types
- val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe)))
- Apply(factory, List(TypeApply(Ident(newTermName("classOf")), List(TypeTree(erasure)))))
- }
- }
- try c.typeCheck(result)
- catch { case terr @ c.TypeError(pos, msg) => fail(terr) }
- }
- }
+ def materializeClassTag(tpe: Type): Tree =
+ materializeTag(c.reflectMirrorPrefix, tpe, ClassTagModule, c.reifyErasure(tpe))
def materializeTypeTag(tpe: Type, requireConcreteTypeTag: Boolean): Tree = {
def prefix: Tree = ??? // todo. needs to be synthesized from c.prefix
- materializeTypeTag(prefix, tpe, requireConcreteTypeTag)
+ val tagModule = if (requireConcreteTypeTag) ConcreteTypeTagModule else TypeTagModule
+ materializeTag(prefix, tpe, tagModule, c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireConcreteTypeTag = requireConcreteTypeTag))
}
- def materializeTypeTag(prefix: Tree, tpe: Type, requireConcreteTypeTag: Boolean): Tree = {
- val tagModule = if (requireConcreteTypeTag) ConcreteTypeTagModule else TypeTagModule
+ private def materializeTag(prefix: Tree, tpe: Type, tagModule: Symbol, materializer: => Tree): Tree = {
val result =
tpe match {
case coreTpe if coreTags contains coreTpe =>
Select(Select(prefix, tagModule.name), coreTags(coreTpe))
case _ =>
- try c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireConcreteTypeTag = requireConcreteTypeTag)
+ try materializer
catch {
case ex: Throwable =>
// [Eugene] cannot pattern match on an abstract type, so had to do this
diff --git a/src/library/scala/reflect/api/Symbols.scala b/src/library/scala/reflect/api/Symbols.scala
index e47bc7216e..d9293888d9 100755
--- a/src/library/scala/reflect/api/Symbols.scala
+++ b/src/library/scala/reflect/api/Symbols.scala
@@ -120,6 +120,11 @@ trait Symbols { self: Universe =>
*/
def isTerm : Boolean
+ /** Does this symbol represent a package?
+ * If yes, `isTerm` is also guaranteed to be true.
+ */
+ def isPackage : Boolean
+
/** Does this symbol represent the definition of method?
* If yes, `isTerm` is also guaranteed to be true.
*/
@@ -146,6 +151,11 @@ trait Symbols { self: Universe =>
*/
def isClass : Boolean
+ /** Does this symbol represent a package class?
+ * If yes, `isClass` is also guaranteed to be true.
+ */
+ def isPackageClass : Boolean
+
/** Does this symbol represent the definition of a primitive class?
* Namely, is it one of [[scala.Double]], [[scala.Float]], [[scala.Long]], [[scala.Int]], [[scala.Char]],
* [[scala.Short]], [[scala.Byte]], [[scala.Unit]] or [[scala.Boolean]]?
diff --git a/src/library/scala/reflect/api/TreeBuildUtil.scala b/src/library/scala/reflect/api/TreeBuildUtil.scala
index 32d7eefa5b..4f510337c2 100644
--- a/src/library/scala/reflect/api/TreeBuildUtil.scala
+++ b/src/library/scala/reflect/api/TreeBuildUtil.scala
@@ -62,20 +62,34 @@ trait TreeBuildUtil { self: Universe =>
* @param name the name of the free variable
* @param info the type signature of the free variable
* @param value the value of the free variable at runtime
+ * @param flags (optional) flags of the free variable
* @param origin debug information that tells where this symbol comes from
*/
- def newFreeTerm(name: String, info: Type, value: => Any, origin: String): Symbol
+ def newFreeTerm(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): Symbol
- /** Create a fresh free type symbol.
+ /** Create a fresh free non-existential type symbol.
* @param name the name of the free variable
* @param info the type signature of the free variable
* @param value a type tag that captures the value of the free variable
* is completely phantom, since the captured type cannot be propagated to the runtime
* if it could be, we wouldn't be creating a free type to begin with
* the only usage for it is preserving the captured symbol for compile-time analysis
+ * @param flags (optional) flags of the free variable
* @param origin debug information that tells where this symbol comes from
*/
- def newFreeType(name: String, info: Type, value: => Any, origin: String): Symbol
+ def newFreeType(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): Symbol
+
+ /** Create a fresh free existential type symbol.
+ * @param name the name of the free variable
+ * @param info the type signature of the free variable
+ * @param value a type tag that captures the value of the free variable
+ * is completely phantom, since the captured type cannot be propagated to the runtime
+ * if it could be, we wouldn't be creating a free type to begin with
+ * the only usage for it is preserving the captured symbol for compile-time analysis
+ * @param flags (optional) flags of the free variable
+ * @param origin (optional) debug information that tells where this symbol comes from
+ */
+ def newFreeExistential(name: String, info: Type, value: => Any, flags: Long = 0L, origin: String = null): Symbol
/** Create a Modiiers structure given internal flags, qualifier, annotations */
def modifiersFromInternalFlags(flags: Long, privateWithin: Name, annotations: List[Tree]): Modifiers
diff --git a/src/library/scala/reflect/api/TypeTags.scala b/src/library/scala/reflect/api/TypeTags.scala
index 59a7c87f44..85755cd2f2 100644
--- a/src/library/scala/reflect/api/TypeTags.scala
+++ b/src/library/scala/reflect/api/TypeTags.scala
@@ -7,6 +7,7 @@ package scala.reflect
package api
import scala.reflect.{ mirror => rm }
+import java.lang.{ Class => jClass }
import language.implicitConversions
/**
@@ -119,7 +120,7 @@ trait TypeTags { self: Universe =>
* @see [[scala.reflect.api.TypeTags]]
*/
@annotation.implicitNotFound(msg = "No ConcreteTypeTag available for ${T}")
- class ConcreteTypeTag[T](tpe: Type) extends TypeTag[T](tpe) {
+ abstract class ConcreteTypeTag[T](tpe: Type, val erasure: jClass[_]) extends TypeTag[T](tpe) {
// it's unsafe to use assert here, because we might run into deadlocks with Predef
// also see comments in ClassTags.scala
//assert(isConcrete, tpe)
@@ -128,24 +129,24 @@ trait TypeTags { self: Universe =>
}
object ConcreteTypeTag {
- val Byte : ConcreteTypeTag[scala.Byte] = new ConcreteTypeTag[scala.Byte](ByteTpe) { private def readResolve() = ConcreteTypeTag.Byte }
- val Short : ConcreteTypeTag[scala.Short] = new ConcreteTypeTag[scala.Short](ShortTpe) { private def readResolve() = ConcreteTypeTag.Short }
- val Char : ConcreteTypeTag[scala.Char] = new ConcreteTypeTag[scala.Char](CharTpe) { private def readResolve() = ConcreteTypeTag.Char }
- val Int : ConcreteTypeTag[scala.Int] = new ConcreteTypeTag[scala.Int](IntTpe) { private def readResolve() = ConcreteTypeTag.Int }
- val Long : ConcreteTypeTag[scala.Long] = new ConcreteTypeTag[scala.Long](LongTpe) { private def readResolve() = ConcreteTypeTag.Long }
- val Float : ConcreteTypeTag[scala.Float] = new ConcreteTypeTag[scala.Float](FloatTpe) { private def readResolve() = ConcreteTypeTag.Float }
- val Double : ConcreteTypeTag[scala.Double] = new ConcreteTypeTag[scala.Double](DoubleTpe) { private def readResolve() = ConcreteTypeTag.Double }
- val Boolean : ConcreteTypeTag[scala.Boolean] = new ConcreteTypeTag[scala.Boolean](BooleanTpe) { private def readResolve() = ConcreteTypeTag.Boolean }
- val Unit : ConcreteTypeTag[scala.Unit] = new ConcreteTypeTag[scala.Unit](UnitTpe) { private def readResolve() = ConcreteTypeTag.Unit }
- val Any : ConcreteTypeTag[scala.Any] = new ConcreteTypeTag[scala.Any](AnyTpe) { private def readResolve() = ConcreteTypeTag.Any }
- val Object : ConcreteTypeTag[java.lang.Object] = new ConcreteTypeTag[java.lang.Object](ObjectTpe) { private def readResolve() = ConcreteTypeTag.Object }
- val AnyVal : ConcreteTypeTag[scala.AnyVal] = new ConcreteTypeTag[scala.AnyVal](AnyValTpe) { private def readResolve() = ConcreteTypeTag.AnyVal }
- val AnyRef : ConcreteTypeTag[scala.AnyRef] = new ConcreteTypeTag[scala.AnyRef](AnyRefTpe) { private def readResolve() = ConcreteTypeTag.AnyRef }
- val Nothing : ConcreteTypeTag[scala.Nothing] = new ConcreteTypeTag[scala.Nothing](NothingTpe) { private def readResolve() = ConcreteTypeTag.Nothing }
- val Null : ConcreteTypeTag[scala.Null] = new ConcreteTypeTag[scala.Null](NullTpe) { private def readResolve() = ConcreteTypeTag.Null }
- val String : ConcreteTypeTag[java.lang.String] = new ConcreteTypeTag[java.lang.String](StringTpe) { private def readResolve() = ConcreteTypeTag.String }
-
- def apply[T](tpe: Type): ConcreteTypeTag[T] =
+ val Byte : ConcreteTypeTag[scala.Byte] = new ConcreteTypeTag[scala.Byte](ByteTpe, ClassTag.Byte.erasure) { private def readResolve() = ConcreteTypeTag.Byte }
+ val Short : ConcreteTypeTag[scala.Short] = new ConcreteTypeTag[scala.Short](ShortTpe, ClassTag.Short.erasure) { private def readResolve() = ConcreteTypeTag.Short }
+ val Char : ConcreteTypeTag[scala.Char] = new ConcreteTypeTag[scala.Char](CharTpe, ClassTag.Char.erasure) { private def readResolve() = ConcreteTypeTag.Char }
+ val Int : ConcreteTypeTag[scala.Int] = new ConcreteTypeTag[scala.Int](IntTpe, ClassTag.Int.erasure) { private def readResolve() = ConcreteTypeTag.Int }
+ val Long : ConcreteTypeTag[scala.Long] = new ConcreteTypeTag[scala.Long](LongTpe, ClassTag.Long.erasure) { private def readResolve() = ConcreteTypeTag.Long }
+ val Float : ConcreteTypeTag[scala.Float] = new ConcreteTypeTag[scala.Float](FloatTpe, ClassTag.Float.erasure) { private def readResolve() = ConcreteTypeTag.Float }
+ val Double : ConcreteTypeTag[scala.Double] = new ConcreteTypeTag[scala.Double](DoubleTpe, ClassTag.Double.erasure) { private def readResolve() = ConcreteTypeTag.Double }
+ val Boolean : ConcreteTypeTag[scala.Boolean] = new ConcreteTypeTag[scala.Boolean](BooleanTpe, ClassTag.Boolean.erasure) { private def readResolve() = ConcreteTypeTag.Boolean }
+ val Unit : ConcreteTypeTag[scala.Unit] = new ConcreteTypeTag[scala.Unit](UnitTpe, ClassTag.Unit.erasure) { private def readResolve() = ConcreteTypeTag.Unit }
+ val Any : ConcreteTypeTag[scala.Any] = new ConcreteTypeTag[scala.Any](AnyTpe, ClassTag.Any.erasure) { private def readResolve() = ConcreteTypeTag.Any }
+ val Object : ConcreteTypeTag[java.lang.Object] = new ConcreteTypeTag[java.lang.Object](ObjectTpe, ClassTag.Object.erasure) { private def readResolve() = ConcreteTypeTag.Object }
+ val AnyVal : ConcreteTypeTag[scala.AnyVal] = new ConcreteTypeTag[scala.AnyVal](AnyValTpe, ClassTag.AnyVal.erasure) { private def readResolve() = ConcreteTypeTag.AnyVal }
+ val AnyRef : ConcreteTypeTag[scala.AnyRef] = new ConcreteTypeTag[scala.AnyRef](AnyRefTpe, ClassTag.AnyRef.erasure) { private def readResolve() = ConcreteTypeTag.AnyRef }
+ val Nothing : ConcreteTypeTag[scala.Nothing] = new ConcreteTypeTag[scala.Nothing](NothingTpe, ClassTag.Nothing.erasure) { private def readResolve() = ConcreteTypeTag.Nothing }
+ val Null : ConcreteTypeTag[scala.Null] = new ConcreteTypeTag[scala.Null](NullTpe, ClassTag.Null.erasure) { private def readResolve() = ConcreteTypeTag.Null }
+ val String : ConcreteTypeTag[java.lang.String] = new ConcreteTypeTag[java.lang.String](StringTpe, ClassTag.String.erasure) { private def readResolve() = ConcreteTypeTag.String }
+
+ def apply[T](tpe: Type, erasure: jClass[_] = null): ConcreteTypeTag[T] =
tpe match {
case ByteTpe => ConcreteTypeTag.Byte.asInstanceOf[ConcreteTypeTag[T]]
case ShortTpe => ConcreteTypeTag.Short.asInstanceOf[ConcreteTypeTag[T]]
@@ -163,12 +164,12 @@ trait TypeTags { self: Universe =>
case NothingTpe => ConcreteTypeTag.Nothing.asInstanceOf[ConcreteTypeTag[T]]
case NullTpe => ConcreteTypeTag.Null.asInstanceOf[ConcreteTypeTag[T]]
case StringTpe => ConcreteTypeTag.String.asInstanceOf[ConcreteTypeTag[T]]
- case _ => new ConcreteTypeTag[T](tpe) {}
+ case _ => new ConcreteTypeTag[T](tpe, erasure) {}
}
def unapply[T](ttag: TypeTag[T]): Option[Type] = if (ttag.isConcrete) Some(ttag.tpe) else None
- implicit def toClassTag[T](ttag: rm.ConcreteTypeTag[T]): ClassTag[T] = ClassTag[T](rm.typeToClass(ttag.tpe.erasure))
+ implicit def toClassTag[T](ttag: rm.ConcreteTypeTag[T]): ClassTag[T] = ClassTag[T](ttag)
implicit def toDeprecatedManifestApis[T](ttag: rm.ConcreteTypeTag[T]): DeprecatedManifestApis[T] = new DeprecatedManifestApis[T](ttag)
diff --git a/src/library/scala/reflect/api/Types.scala b/src/library/scala/reflect/api/Types.scala
index 5e1c1af2fe..4cb5609166 100755
--- a/src/library/scala/reflect/api/Types.scala
+++ b/src/library/scala/reflect/api/Types.scala
@@ -53,14 +53,26 @@ trait Types { self: Universe =>
*/
def typeArguments: List[Type]
+ /** For a (potentially wrapped) poly type, its type parameters,
+ * the empty list for all other types */
+ def typeParams: List[Symbol]
+
/** Is this type a type constructor that is missing its type arguments?
*/
def isHigherKinded: Boolean // !!! This should be called "isTypeConstructor", no?
- /** Does this type refer to abstract types or is an abstract type?
+ /** Returns the corresponding type constructor (e.g. List for List[T] or List[String])
+ */
+ def typeConstructor: Type
+
+ /** Does this type refer to spliceable types or is a spliceable type?
*/
def isConcrete: Boolean
+ /** Is this type an abstract type that needs to be resolved?
+ */
+ def isSpliceable: Boolean
+
/**
* Expands type aliases and converts higher-kinded TypeRefs to PolyTypes.
* Functions on types are also implemented as PolyTypes.
diff --git a/src/library/scala/reflect/makro/Reifiers.scala b/src/library/scala/reflect/makro/Reifiers.scala
index d690df6aee..b9e82e0387 100644
--- a/src/library/scala/reflect/makro/Reifiers.scala
+++ b/src/library/scala/reflect/makro/Reifiers.scala
@@ -48,6 +48,10 @@ trait Reifiers {
*/
def reifyType(prefix: Tree, tpe: Type, dontSpliceAtTopLevel: Boolean = false, requireConcreteTypeTag: Boolean = false): Tree
+ /** Given a type, generate a tree that when compiled and executed produces the erasure of the original type.
+ */
+ def reifyErasure(tpe: Type): Tree
+
/** Undoes reification of a tree.
*
* This reversion doesn't simply restore the original tree (that would lose the context of reification),
diff --git a/src/library/scala/reflect/makro/internal/Utils.scala b/src/library/scala/reflect/makro/internal/Utils.scala
index db658fd637..604bba10b6 100644
--- a/src/library/scala/reflect/makro/internal/Utils.scala
+++ b/src/library/scala/reflect/makro/internal/Utils.scala
@@ -55,49 +55,22 @@ package internal {
NothingClass.asType -> newTermName("Nothing"),
NullClass.asType -> newTermName("Null"))
- def materializeClassTag(prefix: Tree, tpe: Type): Tree = {
- val typetagInScope = c.inferImplicitValue(appliedType(typeRef(prefix.tpe, ConcreteTypeTagClass, Nil), List(tpe)))
- def typetagIsSynthetic(tree: Tree) = tree.isInstanceOf[Block] || (tree exists (sub => sub.symbol == TypeTagModule || sub.symbol == ConcreteTypeTagModule))
- typetagInScope match {
- case success if !success.isEmpty && !typetagIsSynthetic(success) =>
- val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe)))
- Apply(factory, List(Select(typetagInScope, newTermName("tpe"))))
- case _ =>
- val result =
- tpe match {
- case coreTpe if coreTags contains coreTpe =>
- Select(Ident(ClassTagModule), coreTags(coreTpe))
- case _ =>
- if (tpe.typeSymbol == ArrayClass) {
- val componentTpe = tpe.typeArguments(0)
- val classtagInScope = c.inferImplicitValue(appliedType(typeRef(NoPrefix, ClassTagClass, Nil), List(componentTpe)))
- val componentTag = classtagInScope orElse materializeClassTag(prefix, componentTpe)
- Select(componentTag, newTermName("wrap"))
- } else {
- // [Eugene] what's the intended behavior? there's no spec on ClassManifests
- // for example, should we ban Array[T] or should we tag them with Array[AnyRef]?
- // if its the latter, what should be the result of tagging Array[T] where T <: Int?
- if (tpe.typeSymbol.isAbstractType) fail("tpe is an abstract type")
- val erasure =
- if (tpe.typeSymbol.isDerivedValueClass) tpe // [Eugene to Martin] is this correct?
- else tpe.erasure.normalize // necessary to deal with erasures of HK types
- val factory = TypeApply(Select(Ident(ClassTagModule), newTermName("apply")), List(TypeTree(tpe)))
- Apply(factory, List(TypeApply(Ident(newTermName("classOf")), List(TypeTree(erasure)))))
- }
- }
- try c.typeCheck(result)
- catch { case terr @ c.TypeError(pos, msg) => fail(terr) }
- }
- }
+ def materializeClassTag(prefix: Tree, tpe: Type): Tree =
+ materializeTag(prefix, tpe, ClassTagModule, c.reifyErasure(tpe))
def materializeTypeTag(prefix: Tree, tpe: Type, requireConcreteTypeTag: Boolean): Tree = {
val tagModule = if (requireConcreteTypeTag) ConcreteTypeTagModule else TypeTagModule
+ materializeTag(prefix, tpe, tagModule, c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireConcreteTypeTag = requireConcreteTypeTag))
+ }
+
+ private def materializeTag(prefix: Tree, tpe: Type, tagModule: Symbol, materializer: => Tree): Tree = {
val result =
tpe match {
case coreTpe if coreTags contains coreTpe =>
- Select(Select(prefix, tagModule.name), coreTags(coreTpe))
+ val ref = if (tagModule.owner.isPackageClass) Ident(tagModule) else Select(prefix, tagModule.name)
+ Select(ref, coreTags(coreTpe))
case _ =>
- try c.reifyType(prefix, tpe, dontSpliceAtTopLevel = true, requireConcreteTypeTag = requireConcreteTypeTag)
+ try materializer
catch {
case ex: Throwable =>
// [Eugene] cannot pattern match on an abstract type, so had to do this
diff --git a/src/library/scala/reflect/package.scala b/src/library/scala/reflect/package.scala
index 6d50a96dfd..93fd0bb711 100644
--- a/src/library/scala/reflect/package.scala
+++ b/src/library/scala/reflect/package.scala
@@ -64,7 +64,7 @@ package object reflect {
@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")
- object NoManifest extends OptManifest[Nothing](scala.reflect.mirror.definitions.NothingClass.asType) with Serializable
+ object NoManifest extends OptManifest[Nothing](scala.reflect.mirror.TypeTag.Nothing.tpe)
// ClassTag class is defined separately from the mirror
type TypeTag[T] = scala.reflect.mirror.TypeTag[T]