1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
/* NSC -- new Scala compiler
* Copyright 2005-2011 LAMP/EPFL
* @author Paul Phillips
*/
package scala.tools.nsc
package interpreter
import java.lang.{ reflect => r }
import r.TypeVariable
import scala.reflect.NameTransformer
/** Logic for turning a type into a String. The goal is to be
* able to take some arbitrary object 'x' and obtain the most precise
* String for which an injection of x.asInstanceOf[String] will
* be valid from both the JVM's and scala's perspectives.
*
* "definition" is when you want strings like
*/
trait TypeStrings {
private val ObjectClass = classOf[java.lang.Object]
private val primitives = Set[String]("byte", "char", "short", "int", "long", "float", "double", "boolean")
private def unbox(s: String): String = s.stripPrefix("java.lang.") match {
case "Integer" => "scala.Int"
case "Character" => "scala.Char"
case "Void" => "scala.Unit"
case x @ ("Byte" | "Short" | "Long" | "Float" | "Double" | "Boolean") => "scala." + x
case _ => NameTransformer.decode(s)
}
def scalaName(s: String): String = {
if (s endsWith "$") (s dropRight 1) + ".type"
else if (primitives(s)) "scala." + s.capitalize
else if (s == "void") "scala.Unit"
else unbox(s)
}
def scalaName(clazz: JClass): String = scalaName(clazz.getName)
def scalaName(m: ClassManifest[_]): String = scalaName(m.erasure)
def anyClass(x: Any): JClass = if (x == null) null else x.asInstanceOf[AnyRef].getClass
private def tvarString(tvar: TypeVariable[_]): String = tvarString(tvar.getBounds.toList)
private def tvarString(bounds: List[AnyRef]): String = {
val xs = bounds filterNot (_ == ObjectClass) collect { case x: Class[_] => x }
if (xs.isEmpty) "_"
else scalaName(xs.head)
}
private def tparamString(clazz: JClass): String = {
val tps = clazz.getTypeParameters.toList
if (tps.isEmpty)
return ""
(tps map tvarString).mkString("[", ", ", "]")
}
private def tparamString[T: Manifest] : String = {
val tps = manifest[T].typeArguments
if (tps.isEmpty)
return ""
tps.map(m => tvarString(List(m.erasure))).mkString("[", ", ", "]")
}
/** Going for an overabundance of caution right now.
*/
def fromTypedValue[T: Manifest](x: T): String = fromManifest[T]
def fromValue(value: Any): String = if (value == null) "Null" else fromClazz(anyClass(value))
def fromClazz(clazz: JClass): String = scalaName(clazz) + tparamString(clazz)
def fromManifest[T: Manifest] : String = scalaName(manifest[T].erasure) + tparamString[T]
/** Reducing fully qualified noise for some common packages.
*/
val typeTransforms = List(
"java.lang." -> "",
"scala.collection.immutable." -> "immutable.",
"scala.collection.mutable." -> "mutable.",
"scala.collection.generic." -> "generic."
)
}
object TypeStrings extends TypeStrings { }
|