summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/library/scala/reflect/package.scala3
-rw-r--r--src/reflect/scala/reflect/api/Mirrors.scala144
-rw-r--r--src/reflect/scala/reflect/runtime/JavaMirrors.scala56
-rw-r--r--test/files/run/reflection-constructormirror-inner-badpath.check2
-rw-r--r--test/files/run/reflection-constructormirror-nested-badpath.check2
-rw-r--r--test/files/run/reflection-constructormirror-toplevel-badpath.check2
-rw-r--r--test/files/run/reflection-fieldmirror-accessorsareokay.check6
-rw-r--r--test/files/run/reflection-fieldmirror-accessorsareokay.scala29
-rw-r--r--test/files/run/reflection-fieldmirror-ctorparam.check4
-rw-r--r--test/files/run/reflection-fieldmirror-getsetval.check2
-rw-r--r--test/files/run/reflection-fieldmirror-sanitycheck.check6
-rw-r--r--test/files/run/reflection-fieldmirror-sanitycheck.scala22
-rw-r--r--test/files/run/reflection-modulemirror-inner-badpath.check4
-rw-r--r--test/files/run/reflection-modulemirror-nested-badpath.check4
-rw-r--r--test/files/run/reflection-modulemirror-toplevel-badpath.check4
-rw-r--r--test/files/run/reflection-sanitychecks.check8
-rw-r--r--test/files/run/reflection-sanitychecks.scala30
17 files changed, 236 insertions, 92 deletions
diff --git a/src/library/scala/reflect/package.scala b/src/library/scala/reflect/package.scala
index 9f9d4089c4..d97f2ec633 100644
--- a/src/library/scala/reflect/package.scala
+++ b/src/library/scala/reflect/package.scala
@@ -65,3 +65,6 @@ package object reflect {
@deprecated("Use `@scala.beans.ScalaBeanInfo` instead", "2.10.0")
type ScalaBeanInfo = scala.beans.ScalaBeanInfo
}
+
+/** An exception that indicates an error during Scala reflection */
+case class ScalaReflectionException(msg: String) extends Exception(msg)
diff --git a/src/reflect/scala/reflect/api/Mirrors.scala b/src/reflect/scala/reflect/api/Mirrors.scala
index 348ab3656b..27176a2a2d 100644
--- a/src/reflect/scala/reflect/api/Mirrors.scala
+++ b/src/reflect/scala/reflect/api/Mirrors.scala
@@ -27,28 +27,63 @@ trait Mirrors { self: Universe =>
/** The instance value reflected by this mirror */
def instance: Any
- /** The symbol corresponding to the run-time class of the reflected instance. */
+ /** The symbol corresponding to the run-time class of the reflected instance */
def symbol: ClassSymbol
- /** Get value of field in reflected instance.
- * @field A field symbol that should represent a field of the instance class.
- * @return The value associated with that field in the reflected instance
- * @throws ???
+ /** Reflects against a field symbol and returns a mirror
+ * that can be used to get and, if appropriate, set the value of the field.
+ *
+ * To get a field symbol by the name of the field you would like to reflect,
+ * use `<this mirror>.symbol.typeSignature.member(newTermName(<name of the field>)).asTermSymbol`.
+ * For further information about member lookup refer to `Symbol.typeSignature`.
+ *
+ * The input symbol can be either private or non-private (Scala reflection transparently deals with visibility).
+ * It must be a member (declared or inherited) of the class of the instance underlying this mirror.
+ *
+ * The input symbol can represent either a field itself or one of the corresponding accessors
+ * (in all cases the resulting mirror will refer to the field symbol).
+ *
+ * If a field symbol doesn't correspond to a reflectable entity of the underlying platform,
+ * a `ScalaReflectionException` exception will be thrown. This might happen, for example, for primary constructor parameters.
+ * Typically they produce class fields, however, private parameters that aren't used outside the constructor
+ * remain plain parameters of a constructor method of the class.
*/
def reflectField(field: TermSymbol): FieldMirror
- /** Invokes a method on the reflected instance.
- * @param meth A method symbol that should represent a method of the instance class
- * @param args The arguments to pass to the method
- * @return The result of invoking `meth(args)` on the reflected instance.
- * @throws ???
+ /** Reflects against a method symbol and returns a mirror
+ * that can be used to invoke the method provided.
+ *
+ * To get a method symbol by the name of the method you would like to reflect,
+ * use `<this mirror>.symbol.typeSignature.member(newTermName(<name of the method>)).asMethodSymbol`.
+ * For further information about member lookup refer to `Symbol.typeSignature`.
+ *
+ * The input symbol can be either private or non-private (Scala reflection transparently deals with visibility).
+ * It must be a member (declared or inherited) of the instance underlying this mirror.
*/
def reflectMethod(method: MethodSymbol): MethodMirror
- /** .. */
+ /** Reflects against an inner class symbol and returns a mirror
+ * that can be used to create instances of the class, inspect its companion object or perform further reflections.
+ *
+ * To get a class symbol by the name of the class you would like to reflect,
+ * use `<this mirror>.symbol.typeSignature.member(newTypeName(<name of the class>)).asClassSymbol`.
+ * For further information about member lookup refer to `Symbol.typeSignature`.
+ *
+ * The input symbol can be either private or non-private (Scala reflection transparently deals with visibility).
+ * It must be a member (declared or inherited) of the instance underlying this mirror.
+ */
def reflectClass(cls: ClassSymbol): ClassMirror
- /** .. */
+ /** Reflects against an inner module symbol and returns a mirror
+ * that can be used to get the instance of the object or inspect its companion class.
+ *
+ * To get a module symbol by the name of the object you would like to reflect,
+ * use `<this mirror>.symbol.typeSignature.member(newTermName(<name of the object>)).asModuleSymbol`.
+ * For further information about member lookup refer to `Symbol.typeSignature`.
+ *
+ * The input symbol can be either private or non-private (Scala reflection transparently deals with visibility).
+ * It must be a member (declared or inherited) of the instance underlying this mirror.
+ */
def reflectModule(mod: ModuleSymbol): ModuleMirror
}
@@ -58,13 +93,31 @@ trait Mirrors { self: Universe =>
/** The object containing the field */
def receiver: AnyRef
- /** The field symbol representing the field */
+ /** The field symbol representing the field.
+ *
+ * In Scala `val` and `var` declarations are usually compiled down to a pair of
+ * a backing field and corresponding accessor/accessors, which means that a single
+ * declaration might correspond to up to three different symbols. Nevertheless
+ * the `FieldMirror.symbol` field always points to a backing field symbol.
+ */
def symbol: TermSymbol
- /** Retrieves the value stored in the field */
+ /** Retrieves the value stored in the field.
+ *
+ * Scala reflection uses reflection capabilities of the underlying platform,
+ * so `FieldMirror.get` might throw platform-specific exceptions associated
+ * with getting a field or invoking a getter method of the field.
+ */
def get: Any
- /** Updates the value stored in the field */
+ /** Updates the value stored in the field.
+ *
+ * If a field is immutable, a `ScalaReflectionException` will be thrown.
+ *
+ * Scala reflection uses reflection capabilities of the underlying platform,
+ * so `FieldMirror.get` might throw platform-specific exceptions associated
+ * with setting a field or invoking a setter method of the field.
+ */
def set(value: Any): Unit
}
@@ -77,8 +130,12 @@ trait Mirrors { self: Universe =>
/** The method symbol representing the method */
def symbol: MethodSymbol
- /** The result of applying the method to the given arguments */
- // [Eugene+++] If it's a constructor, it should account for inner classes
+ /** The result of applying the method to the given arguments
+ *
+ * Scala reflection uses reflection capabilities of the underlying platform,
+ * so `FieldMirror.get` might throw platform-specific exceptions associated
+ * with invoking the corresponding method or constructor.
+ */
def apply(args: Any*): Any
}
@@ -97,7 +154,7 @@ trait Mirrors { self: Universe =>
*/
def isStatic: Boolean
- /** The Scala symbol corresponding to the reflected runtime class or module. */
+ /** The Scala symbol corresponding to the reflected runtime class or object */
def symbol: Symbol
/** Optionally, the mirror of the companion reflected by this mirror.
@@ -116,7 +173,7 @@ trait Mirrors { self: Universe =>
/** A mirror that reflects a Scala object definition or the static parts of a runtime class */
trait ModuleMirror extends TemplateMirror {
- /** The Scala module symbol corresponding to the reflected module. */
+ /** The Scala module symbol corresponding to the reflected object */
override def symbol: ModuleSymbol
/** If the reflected runtime class corresponds to a Scala object definition,
@@ -137,15 +194,18 @@ trait Mirrors { self: Universe =>
/** A mirror that reflects the instance parts of a runtime class */
trait ClassMirror extends TemplateMirror {
- /** The Scala class symbol corresponding to the reflected class. */
+ /** The Scala class symbol corresponding to the reflected class */
override def symbol: ClassSymbol
- /** Returns a fresh instance of by invoking that constructor.
- * @throws InstantiationException if the class does not have a public
- * constructor with an empty parameter list.
- * @throws IllegalAccessException if the class or its constructor is not accessible.
- * @throws ExceptionInInitializerError if the initialization of the constructor fails.
- * @throws SecurityException if creating a new instance is not permitted.
+ /** Reflects against a constructor symbol and returns a mirror
+ * that can be used to invoke it and construct instances of this mirror's symbols.
+ *
+ * To get a constructor symbol you would like to reflect,
+ * use `<this mirror>.symbol.typeSignature.member(nme.CONSTRUCTOR).asMethodSymbol`.
+ * For further information about member lookup refer to `Symbol.typeSignature`.
+ *
+ * The input symbol can be either private or non-private (Scala reflection transparently deals with visibility).
+ * It must be a member (declared or inherited) of the class underlying this mirror.
*/
def reflectConstructor(constructor: MethodSymbol): MethodMirror
@@ -161,24 +221,40 @@ trait Mirrors { self: Universe =>
/** A mirror that reflects instances and static classes */
trait ReflectiveMirror extends MirrorOf[Mirrors.this.type] {
- /** A reflective mirror for the given object
- * @param obj An arbitrary value
- * @return The mirror for `obj`.
+ /** A reflective mirror for the given object.
+ *
+ * Such a mirror can be used to further reflect against the members of the object
+ * to get/set fields, invoke methods and inspect inner classes and objects.
*/
def reflect(obj: Any): InstanceMirror
- /** .. */
+ /** Reflects against a static class symbol and returns a mirror
+ * that can be used to create instances of the class, inspect its companion object or perform further reflections.
+ *
+ * To get a class symbol by the name of the class you would like to reflect,
+ * use `<this mirror>.classSymbol(<runtime class loaded by its name>)`.
+ *
+ * The input symbol can be either private or non-private (Scala reflection transparently deals with visibility).
+ * It must be static, i.e. either top-level or nested within one or several static objects.
+ */
def reflectClass(cls: ClassSymbol): ClassMirror
- /** .. */
+ /** Reflects against a static module symbol and returns a mirror
+ * that can be used to get the instance of the object or inspect its companion class.
+ *
+ * To get a module symbol by the name of its companion class you would like to reflect,
+ * use `<this mirror>.classSymbol(<runtime class loaded by its name>).companion.get`.
+ *
+ * The input symbol can be either private or non-private (Scala reflection transparently deals with visibility).
+ * It must be static, i.e. either top-level or nested within one or several static objects.
+ */
def reflectModule(mod: ModuleSymbol): ModuleMirror
}
/** The API of a mirror for a reflective universe */
trait RuntimeMirror extends ReflectiveMirror { self =>
- /** Maps a Scala type to the corresponding Java class object
- */
+ /** Maps a Scala type to the corresponding Java class object */
def runtimeClass(tpe: Type): RuntimeClass
/** Maps a Scala class symbol to the corresponding Java class object
@@ -198,7 +274,7 @@ trait Mirrors { self: Universe =>
def classSymbol(rtcls: RuntimeClass): ClassSymbol
/** A module symbol for the specified runtime class.
- * @return The module symbol for the runtime class in the current class loader.
+ * @return The module symbol for the runtime class in the current class loader.
* @throws java.lang.ClassNotFoundException if no class with that name exists
* @throws scala.reflect.internal.MissingRequirementError if no corresponding symbol exists
* to do: throws anything else?
diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
index 75d43a7553..9f9f79058d 100644
--- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala
+++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
@@ -107,15 +107,28 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym
// ----------- Implementations of mirror operations and classes -------------------
+ private def ErrorInnerClass(wannabe: Symbol) = throw new ScalaReflectionException(s"$wannabe is an inner class, use reflectClass on an InstanceMirror to obtain its ClassMirror")
+ private def ErrorInnerModule(wannabe: Symbol) = throw new ScalaReflectionException(s"$wannabe is an inner module, use reflectModule on an InstanceMirror to obtain its ModuleMirror")
+ private def ErrorStaticClass(wannabe: Symbol) = throw new ScalaReflectionException(s"$wannabe is a static class, use reflectClass on a RuntimeMirror to obtain its ClassMirror")
+ private def ErrorStaticModule(wannabe: Symbol) = throw new ScalaReflectionException(s"$wannabe is a static module, use reflectModule on a RuntimeMirror to obtain its ModuleMirror")
+ private def ErrorNotMember(wannabe: Symbol, owner: Symbol) = throw new ScalaReflectionException(s"expected a member of $owner, you provided ${wannabe.kind} ${wannabe.fullName}")
+ private def ErrorNotField(wannabe: Symbol) = throw new ScalaReflectionException(s"expected a field or an accessor method symbol, you provided $wannabe}")
+ private def ErrorNonExistentField(wannabe: Symbol) = throw new ScalaReflectionException(s"""
+ |Scala field ${wannabe.name} 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)
+ private def ErrorSetImmutableField(wannabe: Symbol) = throw new ScalaReflectionException(s"cannot set an immutable field ${wannabe.name}")
+
def reflect(obj: Any): InstanceMirror = new JavaInstanceMirror(obj.asInstanceOf[AnyRef])
def reflectClass(cls: ClassSymbol): ClassMirror = {
- if (!cls.isStatic) throw new Error("this is an inner class, use reflectClass on an InstanceMirror to obtain its ClassMirror")
+ if (!cls.isStatic) ErrorInnerClass(cls)
new JavaClassMirror(null, cls)
}
def reflectModule(mod: ModuleSymbol): ModuleMirror = {
- if (!mod.isStatic) throw new Error("this is an inner module, use reflectModule on an InstanceMirror to obtain its ModuleMirror")
+ if (!mod.isStatic) ErrorInnerModule(mod)
new JavaModuleMirror(null, mod)
}
@@ -127,34 +140,39 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym
def moduleSymbol(rtcls: RuntimeClass): ModuleSymbol = classToScala(rtcls).companionModule.asModuleSymbol
+ private def checkMemberOf(wannabe: Symbol, owner: Symbol) =
+ if (!owner.info.member(wannabe.name).alternatives.contains(wannabe)) ErrorNotMember(wannabe, owner)
+
private class JavaInstanceMirror(obj: AnyRef)
extends InstanceMirror {
def instance = obj
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)
+ checkMemberOf(field, symbol)
+ if ((field.isMethod && !field.isAccessor) || field.isModule) ErrorNotField(field)
+ 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 => ErrorNonExistentField(field1)
+ }
+ new JavaFieldMirror(obj, field1)
}
def reflectMethod(method: MethodSymbol): MethodMirror = {
- // [Eugene+++] check whether `method` represents a member of a `symbol`
+ checkMemberOf(method, symbol)
new JavaMethodMirror(obj, method)
}
def reflectClass(cls: ClassSymbol): ClassMirror = {
- // [Eugene+++] check whether `cls` represents a member of a `symbol`
- if (cls.isStatic) throw new Error("this is a static class, use reflectClass on a RuntimeMirror to obtain its ClassMirror")
+ if (cls.isStatic) ErrorStaticClass(cls)
+ checkMemberOf(cls, symbol)
new JavaClassMirror(instance, cls)
}
def reflectModule(mod: ModuleSymbol): ModuleMirror = {
- // [Eugene+++] check whether `mod` represents a member of a `symbol`
- if (mod.isStatic) throw new Error("this is a static module, use reflectModule on a RuntimeMirror to obtain its ModuleMirror")
+ if (mod.isStatic) ErrorStaticModule(mod)
+ checkMemberOf(mod, symbol)
new JavaModuleMirror(instance, mod)
}
}
@@ -168,7 +186,7 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym
}
def get = jfield.get(receiver)
def set(value: Any) = {
- if (!symbol.isMutable) throw new Error("cannot set an immutable field")
+ if (!symbol.isMutable) ErrorSetImmutableField(symbol)
jfield.set(receiver, value)
}
}
@@ -186,7 +204,7 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym
case nme.length => jArray.getLength(receiver)
case nme.apply => jArray.get(receiver, args(0).asInstanceOf[Int])
case nme.update => jArray.set(receiver, args(0).asInstanceOf[Int], args(1))
- case _ => throw new Error(s"unexpected array method $symbol")
+ case _ => assert(false, s"unexpected array method: $symbol")
}
else
jmeth.invoke(receiver, args.asInstanceOf[Seq[AnyRef]]: _*)
diff --git a/test/files/run/reflection-constructormirror-inner-badpath.check b/test/files/run/reflection-constructormirror-inner-badpath.check
index 28b936eca1..2fb0610ad6 100644
--- a/test/files/run/reflection-constructormirror-inner-badpath.check
+++ b/test/files/run/reflection-constructormirror-inner-badpath.check
@@ -1,2 +1,2 @@
-this is an inner class, use reflectClass on an InstanceMirror to obtain its ClassMirror
+class R is an inner class, use reflectClass on an InstanceMirror to obtain its ClassMirror
()
diff --git a/test/files/run/reflection-constructormirror-nested-badpath.check b/test/files/run/reflection-constructormirror-nested-badpath.check
index 9ceb603dc2..acd21df9c0 100644
--- a/test/files/run/reflection-constructormirror-nested-badpath.check
+++ b/test/files/run/reflection-constructormirror-nested-badpath.check
@@ -1,2 +1,2 @@
-this is a static class, use reflectClass on a RuntimeMirror to obtain its ClassMirror
+class R is a static class, use reflectClass on a RuntimeMirror to obtain its ClassMirror
()
diff --git a/test/files/run/reflection-constructormirror-toplevel-badpath.check b/test/files/run/reflection-constructormirror-toplevel-badpath.check
index 9ceb603dc2..acd21df9c0 100644
--- a/test/files/run/reflection-constructormirror-toplevel-badpath.check
+++ b/test/files/run/reflection-constructormirror-toplevel-badpath.check
@@ -1,2 +1,2 @@
-this is a static class, use reflectClass on a RuntimeMirror to obtain its ClassMirror
+class R is a static class, use reflectClass on a RuntimeMirror to obtain its ClassMirror
()
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..31f6491b14 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 scala.ScalaReflectionException: Scala field x 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-getsetval.check b/test/files/run/reflection-fieldmirror-getsetval.check
index 707bbcccce..e1927f68d0 100644
--- a/test/files/run/reflection-fieldmirror-getsetval.check
+++ b/test/files/run/reflection-fieldmirror-getsetval.check
@@ -1,2 +1,2 @@
42
-cannot set an immutable field
+cannot set an immutable field x
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)
- }
-}
diff --git a/test/files/run/reflection-modulemirror-inner-badpath.check b/test/files/run/reflection-modulemirror-inner-badpath.check
index d3fe43336e..1e990ec900 100644
--- a/test/files/run/reflection-modulemirror-inner-badpath.check
+++ b/test/files/run/reflection-modulemirror-inner-badpath.check
@@ -1,2 +1,2 @@
-this is an inner module, use reflectModule on an InstanceMirror to obtain its ModuleMirror
-()
+object R is an inner module, use reflectModule on an InstanceMirror to obtain its ModuleMirror
+()
diff --git a/test/files/run/reflection-modulemirror-nested-badpath.check b/test/files/run/reflection-modulemirror-nested-badpath.check
index 16a5b10390..f7980b9986 100644
--- a/test/files/run/reflection-modulemirror-nested-badpath.check
+++ b/test/files/run/reflection-modulemirror-nested-badpath.check
@@ -1,2 +1,2 @@
-this is a static module, use reflectModule on a RuntimeMirror to obtain its ModuleMirror
-()
+object R is a static module, use reflectModule on a RuntimeMirror to obtain its ModuleMirror
+()
diff --git a/test/files/run/reflection-modulemirror-toplevel-badpath.check b/test/files/run/reflection-modulemirror-toplevel-badpath.check
index 16a5b10390..f7980b9986 100644
--- a/test/files/run/reflection-modulemirror-toplevel-badpath.check
+++ b/test/files/run/reflection-modulemirror-toplevel-badpath.check
@@ -1,2 +1,2 @@
-this is a static module, use reflectModule on a RuntimeMirror to obtain its ModuleMirror
-()
+object R is a static module, use reflectModule on a RuntimeMirror to obtain its ModuleMirror
+()
diff --git a/test/files/run/reflection-sanitychecks.check b/test/files/run/reflection-sanitychecks.check
new file mode 100644
index 0000000000..d977e0ed66
--- /dev/null
+++ b/test/files/run/reflection-sanitychecks.check
@@ -0,0 +1,8 @@
+field: 1
+method: 2
+class: CC
+object: java.lang.Error: inner and nested modules are not supported yet
+field: scala.ScalaReflectionException: expected a member of class C, you provided value D.foo
+method: scala.ScalaReflectionException: expected a member of class C, you provided method D.bar
+class: scala.ScalaReflectionException: expected a member of class C, you provided class D.C
+object: scala.ScalaReflectionException: expected a member of class C, you provided object D.O
diff --git a/test/files/run/reflection-sanitychecks.scala b/test/files/run/reflection-sanitychecks.scala
new file mode 100644
index 0000000000..a6a24088a4
--- /dev/null
+++ b/test/files/run/reflection-sanitychecks.scala
@@ -0,0 +1,30 @@
+class C {
+ val foo = 1
+ def bar = 2
+ class C { override def toString = "CC" }
+ object O { override def toString = "CO" }
+}
+
+class D {
+ val foo = 3
+ def bar = 4
+ class C { override def toString = "DC" }
+ object O { override def toString = "DO" }
+}
+
+object Test extends App {
+ import scala.reflect.runtime.universe._
+ import scala.reflect.runtime.{currentMirror => cm}
+ val im = cm.reflect(new C)
+
+ def test(tpe: Type): Unit = {
+ def failsafe(action: => Any): Any = try action catch { case ex: Throwable => ex.toString }
+ println("field: " + failsafe(im.reflectField(tpe.member(newTermName("foo")).asTermSymbol).get))
+ println("method: " + failsafe(im.reflectMethod(tpe.member(newTermName("bar")).asMethodSymbol)()))
+ println("class: " + failsafe(im.reflectClass(tpe.member(newTypeName("C")).asClassSymbol).reflectConstructor(typeOf[C].member(newTypeName("C")).asClassSymbol.typeSignature.member(newTermName("<init>")).asMethodSymbol)()))
+ println("object: " + failsafe(im.reflectModule(tpe.member(newTermName("O")).asModuleSymbol).instance))
+ }
+
+ test(typeOf[C])
+ test(typeOf[D])
+} \ No newline at end of file