Skip to content

Commit 3c43a7b

Browse files
authored
Merge pull request scala#5264 from lrytz/t8561
SI-8561 named subclasses for known Manifest / ClassTag instances
2 parents 1bca386 + 78c3bfd commit 3c43a7b

File tree

3 files changed

+84
-70
lines changed

3 files changed

+84
-70
lines changed

src/library/scala/reflect/ClassTag.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ object ClassTag {
134134
val Nothing : ClassTag[scala.Nothing] = Manifest.Nothing
135135
val Null : ClassTag[scala.Null] = Manifest.Null
136136

137+
private class GenericClassTag[T](val runtimeClass: jClass[_]) extends ClassTag[T]
138+
137139
def apply[T](runtimeClass1: jClass[_]): ClassTag[T] =
138140
runtimeClass1 match {
139141
case java.lang.Byte.TYPE => ClassTag.Byte.asInstanceOf[ClassTag[T]]
@@ -148,7 +150,7 @@ object ClassTag {
148150
case ObjectTYPE => ClassTag.Object.asInstanceOf[ClassTag[T]]
149151
case NothingTYPE => ClassTag.Nothing.asInstanceOf[ClassTag[T]]
150152
case NullTYPE => ClassTag.Null.asInstanceOf[ClassTag[T]]
151-
case _ => new ClassTag[T]{ def runtimeClass = runtimeClass1 }
153+
case _ => new GenericClassTag[T](runtimeClass1)
152154
}
153155

154156
def unapply[T](ctag: ClassTag[T]): Option[Class[_]] = Some(ctag.runtimeClass)

src/library/scala/reflect/Manifest.scala

Lines changed: 66 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
package scala
1010
package reflect
1111

12-
import scala.collection.mutable.{ ArrayBuilder, WrappedArray }
12+
import scala.collection.mutable.{ArrayBuilder, WrappedArray}
1313

1414
/** A `Manifest[T]` is an opaque descriptor for type T. Its supported use
1515
* is to give access to the erasure of the type as a `Class` instance, as
@@ -21,23 +21,22 @@ import scala.collection.mutable.{ ArrayBuilder, WrappedArray }
2121
* which are not yet adequately represented in manifests.
2222
*
2323
* Example usages:
24-
{{{
25-
def arr[T] = new Array[T](0) // does not compile
26-
def arr[T](implicit m: Manifest[T]) = new Array[T](0) // compiles
27-
def arr[T: Manifest] = new Array[T](0) // shorthand for the preceding
28-
29-
// Methods manifest, classManifest, and optManifest are in [[scala.Predef]].
30-
def isApproxSubType[T: Manifest, U: Manifest] = manifest[T] <:< manifest[U]
31-
isApproxSubType[List[String], List[AnyRef]] // true
32-
isApproxSubType[List[String], List[Int]] // false
33-
34-
def methods[T: ClassManifest] = classManifest[T].erasure.getMethods
35-
def retType[T: ClassManifest](name: String) =
36-
methods[T] find (_.getName == name) map (_.getGenericReturnType)
37-
38-
retType[Map[_, _]]("values") // Some(scala.collection.Iterable<B>)
39-
}}}
24+
* {{{
25+
* def arr[T] = new Array[T](0) // does not compile
26+
* def arr[T](implicit m: Manifest[T]) = new Array[T](0) // compiles
27+
* def arr[T: Manifest] = new Array[T](0) // shorthand for the preceding
4028
*
29+
* // Methods manifest, classManifest, and optManifest are in [[scala.Predef]].
30+
* def isApproxSubType[T: Manifest, U: Manifest] = manifest[T] <:< manifest[U]
31+
* isApproxSubType[List[String], List[AnyRef]] // true
32+
* isApproxSubType[List[String], List[Int]] // false
33+
*
34+
* def methods[T: ClassManifest] = classManifest[T].erasure.getMethods
35+
* def retType[T: ClassManifest](name: String) =
36+
* methods[T] find (_.getName == name) map (_.getGenericReturnType)
37+
*
38+
* retType[Map[_, _]]("values") // Some(scala.collection.Iterable<B>)
39+
* }}}
4140
*/
4241
@scala.annotation.implicitNotFound(msg = "No Manifest available for ${T}.")
4342
// TODO undeprecated until Scala reflection becomes non-experimental
@@ -88,71 +87,79 @@ object ManifestFactory {
8887
def valueManifests: List[AnyValManifest[_]] =
8988
List(Byte, Short, Char, Int, Long, Float, Double, Boolean, Unit)
9089

91-
val Byte: AnyValManifest[Byte] = new AnyValManifest[scala.Byte]("Byte") {
90+
private class ByteManifest extends AnyValManifest[scala.Byte]("Byte") {
9291
def runtimeClass = java.lang.Byte.TYPE
9392
override def newArray(len: Int): Array[Byte] = new Array[Byte](len)
9493
override def newWrappedArray(len: Int): WrappedArray[Byte] = new WrappedArray.ofByte(new Array[Byte](len))
9594
override def newArrayBuilder(): ArrayBuilder[Byte] = new ArrayBuilder.ofByte()
9695
private def readResolve(): Any = Manifest.Byte
9796
}
97+
val Byte: AnyValManifest[Byte] = new ByteManifest
9898

99-
val Short: AnyValManifest[Short] = new AnyValManifest[scala.Short]("Short") {
99+
private class ShortManifest extends AnyValManifest[scala.Short]("Short") {
100100
def runtimeClass = java.lang.Short.TYPE
101101
override def newArray(len: Int): Array[Short] = new Array[Short](len)
102102
override def newWrappedArray(len: Int): WrappedArray[Short] = new WrappedArray.ofShort(new Array[Short](len))
103103
override def newArrayBuilder(): ArrayBuilder[Short] = new ArrayBuilder.ofShort()
104104
private def readResolve(): Any = Manifest.Short
105105
}
106+
val Short: AnyValManifest[Short] = new ShortManifest
106107

107-
val Char: AnyValManifest[Char] = new AnyValManifest[scala.Char]("Char") {
108+
private class CharManifest extends AnyValManifest[scala.Char]("Char") {
108109
def runtimeClass = java.lang.Character.TYPE
109110
override def newArray(len: Int): Array[Char] = new Array[Char](len)
110111
override def newWrappedArray(len: Int): WrappedArray[Char] = new WrappedArray.ofChar(new Array[Char](len))
111112
override def newArrayBuilder(): ArrayBuilder[Char] = new ArrayBuilder.ofChar()
112113
private def readResolve(): Any = Manifest.Char
113114
}
115+
val Char: AnyValManifest[Char] = new CharManifest
114116

115-
val Int: AnyValManifest[Int] = new AnyValManifest[scala.Int]("Int") {
117+
private class IntManifest extends AnyValManifest[scala.Int]("Int") {
116118
def runtimeClass = java.lang.Integer.TYPE
117119
override def newArray(len: Int): Array[Int] = new Array[Int](len)
118120
override def newWrappedArray(len: Int): WrappedArray[Int] = new WrappedArray.ofInt(new Array[Int](len))
119121
override def newArrayBuilder(): ArrayBuilder[Int] = new ArrayBuilder.ofInt()
120122
private def readResolve(): Any = Manifest.Int
121123
}
124+
val Int: AnyValManifest[Int] = new IntManifest
122125

123-
val Long: AnyValManifest[Long] = new AnyValManifest[scala.Long]("Long") {
126+
private class LongManifest extends AnyValManifest[scala.Long]("Long") {
124127
def runtimeClass = java.lang.Long.TYPE
125128
override def newArray(len: Int): Array[Long] = new Array[Long](len)
126129
override def newWrappedArray(len: Int): WrappedArray[Long] = new WrappedArray.ofLong(new Array[Long](len))
127130
override def newArrayBuilder(): ArrayBuilder[Long] = new ArrayBuilder.ofLong()
128131
private def readResolve(): Any = Manifest.Long
129132
}
133+
val Long: AnyValManifest[Long] = new LongManifest
130134

131-
val Float: AnyValManifest[Float] = new AnyValManifest[scala.Float]("Float") {
135+
private class FloatManifest extends AnyValManifest[scala.Float]("Float") {
132136
def runtimeClass = java.lang.Float.TYPE
133137
override def newArray(len: Int): Array[Float] = new Array[Float](len)
134138
override def newWrappedArray(len: Int): WrappedArray[Float] = new WrappedArray.ofFloat(new Array[Float](len))
135139
override def newArrayBuilder(): ArrayBuilder[Float] = new ArrayBuilder.ofFloat()
136140
private def readResolve(): Any = Manifest.Float
137141
}
142+
val Float: AnyValManifest[Float] = new FloatManifest
138143

139-
val Double: AnyValManifest[Double] = new AnyValManifest[scala.Double]("Double") {
144+
private class DoubleManifest extends AnyValManifest[scala.Double]("Double") {
140145
def runtimeClass = java.lang.Double.TYPE
141146
override def newArray(len: Int): Array[Double] = new Array[Double](len)
142147
override def newWrappedArray(len: Int): WrappedArray[Double] = new WrappedArray.ofDouble(new Array[Double](len))
143148
override def newArrayBuilder(): ArrayBuilder[Double] = new ArrayBuilder.ofDouble()
144149
private def readResolve(): Any = Manifest.Double
145150
}
151+
val Double: AnyValManifest[Double] = new DoubleManifest
146152

147-
val Boolean: AnyValManifest[Boolean] = new AnyValManifest[scala.Boolean]("Boolean") {
153+
private class BooleanManifest extends AnyValManifest[scala.Boolean]("Boolean") {
148154
def runtimeClass = java.lang.Boolean.TYPE
149155
override def newArray(len: Int): Array[Boolean] = new Array[Boolean](len)
150156
override def newWrappedArray(len: Int): WrappedArray[Boolean] = new WrappedArray.ofBoolean(new Array[Boolean](len))
151157
override def newArrayBuilder(): ArrayBuilder[Boolean] = new ArrayBuilder.ofBoolean()
152158
private def readResolve(): Any = Manifest.Boolean
153159
}
160+
val Boolean: AnyValManifest[Boolean] = new BooleanManifest
154161

155-
val Unit: AnyValManifest[Unit] = new AnyValManifest[scala.Unit]("Unit") {
162+
private class UnitManifest extends AnyValManifest[scala.Unit]("Unit") {
156163
def runtimeClass = java.lang.Void.TYPE
157164
override def newArray(len: Int): Array[Unit] = new Array[Unit](len)
158165
override def newWrappedArray(len: Int): WrappedArray[Unit] = new WrappedArray.ofUnit(new Array[Unit](len))
@@ -162,43 +169,49 @@ object ManifestFactory {
162169
else super.arrayClass(tp)
163170
private def readResolve(): Any = Manifest.Unit
164171
}
172+
val Unit: AnyValManifest[Unit] = new UnitManifest
165173

166174
private val ObjectTYPE = classOf[java.lang.Object]
167175
private val NothingTYPE = classOf[scala.runtime.Nothing$]
168176
private val NullTYPE = classOf[scala.runtime.Null$]
169177

170-
val Any: Manifest[scala.Any] = new PhantomManifest[scala.Any](ObjectTYPE, "Any") {
178+
private class AnyManifest extends PhantomManifest[scala.Any](ObjectTYPE, "Any") {
171179
override def newArray(len: Int) = new Array[scala.Any](len)
172180
override def <:<(that: ClassManifest[_]): Boolean = (that eq this)
173181
private def readResolve(): Any = Manifest.Any
174182
}
183+
val Any: Manifest[scala.Any] = new AnyManifest
175184

176-
val Object: Manifest[java.lang.Object] = new PhantomManifest[java.lang.Object](ObjectTYPE, "Object") {
185+
private class ObjectManifest extends PhantomManifest[java.lang.Object](ObjectTYPE, "Object") {
177186
override def newArray(len: Int) = new Array[java.lang.Object](len)
178187
override def <:<(that: ClassManifest[_]): Boolean = (that eq this) || (that eq Any)
179188
private def readResolve(): Any = Manifest.Object
180189
}
190+
val Object: Manifest[java.lang.Object] = new ObjectManifest
181191

182192
val AnyRef: Manifest[scala.AnyRef] = Object.asInstanceOf[Manifest[scala.AnyRef]]
183193

184-
val AnyVal: Manifest[scala.AnyVal] = new PhantomManifest[scala.AnyVal](ObjectTYPE, "AnyVal") {
194+
private class AnyValPhantomManifest extends PhantomManifest[scala.AnyVal](ObjectTYPE, "AnyVal") {
185195
override def newArray(len: Int) = new Array[scala.AnyVal](len)
186196
override def <:<(that: ClassManifest[_]): Boolean = (that eq this) || (that eq Any)
187197
private def readResolve(): Any = Manifest.AnyVal
188198
}
199+
val AnyVal: Manifest[scala.AnyVal] = new AnyValPhantomManifest
189200

190-
val Null: Manifest[scala.Null] = new PhantomManifest[scala.Null](NullTYPE, "Null") {
201+
private class NullManifest extends PhantomManifest[scala.Null](NullTYPE, "Null") {
191202
override def newArray(len: Int) = new Array[scala.Null](len)
192203
override def <:<(that: ClassManifest[_]): Boolean =
193204
(that ne null) && (that ne Nothing) && !(that <:< AnyVal)
194205
private def readResolve(): Any = Manifest.Null
195206
}
207+
val Null: Manifest[scala.Null] = new NullManifest
196208

197-
val Nothing: Manifest[scala.Nothing] = new PhantomManifest[scala.Nothing](NothingTYPE, "Nothing") {
209+
private class NothingManifest extends PhantomManifest[scala.Nothing](NothingTYPE, "Nothing") {
198210
override def newArray(len: Int) = new Array[scala.Nothing](len)
199211
override def <:<(that: ClassManifest[_]): Boolean = (that ne null)
200212
private def readResolve(): Any = Manifest.Nothing
201213
}
214+
val Nothing: Manifest[scala.Nothing] = new NothingManifest
202215

203216
private class SingletonTypeManifest[T <: AnyRef](value: AnyRef) extends Manifest[T] {
204217
lazy val runtimeClass = value.getClass
@@ -251,31 +264,37 @@ object ManifestFactory {
251264
def arrayType[T](arg: Manifest[_]): Manifest[Array[T]] =
252265
arg.asInstanceOf[Manifest[T]].arrayManifest
253266

267+
private class AbstractTypeManifest[T](prefix: Manifest[_], name: String, upperBound: Predef.Class[_], args: Seq[Manifest[_]]) extends Manifest[T] {
268+
def runtimeClass = upperBound
269+
override val typeArguments = args.toList
270+
override def toString = prefix.toString+"#"+name+argString
271+
}
272+
254273
/** Manifest for the abstract type `prefix # name`. `upperBound` is not
255274
* strictly necessary as it could be obtained by reflection. It was
256275
* added so that erasure can be calculated without reflection. */
257276
def abstractType[T](prefix: Manifest[_], name: String, upperBound: Predef.Class[_], args: Manifest[_]*): Manifest[T] =
258-
new Manifest[T] {
259-
def runtimeClass = upperBound
260-
override val typeArguments = args.toList
261-
override def toString = prefix.toString+"#"+name+argString
262-
}
277+
new AbstractTypeManifest[T](prefix, name, upperBound, args)
278+
279+
private class WildcardManifest[T](lowerBound: Manifest[_], upperBound: Manifest[_]) extends Manifest[T] {
280+
def runtimeClass = upperBound.runtimeClass
281+
override def toString =
282+
"_" +
283+
(if (lowerBound eq Nothing) "" else " >: "+lowerBound) +
284+
(if (upperBound eq Nothing) "" else " <: "+upperBound)
285+
}
263286

264287
/** Manifest for the unknown type `_ >: L <: U` in an existential.
265288
*/
266289
def wildcardType[T](lowerBound: Manifest[_], upperBound: Manifest[_]): Manifest[T] =
267-
new Manifest[T] {
268-
def runtimeClass = upperBound.runtimeClass
269-
override def toString =
270-
"_" +
271-
(if (lowerBound eq Nothing) "" else " >: "+lowerBound) +
272-
(if (upperBound eq Nothing) "" else " <: "+upperBound)
273-
}
290+
new WildcardManifest[T](lowerBound, upperBound)
291+
292+
private class IntersectionTypeManifest[T](parents: Seq[Manifest[_]]) extends Manifest[T] {
293+
def runtimeClass = parents.head.runtimeClass
294+
override def toString = parents.mkString(" with ")
295+
}
274296

275297
/** Manifest for the intersection type `parents_0 with ... with parents_n`. */
276298
def intersectionType[T](parents: Manifest[_]*): Manifest[T] =
277-
new Manifest[T] {
278-
def runtimeClass = parents.head.runtimeClass
279-
override def toString = parents.mkString(" with ")
280-
}
299+
new IntersectionTypeManifest[T](parents)
281300
}

0 commit comments

Comments
 (0)