summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala')
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala78
1 files changed, 78 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala b/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala
new file mode 100644
index 0000000000..91dee97277
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala
@@ -0,0 +1,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 { } \ No newline at end of file