diff options
Diffstat (limited to 'test/files/run/reflection-valueclasses-magic.scala')
-rw-r--r-- | test/files/run/reflection-valueclasses-magic.scala | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/test/files/run/reflection-valueclasses-magic.scala b/test/files/run/reflection-valueclasses-magic.scala new file mode 100644 index 0000000000..f9feb2d504 --- /dev/null +++ b/test/files/run/reflection-valueclasses-magic.scala @@ -0,0 +1,110 @@ +import scala.reflect.runtime.universe._ +import scala.reflect.runtime.universe.definitions._ +import scala.reflect.runtime.{currentMirror => cm} +import scala.reflect.ClassTag + +object Test extends App { + def key(sym: Symbol) = { + sym match { + // initialize parameter symbols + case meth: MethodSymbol => meth.params.flatten.map(_.typeSignature) + } + sym + ": " + sym.typeSignature + } + + def convert(value: Any, tpe: Type) = { + import scala.runtime.BoxesRunTime._ + if (tpe =:= typeOf[Byte]) toByte(value) + else if (tpe =:= typeOf[Short]) toShort(value) + else if (tpe =:= typeOf[Char]) toCharacter(value) + else if (tpe =:= typeOf[Int]) toInteger(value) + else if (tpe =:= typeOf[Long]) toLong(value) + else if (tpe =:= typeOf[Float]) toFloat(value) + else if (tpe =:= typeOf[Double]) toDouble(value) + else if (tpe =:= typeOf[String]) value.toString + else if (tpe =:= typeOf[Boolean]) value.asInstanceOf[Boolean] + else throw new Exception(s"not supported: value = $value, tpe = $tpe") + } + + def test[T: ClassTag](tpe: Type, receiver: T, method: String, args: Any*) { + def wrap[T](op: => T) = + try { + var result = op.asInstanceOf[AnyRef] + if (scala.runtime.ScalaRunTime.isArray(result)) + result = scala.runtime.ScalaRunTime.toObjectArray(result).toList + println(s"[${result.getClass}] =======> $result") + } catch { + case ex: Throwable => + val realex = scala.reflect.runtime.ReflectionUtils.unwrapThrowable(ex) + println(realex.getClass + ": " + realex.getMessage) + } + val meth = tpe.declaration(newTermName(method).encodedName.toTermName) + val testees = if (meth.isMethod) List(meth.asMethod) else meth.asTerm.alternatives.map(_.asMethod) + testees foreach (testee => { + val convertedArgs = args.zipWithIndex.map { case (arg, i) => convert(arg, testee.params.flatten.apply(i).typeSignature) } + print(s"testing ${tpe.typeSymbol.name}.$method(${testee.params.flatten.map(_.typeSignature).mkString(','.toString)}) with receiver = $receiver and args = ${convertedArgs.map(arg => arg + ' '.toString + arg.getClass).toList}: ") + wrap(cm.reflect(receiver).reflectMethod(testee)(convertedArgs: _*)) + }) + } + def header(tpe: Type) { + println(s"============\n$tpe") + println("it's important to print the list of Byte's members") + println("if some of them change (possibly, adding and/or removing magic symbols), we must update this test") + tpe.members.toList.sortBy(key).foreach(sym => println(key(sym))) + } + + def testNumeric[T: ClassTag](tpe: Type, value: T) { + header(tpe) + List("toByte", "toShort", "toChar", "toInt", "toLong", "toFloat", "toDouble") foreach (meth => test(tpe, value, meth)) + test(tpe, value, "==", 2) + test(tpe, value, "!=", 2) + test(tpe, value, "<", 2) + test(tpe, value, "<=", 2) + test(tpe, value, ">", 2) + test(tpe, value, ">=", 2) + test(tpe, value, "+", 2) + test(tpe, value, "-", 2) + test(tpe, value, "*", 2) + test(tpe, value, "/", 2) + test(tpe, value, "%", 2) + } + + def testIntegral[T: ClassTag](tpe: Type, value: T) { + testNumeric(tpe, value) + test(tpe, value, "unary_~") + test(tpe, value, "unary_+") + test(tpe, value, "unary_-") + test(tpe, value, "<<", 2) + test(tpe, value, ">>", 2) + test(tpe, value, ">>>", 2) + test(tpe, value, "|", 2) + test(tpe, value, "&", 2) + test(tpe, value, "^", 2) + } + + def testBoolean() { + header(typeOf[Boolean]) + test(typeOf[Boolean], true, "unary_!") + test(typeOf[Boolean], true, "==", true) + test(typeOf[Boolean], true, "!=", true) + test(typeOf[Boolean], true, "||", true) + test(typeOf[Boolean], true, "&&", true) + test(typeOf[Boolean], true, "|", true) + test(typeOf[Boolean], true, "&", true) + test(typeOf[Boolean], true, "^", true) + } + + def testUnit() { + header(typeOf[Unit]) + } + + testNumeric(typeOf[Byte], 2.toByte) + testNumeric(typeOf[Short], 2.toShort) + testNumeric(typeOf[Char], 2.toChar) + testNumeric(typeOf[Int], 2.toInt) + testNumeric(typeOf[Long], 2.toLong) + testNumeric(typeOf[Float], 2.toFloat) + testNumeric(typeOf[Double], 2.toDouble) + testBoolean() + testUnit() +}
\ No newline at end of file |