From bab827a5426aeb654006573712eb7aabc047db36 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Wed, 11 Jul 2012 14:46:01 +0200 Subject: SI-5895 fixes FieldMirrors reflectField now accepts getters and setters along with the field symbols, it also checks whether a field has a reasonable binary representation (this is necessary, because ctor parameters that are unused outside of their declaring constructors don't get compiled down to Java fields/methods). --- .../scala/reflect/runtime/JavaMirrors.scala | 25 ++++++++++++------- .../reflection-fieldmirror-accessorsareokay.check | 6 +++++ .../reflection-fieldmirror-accessorsareokay.scala | 29 ++++++++++++++++++++++ .../run/reflection-fieldmirror-ctorparam.check | 4 ++- .../run/reflection-fieldmirror-sanitycheck.check | 6 ----- .../run/reflection-fieldmirror-sanitycheck.scala | 22 ---------------- 6 files changed, 54 insertions(+), 38 deletions(-) create mode 100644 test/files/run/reflection-fieldmirror-accessorsareokay.check create mode 100644 test/files/run/reflection-fieldmirror-accessorsareokay.scala delete mode 100644 test/files/run/reflection-fieldmirror-sanitycheck.check delete mode 100644 test/files/run/reflection-fieldmirror-sanitycheck.scala diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala index 185621efa4..1c5ea9caba 100644 --- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala +++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala @@ -133,15 +133,22 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym def symbol = wholemirror.classSymbol(obj.getClass) def reflectField(field: TermSymbol): FieldMirror = { // [Eugene+++] check whether `field` represents a member of a `symbol` - 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) + if ((field.isMethod && !field.isAccessor) || field.isModule) throw new Error(s"expected a field or accessor method symbol, you provided a ${field.kind} symbol") + val name = + if (field.isGetter) nme.getterToLocal(field.name) + else if (field.isSetter) nme.getterToLocal(nme.setterToGetter(field.name)) + else field.name + val field1 = (field.owner.info decl name).asTermSymbol + try fieldToJava(field1) + catch { + case _: NoSuchFieldException => + throw new Error(s""" + |this Scala field isn't represented as a Java field, neither it has a Java accessor method + |note that private parameters of class constructors don't get mapped onto fields and/or accessors, + |unless they are used outside of their declaring constructors. + """.trim.stripMargin) + } + new JavaFieldMirror(obj, field1) } def reflectMethod(method: MethodSymbol): MethodMirror = { // [Eugene+++] check whether `method` represents a member of a `symbol` diff --git a/test/files/run/reflection-fieldmirror-accessorsareokay.check b/test/files/run/reflection-fieldmirror-accessorsareokay.check new file mode 100644 index 0000000000..635dcd04ce --- /dev/null +++ b/test/files/run/reflection-fieldmirror-accessorsareokay.check @@ -0,0 +1,6 @@ +true +42 +2 +true +2 +2 diff --git a/test/files/run/reflection-fieldmirror-accessorsareokay.scala b/test/files/run/reflection-fieldmirror-accessorsareokay.scala new file mode 100644 index 0000000000..c586ce9bdd --- /dev/null +++ b/test/files/run/reflection-fieldmirror-accessorsareokay.scala @@ -0,0 +1,29 @@ +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.symbol + + def test(f: Symbol) = { + try { + val fm: FieldMirror = im.reflectField(f.asTermSymbol) + println(fm.symbol.isVariable) + println(fm.get) + fm.set(2) + println(fm.get) + } catch { + case ex: Throwable => + println(ex.getMessage) + } + } + + test(cs.typeSignature.declaration(newTermName("x")).asTermSymbol) + test(cs.typeSignature.declaration(newTermName("x_$eq")).asTermSymbol) +} diff --git a/test/files/run/reflection-fieldmirror-ctorparam.check b/test/files/run/reflection-fieldmirror-ctorparam.check index 8b99a6f772..7ae2cec81e 100644 --- a/test/files/run/reflection-fieldmirror-ctorparam.check +++ b/test/files/run/reflection-fieldmirror-ctorparam.check @@ -1 +1,3 @@ -class java.lang.NoSuchFieldException: Test$A$$x +class java.lang.Error: this Scala field isn't represented as a Java field, neither it has a Java accessor method +note that private parameters of class constructors don't get mapped onto fields and/or accessors, +unless they are used outside of their declaring constructors. diff --git a/test/files/run/reflection-fieldmirror-sanitycheck.check b/test/files/run/reflection-fieldmirror-sanitycheck.check deleted file mode 100644 index e5134de4e3..0000000000 --- a/test/files/run/reflection-fieldmirror-sanitycheck.check +++ /dev/null @@ -1,6 +0,0 @@ -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 deleted file mode 100644 index 6a992dd282..0000000000 --- a/test/files/run/reflection-fieldmirror-sanitycheck.scala +++ /dev/null @@ -1,22 +0,0 @@ -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.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) - } -} -- cgit v1.2.3