summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2012-07-31 10:50:54 +0200
committerEugene Burmako <xeno.by@gmail.com>2012-08-02 15:50:09 +0200
commitb578059b43a4caaadee2cb20f74cd9a7c876c8ef (patch)
treee412b8c89cabf318a0f0c99cc26d0f1486e5e532
parent013acf6eb0117ca12ab2a0d0e8560df40a7392a3 (diff)
downloadscala-b578059b43a4caaadee2cb20f74cd9a7c876c8ef.tar.gz
scala-b578059b43a4caaadee2cb20f74cd9a7c876c8ef.tar.bz2
scala-b578059b43a4caaadee2cb20f74cd9a7c876c8ef.zip
SI-5888 Mirrors now have sane toStrings
Adds informative toString for InstanceMirror, FieldMirror, MethodMirror (for methods and constructors), ClassMirror and ModuleMirror. Universe mirrors (e.g. JavaMirrors or compiler mirrors) already have good toString methods that show their affiliation and/or classpaths.
-rw-r--r--src/reflect/scala/reflect/runtime/JavaMirrors.scala32
-rw-r--r--test/files/run/reflection-allmirrors-tostring.check14
-rw-r--r--test/files/run/reflection-allmirrors-tostring.scala43
3 files changed, 88 insertions, 1 deletions
diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
index 6ae7e6d7eb..b11eda9b7b 100644
--- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala
+++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
@@ -187,6 +187,7 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym
checkMemberOf(mod, symbol)
new JavaModuleMirror(instance, mod)
}
+ override def toString = s"instance mirror for $obj"
}
private class JavaFieldMirror(val receiver: AnyRef, val symbol: TermSymbol)
@@ -201,6 +202,32 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym
if (!symbol.isMutable) ErrorSetImmutableField(symbol)
jfield.set(receiver, value)
}
+ override def toString = s"field mirror for ${symbol.fullName} (bound to $receiver)"
+ }
+
+ private def showMethodSig(symbol: MethodSymbol): String = {
+ var sig = s"${symbol.fullName}"
+ if (symbol.typeParams.nonEmpty) {
+ def showTparam(tparam: Symbol) =
+ tparam.typeSignature match {
+ case tpe @ TypeBounds(_, _) => s"${tparam.name}$tpe"
+ case _ => tparam.name
+ }
+ def showTparams(tparams: List[Symbol]) = "[" + (tparams map showTparam mkString ", ") + "]"
+ sig += showTparams(symbol.typeParams)
+ }
+ if (symbol.allParams.nonEmpty) {
+ def showParam(param: Symbol) = s"${param.name}: ${param.typeSignature}"
+ def showParams(params: List[Symbol]) = {
+ val s_mods = if (params.nonEmpty && params(0).hasFlag(IMPLICIT)) "implicit " else ""
+ val s_params = params map showParam mkString ", "
+ "(" + s_mods + s_params + ")"
+ }
+ def showParamss(paramss: List[List[Symbol]]) = paramss map showParams mkString ""
+ sig += showParamss(symbol.allParams)
+ }
+ sig += s": ${symbol.resultType}"
+ sig
}
private class JavaMethodMirror(val receiver: AnyRef, val symbol: MethodSymbol)
@@ -220,6 +247,7 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym
}
else
jmeth.invoke(receiver, args.asInstanceOf[Seq[AnyRef]]: _*)
+ override def toString = s"method mirror for ${showMethodSig(symbol)} (bound to $receiver)"
}
private class JavaConstructorMirror(val outer: AnyRef, val symbol: MethodSymbol)
@@ -236,9 +264,9 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym
else outer +: args.asInstanceOf[Seq[AnyRef]]
jconstr.newInstance(effectiveArgs: _*)
}
+ override def toString = s"constructor mirror for ${showMethodSig(symbol)} (bound to $outer)"
}
-
private abstract class JavaTemplateMirror
extends TemplateMirror {
def outer: AnyRef
@@ -256,6 +284,7 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym
case module: ModuleSymbol => Some(new JavaModuleMirror(outer, module))
case _ => None
}
+ override def toString = s"class mirror for ${symbol.fullName} (bound to $outer)"
}
private class JavaModuleMirror(val outer: AnyRef, val symbol: ModuleSymbol)
@@ -270,6 +299,7 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym
case cls: ClassSymbol => Some(new JavaClassMirror(outer, cls))
case _ => None
}
+ override def toString = s"module mirror for ${symbol.fullName} (bound to $outer)"
}
// -------------------- Java to Scala -----------------------------------
diff --git a/test/files/run/reflection-allmirrors-tostring.check b/test/files/run/reflection-allmirrors-tostring.check
new file mode 100644
index 0000000000..b5fe6c33bb
--- /dev/null
+++ b/test/files/run/reflection-allmirrors-tostring.check
@@ -0,0 +1,14 @@
+class mirror for C (bound to null)
+module mirror for M (bound to null)
+instance mirror for an instance of C
+field mirror for C.f1 (bound to an instance of C)
+field mirror for C.f2 (bound to an instance of C)
+method mirror for C.m1: Int (bound to an instance of C)
+method mirror for C.m2(): Int (bound to an instance of C)
+method mirror for C.m3[T >: String <: Int]: T (bound to an instance of C)
+method mirror for C.m4[A, B <: A[Int]](x: A[B])(implicit y: Int): Nothing (bound to an instance of C)
+method mirror for C.m5(x: => Int, y: Int*): String (bound to an instance of C)
+class mirror for C.C (bound to an instance of C)
+module mirror for C.M (bound to an instance of C)
+constructor mirror for C.<init>(): C (bound to null)
+constructor mirror for C.C.<init>(): C.this.C (bound to an instance of C)
diff --git a/test/files/run/reflection-allmirrors-tostring.scala b/test/files/run/reflection-allmirrors-tostring.scala
new file mode 100644
index 0000000000..73afff291c
--- /dev/null
+++ b/test/files/run/reflection-allmirrors-tostring.scala
@@ -0,0 +1,43 @@
+import scala.reflect.runtime.universe._
+
+class C {
+ val f1 = 2
+ var f2 = 3
+
+ def m1 = 4
+ def m2() = 5
+ def m3[T >: String <: Int]: T = ???
+ def m4[A[_], B <: A[Int]](x: A[B])(implicit y: Int) = ???
+ def m5(x: => Int, y: Int*): String = ???
+
+ class C
+ object M
+
+ override def toString = "an instance of C"
+}
+object M
+
+object Test extends App {
+ val cm = scala.reflect.runtime.currentMirror
+// println(cm)
+
+ println(cm.reflectClass(cm.staticClass("C")))
+ println(cm.reflectModule(cm.staticModule("M")))
+ println(cm.reflect(new C))
+
+ val im = cm.reflect(new C)
+ println(im.reflectField(typeOf[C].member(newTermName("f1")).asTerm))
+ println(im.reflectField(typeOf[C].member(newTermName("f2")).asTerm))
+ println(im.reflectMethod(typeOf[C].member(newTermName("m1")).asMethod))
+ println(im.reflectMethod(typeOf[C].member(newTermName("m2")).asMethod))
+ println(im.reflectMethod(typeOf[C].member(newTermName("m3")).asMethod))
+ println(im.reflectMethod(typeOf[C].member(newTermName("m4")).asMethod))
+ println(im.reflectMethod(typeOf[C].member(newTermName("m5")).asMethod))
+ println(im.reflectClass(typeOf[C].member(newTypeName("C")).asClass))
+ println(im.reflectModule(typeOf[C].member(newTermName("M")).asModule))
+
+ val c = cm.staticClass("C")
+ val cc = typeOf[C].member(newTypeName("C")).asClass
+ println(cm.reflectClass(c).reflectConstructor(c.typeSignature.member(nme.CONSTRUCTOR).asMethod))
+ println(im.reflectClass(cc).reflectConstructor(cc.typeSignature.member(nme.CONSTRUCTOR).asMethod))
+} \ No newline at end of file