summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2012-06-07 22:40:41 +0200
committerEugene Burmako <xeno.by@gmail.com>2012-06-08 15:34:40 +0200
commit0c153ee15e714e0ca8752151012b8f1fa9642983 (patch)
tree73fbeaee63acc64f08eeaec05da586ded9fa692f
parent178069e13d841c029bd3cf78773788ad3743e218 (diff)
downloadscala-0c153ee15e714e0ca8752151012b8f1fa9642983.tar.gz
scala-0c153ee15e714e0ca8752151012b8f1fa9642983.tar.bz2
scala-0c153ee15e714e0ca8752151012b8f1fa9642983.zip
fixes some issues with reflectField brought up today
-rw-r--r--src/reflect/scala/reflect/runtime/JavaMirrors.scala41
-rw-r--r--test/files/run/reflection-fieldmirror-ctorparam.check1
-rw-r--r--test/files/run/reflection-fieldmirror-ctorparam.scala21
-rw-r--r--test/files/run/reflection-fieldmirror-getsetval.check2
-rw-r--r--test/files/run/reflection-fieldmirror-getsetval.scala24
-rw-r--r--test/files/run/reflection-fieldmirror-getsetvar.check2
-rw-r--r--test/files/run/reflection-fieldmirror-getsetvar.scala18
-rw-r--r--test/files/run/reflection-fieldmirror-nmelocalsuffixstring.check1
-rw-r--r--test/files/run/reflection-fieldmirror-nmelocalsuffixstring.scala16
-rw-r--r--test/files/run/reflection-fieldmirror-privatethis.check3
-rw-r--r--test/files/run/reflection-fieldmirror-privatethis.scala19
-rw-r--r--test/files/run/reflection-fieldmirror-sanitycheck.check6
-rw-r--r--test/files/run/reflection-fieldmirror-sanitycheck.scala22
13 files changed, 169 insertions, 7 deletions
diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
index a8120d220a..ed03ac30f9 100644
--- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala
+++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
@@ -128,20 +128,41 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym
extends InstanceMirror {
def instance = obj
def reflectClass = wholemirror.reflectClass(obj.getClass)
- def reflectField(field: TermSymbol): FieldMirror = new JavaFieldMirror(obj, field)
+ def reflectField(field: TermSymbol): FieldMirror = {
+ if (field.isMethod || field.isModule) throw new Error(s"""
+ |expected a field symbol, you provided a ${field.kind} symbol
+ |A typical cause of this problem is using a field accessor symbol instead of a field symbol.
+ |To obtain a field symbol append nme.LOCAL_SUFFIX_STRING to the name of the field,
+ |when searching for a member with Type.members or Type.declarations.
+ |This is a temporary inconvenience that will be resolved before 2.10.0-final.
+ |More information can be found here: https://issues.scala-lang.org/browse/SI-5895.
+ """.trim.stripMargin)
+ new JavaFieldMirror(obj, field)
+ }
def reflectMethod(method: MethodSymbol): MethodMirror = new JavaMethodMirror(obj, method)
}
private class JavaFieldMirror(val receiver: AnyRef, val field: TermSymbol)
extends FieldMirror {
- lazy val jfield = fieldToJava(field)
+ lazy val jfield = {
+ val jfield = fieldToJava(field)
+ if (!jfield.isAccessible) jfield.setAccessible(true)
+ jfield
+ }
def get = jfield.get(receiver)
- def set(value: Any) = jfield.set(receiver, value)
+ def set(value: Any) = {
+ if (!field.isMutable) throw new Error("cannot set an immutable field")
+ jfield.set(receiver, value)
+ }
}
private class JavaMethodMirror(val receiver: AnyRef, val method: MethodSymbol)
extends MethodMirror {
- lazy val jmeth = methodToJava(method)
+ lazy val jmeth = {
+ val jmeth = methodToJava(method)
+ if (!jmeth.isAccessible) jmeth.setAccessible(true)
+ jmeth
+ }
def apply(args: Any*): Any =
if (method.owner == ArrayClass)
method.name match {
@@ -157,7 +178,11 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym
private class JavaConstructorMirror(val method: MethodSymbol)
extends MethodMirror {
override val receiver = null
- lazy val jconstr = constructorToJava(method)
+ lazy val jconstr = {
+ val jconstr = constructorToJava(method)
+ if (!jconstr.isAccessible) jconstr.setAccessible(true)
+ jconstr
+ }
def apply(args: Any*): Any = jconstr.newInstance(args.asInstanceOf[Seq[AnyRef]]: _*)
}
@@ -877,7 +902,8 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym
*/
def fieldToJava(fld: TermSymbol): jField = fieldCache.toJava(fld) {
val jclazz = classToJava(fld.owner.asClassSymbol)
- try jclazz getDeclaredField fld.name.toString
+ val jname = nme.dropLocalSuffix(fld.name).toString
+ try jclazz getDeclaredField jname
catch {
case ex: NoSuchFieldException => jclazz getDeclaredField expandedName(fld)
}
@@ -889,7 +915,8 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym
def methodToJava(meth: MethodSymbol): jMethod = methodCache.toJava(meth) {
val jclazz = classToJava(meth.owner.asClassSymbol)
val paramClasses = transformedType(meth).paramTypes map typeToJavaClass
- try jclazz getDeclaredMethod (meth.name.toString, paramClasses: _*)
+ val jname = nme.dropLocalSuffix(meth.name).toString
+ try jclazz getDeclaredMethod (jname, paramClasses: _*)
catch {
case ex: NoSuchMethodException =>
jclazz getDeclaredMethod (expandedName(meth), paramClasses: _*)
diff --git a/test/files/run/reflection-fieldmirror-ctorparam.check b/test/files/run/reflection-fieldmirror-ctorparam.check
new file mode 100644
index 0000000000..8b99a6f772
--- /dev/null
+++ b/test/files/run/reflection-fieldmirror-ctorparam.check
@@ -0,0 +1 @@
+class java.lang.NoSuchFieldException: Test$A$$x
diff --git a/test/files/run/reflection-fieldmirror-ctorparam.scala b/test/files/run/reflection-fieldmirror-ctorparam.scala
new file mode 100644
index 0000000000..286399072e
--- /dev/null
+++ b/test/files/run/reflection-fieldmirror-ctorparam.scala
@@ -0,0 +1,21 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+
+object Test extends App {
+ class A(x: Int) {
+ private[this] var xx = x
+ }
+
+ val a = new A(42)
+
+ val im: InstanceMirror = cm.reflect(a)
+ val cs = im.reflectClass.symbol
+ val f = cs.typeSignature.declaration(newTermName("x")).asTermSymbol
+ try {
+ val fm: FieldMirror = im.reflectField(f)
+ println(fm.get)
+ } catch {
+ case ex: Throwable =>
+ println(s"${ex.getClass}: ${ex.getMessage}")
+ }
+}
diff --git a/test/files/run/reflection-fieldmirror-getsetval.check b/test/files/run/reflection-fieldmirror-getsetval.check
new file mode 100644
index 0000000000..707bbcccce
--- /dev/null
+++ b/test/files/run/reflection-fieldmirror-getsetval.check
@@ -0,0 +1,2 @@
+42
+cannot set an immutable field
diff --git a/test/files/run/reflection-fieldmirror-getsetval.scala b/test/files/run/reflection-fieldmirror-getsetval.scala
new file mode 100644
index 0000000000..aeae66b422
--- /dev/null
+++ b/test/files/run/reflection-fieldmirror-getsetval.scala
@@ -0,0 +1,24 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+
+object Test extends App {
+ class A {
+ val x: Int = 42
+ }
+
+ val a = new A
+
+ val im: InstanceMirror = cm.reflect(a)
+ val cs = im.reflectClass.symbol
+ val f = cs.typeSignature.declaration(newTermName("x" + nme.LOCAL_SUFFIX_STRING)).asTermSymbol
+ val fm: FieldMirror = im.reflectField(f)
+ try {
+ println(fm.get)
+ fm.set(2)
+ println(fm.get)
+ println("this indicates a failure")
+ } catch {
+ case ex: Throwable =>
+ println(ex.getMessage)
+ }
+}
diff --git a/test/files/run/reflection-fieldmirror-getsetvar.check b/test/files/run/reflection-fieldmirror-getsetvar.check
new file mode 100644
index 0000000000..a9b0ccc6a0
--- /dev/null
+++ b/test/files/run/reflection-fieldmirror-getsetvar.check
@@ -0,0 +1,2 @@
+42
+2
diff --git a/test/files/run/reflection-fieldmirror-getsetvar.scala b/test/files/run/reflection-fieldmirror-getsetvar.scala
new file mode 100644
index 0000000000..99ecc8996c
--- /dev/null
+++ b/test/files/run/reflection-fieldmirror-getsetvar.scala
@@ -0,0 +1,18 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+
+object Test extends App {
+ class A {
+ var x: Int = 42
+ }
+
+ val a = new A
+
+ val im: InstanceMirror = cm.reflect(a)
+ val cs = im.reflectClass.symbol
+ val f = cs.typeSignature.declaration(newTermName("x" + nme.LOCAL_SUFFIX_STRING)).asTermSymbol
+ val fm: FieldMirror = im.reflectField(f)
+ println(fm.get)
+ fm.set(2)
+ println(fm.get)
+}
diff --git a/test/files/run/reflection-fieldmirror-nmelocalsuffixstring.check b/test/files/run/reflection-fieldmirror-nmelocalsuffixstring.check
new file mode 100644
index 0000000000..fe75c80bca
--- /dev/null
+++ b/test/files/run/reflection-fieldmirror-nmelocalsuffixstring.check
@@ -0,0 +1 @@
+true
diff --git a/test/files/run/reflection-fieldmirror-nmelocalsuffixstring.scala b/test/files/run/reflection-fieldmirror-nmelocalsuffixstring.scala
new file mode 100644
index 0000000000..9dca7b452c
--- /dev/null
+++ b/test/files/run/reflection-fieldmirror-nmelocalsuffixstring.scala
@@ -0,0 +1,16 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+
+object Test extends App {
+ class A {
+ var x: Int = 42
+ }
+
+ val a = new A
+
+ val im: InstanceMirror = cm.reflect(a)
+ val cs = im.reflectClass.symbol
+ val f = cs.typeSignature.declaration(newTermName("x" + nme.LOCAL_SUFFIX_STRING)).asTermSymbol
+ val fm: FieldMirror = im.reflectField(f)
+ println(fm.field.isVariable)
+}
diff --git a/test/files/run/reflection-fieldmirror-privatethis.check b/test/files/run/reflection-fieldmirror-privatethis.check
new file mode 100644
index 0000000000..889b7c2c34
--- /dev/null
+++ b/test/files/run/reflection-fieldmirror-privatethis.check
@@ -0,0 +1,3 @@
+true
+42
+2
diff --git a/test/files/run/reflection-fieldmirror-privatethis.scala b/test/files/run/reflection-fieldmirror-privatethis.scala
new file mode 100644
index 0000000000..844822d449
--- /dev/null
+++ b/test/files/run/reflection-fieldmirror-privatethis.scala
@@ -0,0 +1,19 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+
+object Test extends App {
+ class A {
+ private[this] var x: Int = 42
+ }
+
+ val a = new A
+
+ val im: InstanceMirror = cm.reflect(a)
+ val cs = im.reflectClass.symbol
+ val f = cs.typeSignature.declaration(newTermName("x")).asTermSymbol
+ val fm: FieldMirror = im.reflectField(f)
+ println(fm.field.isVariable)
+ println(fm.get)
+ fm.set(2)
+ println(fm.get)
+}
diff --git a/test/files/run/reflection-fieldmirror-sanitycheck.check b/test/files/run/reflection-fieldmirror-sanitycheck.check
new file mode 100644
index 0000000000..e5134de4e3
--- /dev/null
+++ b/test/files/run/reflection-fieldmirror-sanitycheck.check
@@ -0,0 +1,6 @@
+expected a field symbol, you provided a method symbol
+A typical cause of this problem is using a field accessor symbol instead of a field symbol.
+To obtain a field symbol append nme.LOCAL_SUFFIX_STRING to the name of the field,
+when searching for a member with Type.members or Type.declarations.
+This is a temporary inconvenience that will be resolved before 2.10.0-final.
+More information can be found here: https://issues.scala-lang.org/browse/SI-5895.
diff --git a/test/files/run/reflection-fieldmirror-sanitycheck.scala b/test/files/run/reflection-fieldmirror-sanitycheck.scala
new file mode 100644
index 0000000000..abd4cf57c5
--- /dev/null
+++ b/test/files/run/reflection-fieldmirror-sanitycheck.scala
@@ -0,0 +1,22 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+
+object Test extends App {
+ class A {
+ var x: Int = 42
+ }
+
+ val a = new A
+
+ val im: InstanceMirror = cm.reflect(a)
+ val cs = im.reflectClass.symbol
+ //val f = cs.typeSignature.declaration(newTermName("x" + nme.LOCAL_SUFFIX_STRING)).asTermSymbol
+ val f = cs.typeSignature.declaration(newTermName("x")).asTermSymbol
+ try {
+ val fm: FieldMirror = im.reflectField(f)
+ println("this indicates a failure")
+ } catch {
+ case ex: Throwable =>
+ println(ex.getMessage)
+ }
+}