diff options
author | Eugene Burmako <xeno.by@gmail.com> | 2012-08-06 21:53:42 +0200 |
---|---|---|
committer | Eugene Burmako <xeno.by@gmail.com> | 2012-08-06 23:18:49 +0200 |
commit | cac52ac3e3bd34dfc6540968c30d3e861799f9e4 (patch) | |
tree | 241dc7cc3cdaebd1c70fda523e336d76e5794679 | |
parent | 7bcb9da47362ba862a695f7c82c0095a8205e3e2 (diff) | |
download | scala-cac52ac3e3bd34dfc6540968c30d3e861799f9e4.tar.gz scala-cac52ac3e3bd34dfc6540968c30d3e861799f9e4.tar.bz2 scala-cac52ac3e3bd34dfc6540968c30d3e861799f9e4.zip |
SI-6199 unit-returning methods now return unit
Since Scala reflection relies on Java reflection to perform member invocations,
it inherits some of the quirks of the underlying platform.
One of such quirks is returning null when invoking a void-returning method.
This is now fixed by introducing a check after calling invoke.
-rw-r--r-- | src/compiler/scala/tools/reflect/ToolBoxFactory.scala | 3 | ||||
-rw-r--r-- | src/reflect/scala/reflect/runtime/JavaMirrors.scala | 12 | ||||
-rw-r--r-- | test/files/run/reflection-magicsymbols-invoke.check | 2 | ||||
-rw-r--r-- | test/files/run/t6199-mirror.check | 1 | ||||
-rw-r--r-- | test/files/run/t6199-mirror.scala | 7 | ||||
-rw-r--r-- | test/files/run/t6199-toolbox.check | 1 | ||||
-rw-r--r-- | test/files/run/t6199-toolbox.scala | 8 |
7 files changed, 29 insertions, 5 deletions
diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala index 9987931cf3..eeec973299 100644 --- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala +++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala @@ -256,7 +256,8 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => // } val (singleton, jmeth) = compileExpr(expr) val result = jmeth.invoke(singleton, thunks map (_.asInstanceOf[AnyRef]): _*) - result + if (jmeth.getReturnType == java.lang.Void.TYPE) () + else result } def parseExpr(code: String): Tree = { diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala index d671225c37..e48c933584 100644 --- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala +++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala @@ -280,19 +280,25 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym jmeth } + def jinvoke(jmeth: jMethod, receiver: Any, args: Seq[Any]): Any = { + val result = jmeth.invoke(receiver, args.asInstanceOf[Seq[AnyRef]]: _*) + if (jmeth.getReturnType == java.lang.Void.TYPE) () + else result + } + override def toString = s"method mirror for ${showMethodSig(symbol)} (bound to $receiver)" } private class JavaVanillaMethodMirror(val receiver: Any, symbol: MethodSymbol) extends JavaMethodMirror(symbol) { - def apply(args: Any*): Any = jmeth.invoke(receiver, args.asInstanceOf[Seq[AnyRef]]: _*) + def apply(args: Any*): Any = jinvoke(jmeth, receiver, args) } private class JavaByNameMethodMirror(val receiver: Any, symbol: MethodSymbol) extends JavaMethodMirror(symbol) { def apply(args: Any*): Any = { val transformed = map2(args.toList, symbol.params.flatten)((arg, param) => if (isByNameParamType(param.info)) () => arg else arg) - jmeth.invoke(receiver, transformed.asInstanceOf[Seq[AnyRef]]: _*) + jinvoke(jmeth, receiver, transformed) } } @@ -321,7 +327,7 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym def invokeMagicPrimitiveMethod = { val jmeths = classOf[BoxesRunTime].getDeclaredMethods.filter(_.getName == nme.primitiveMethodName(symbol.name).toString) assert(jmeths.length == 1, jmeths.toList) - jmeths.head.invoke(null, (objReceiver +: objArgs): _*) + jinvoke(jmeths.head, null, objReceiver +: objArgs) } symbol match { diff --git a/test/files/run/reflection-magicsymbols-invoke.check b/test/files/run/reflection-magicsymbols-invoke.check index a180ed806e..674716adfe 100644 --- a/test/files/run/reflection-magicsymbols-invoke.check +++ b/test/files/run/reflection-magicsymbols-invoke.check @@ -68,7 +68,7 @@ testing Object.==: true testing Object.clone: class java.lang.CloneNotSupportedException: java.lang.String
testing Object.eq: true
testing Object.equals: true
-testing Object.finalize: null
+testing Object.finalize: ()
testing Object.getClass: class java.lang.String
testing Object.hashCode: 50
testing Object.ne: false
diff --git a/test/files/run/t6199-mirror.check b/test/files/run/t6199-mirror.check new file mode 100644 index 0000000000..ec969b5b93 --- /dev/null +++ b/test/files/run/t6199-mirror.check @@ -0,0 +1 @@ +()
diff --git a/test/files/run/t6199-mirror.scala b/test/files/run/t6199-mirror.scala new file mode 100644 index 0000000000..772a384542 --- /dev/null +++ b/test/files/run/t6199-mirror.scala @@ -0,0 +1,7 @@ +import scala.reflect.runtime.universe._ +import scala.reflect.runtime.{currentMirror => cm} + +object Test extends App { + class C { def foo = () } + println(cm.reflect(new C).reflectMethod(typeOf[C].member(newTermName("foo")).asMethod)()) +}
\ No newline at end of file diff --git a/test/files/run/t6199-toolbox.check b/test/files/run/t6199-toolbox.check new file mode 100644 index 0000000000..ec969b5b93 --- /dev/null +++ b/test/files/run/t6199-toolbox.check @@ -0,0 +1 @@ +()
diff --git a/test/files/run/t6199-toolbox.scala b/test/files/run/t6199-toolbox.scala new file mode 100644 index 0000000000..14670f8e21 --- /dev/null +++ b/test/files/run/t6199-toolbox.scala @@ -0,0 +1,8 @@ +import scala.reflect.runtime.universe._ +import scala.reflect.runtime.{currentMirror => cm} +import scala.tools.reflect.ToolBox + +object Test extends App { + val tb = cm.mkToolBox() + println(tb.runExpr(Literal(Constant(())))) +}
\ No newline at end of file |