diff options
author | Eugene Burmako <xeno.by@gmail.com> | 2012-08-06 17:55:12 +0200 |
---|---|---|
committer | Eugene Burmako <xeno.by@gmail.com> | 2012-08-06 23:09:32 +0200 |
commit | 3cbe07f3e3ddb7201d1d174399d14d4a69df52fd (patch) | |
tree | f85e48e71ee73c51ec61138a6095e0f8c4c78254 | |
parent | 3c4f4865f6420f98a7ed502257bc65387951e26c (diff) | |
download | scala-3cbe07f3e3ddb7201d1d174399d14d4a69df52fd.tar.gz scala-3cbe07f3e3ddb7201d1d174399d14d4a69df52fd.tar.bz2 scala-3cbe07f3e3ddb7201d1d174399d14d4a69df52fd.zip |
sanity check for reflectConstructor
In 911bbc4 I've completely overlooked the fact that
reflectConstructor exists and that is also needs sanity checks.
Now reflectConstructor checks that the incoming symbol is actually a ctor,
and that it is actually a ctor of the class reflected by the current mirror.
-rw-r--r-- | src/reflect/scala/reflect/runtime/JavaMirrors.scala | 9 | ||||
-rw-r--r-- | test/files/run/reflection-sanitychecks.check | 4 | ||||
-rw-r--r-- | test/files/run/reflection-sanitychecks.scala | 4 |
3 files changed, 15 insertions, 2 deletions
diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala index 1698e99dae..f9407d5b1b 100644 --- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala +++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala @@ -126,13 +126,14 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym 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 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}") + private def ErrorNotConstructor(wannabe: Symbol, owner: Symbol) = throw new ScalaReflectionException(s"expected a constructor of $owner, you provided $wannabe") def reflect[T: ClassTag](obj: T): InstanceMirror = new JavaInstanceMirror(obj) @@ -379,7 +380,11 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym extends JavaTemplateMirror with ClassMirror { def erasure = symbol def isStatic = false - def reflectConstructor(constructor: MethodSymbol) = new JavaConstructorMirror(outer, constructor) + def reflectConstructor(constructor: MethodSymbol) = { + if (!constructor.isClassConstructor) ErrorNotConstructor(constructor, symbol) + if (!symbol.info.decls.toList.contains(constructor)) ErrorNotConstructor(constructor, symbol) + new JavaConstructorMirror(outer, constructor) + } def companion: Option[ModuleMirror] = symbol.companionModule match { case module: ModuleSymbol => Some(new JavaModuleMirror(outer, module)) case _ => None diff --git a/test/files/run/reflection-sanitychecks.check b/test/files/run/reflection-sanitychecks.check index d977e0ed66..4881285bc0 100644 --- a/test/files/run/reflection-sanitychecks.check +++ b/test/files/run/reflection-sanitychecks.check @@ -1,8 +1,12 @@ field: 1
method: 2
+constructor #1: scala.ScalaReflectionException: expected a constructor of class C, you provided method bar
+constructor #2: an instance of class C
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
+constructor #1: scala.ScalaReflectionException: expected a constructor of class C, you provided method bar
+constructor #2: scala.ScalaReflectionException: expected a constructor of class C, you provided constructor D
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 index e95d130460..b0982fc2fc 100644 --- a/test/files/run/reflection-sanitychecks.scala +++ b/test/files/run/reflection-sanitychecks.scala @@ -3,6 +3,7 @@ class C { def bar = 2 class C { override def toString = "CC" } object O { override def toString = "CO" } + override def toString = "an instance of class C" } class D { @@ -10,6 +11,7 @@ class D { def bar = 4 class C { override def toString = "DC" } object O { override def toString = "DO" } + override def toString = "an instance of class D" } object Test extends App { @@ -21,6 +23,8 @@ object Test extends App { def failsafe(action: => Any): Any = try action catch { case ex: Throwable => ex.toString } println("field: " + failsafe(im.reflectField(tpe.member(newTermName("foo")).asTerm).get)) println("method: " + failsafe(im.reflectMethod(tpe.member(newTermName("bar")).asMethod)())) + println("constructor #1: " + failsafe(cm.reflectClass(im.symbol).reflectConstructor(tpe.member(newTermName("bar")).asMethod)())) + println("constructor #2: " + failsafe(cm.reflectClass(im.symbol).reflectConstructor(tpe.member(newTermName("<init>")).asMethod)())) println("class: " + failsafe(im.reflectClass(tpe.member(newTypeName("C")).asClass).reflectConstructor(typeOf[C].member(newTypeName("C")).asClass.typeSignature.member(newTermName("<init>")).asMethod)())) println("object: " + failsafe(im.reflectModule(tpe.member(newTermName("O")).asModule).instance)) } |