diff options
-rw-r--r-- | src/reflect/scala/reflect/runtime/JavaMirrors.scala | 23 | ||||
-rw-r--r-- | test/files/run/t6323.check | 1 | ||||
-rw-r--r-- | test/files/run/t6323.scala | 21 |
3 files changed, 42 insertions, 3 deletions
diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala index 9f2c3fc79c..455cc14789 100644 --- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala +++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala @@ -133,6 +133,7 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym """.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") + private def ErrorFree(member: Symbol, freeType: Symbol) = throw new ScalaReflectionException(s"cannot reflect ${member.kindString} ${member.name}, because it's a member of a free type ${freeType.name}") def reflect[T: ClassTag](obj: T): InstanceMirror = new JavaInstanceMirror(obj) @@ -154,13 +155,30 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym def moduleSymbol(rtcls: RuntimeClass): ModuleSymbol = classToScala(rtcls).companionModule.asModule + private def ensuringNotFree(wannabe: Symbol)(body: => Any) { + val freeType = wannabe.ownerChain find (_.isFreeType) + freeType match { + case Some(freeType) => ErrorFree(wannabe, freeType) + case _ => body + } + } + private def checkMemberOf(wannabe: Symbol, owner: ClassSymbol) { if (wannabe.owner == AnyClass || wannabe.owner == AnyRefClass || wannabe.owner == ObjectClass) { // do nothing } else if (wannabe.owner == AnyValClass) { if (!owner.isPrimitiveValueClass && !owner.isDerivedValueClass) ErrorNotMember(wannabe, owner) } else { - if (!(owner.info.baseClasses contains wannabe.owner)) ErrorNotMember(wannabe, owner) + ensuringNotFree(wannabe) { + if (!(owner.info.baseClasses contains wannabe.owner)) ErrorNotMember(wannabe, owner) + } + } + } + + private def checkConstructorOf(wannabe: Symbol, owner: ClassSymbol) { + if (!wannabe.isClassConstructor) ErrorNotConstructor(wannabe, owner) + ensuringNotFree(wannabe) { + if (!owner.info.decls.toList.contains(wannabe)) ErrorNotConstructor(wannabe, owner) } } @@ -386,8 +404,7 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym def erasure = symbol def isStatic = false def reflectConstructor(constructor: MethodSymbol) = { - if (!constructor.isClassConstructor) ErrorNotConstructor(constructor, symbol) - if (!symbol.info.decls.toList.contains(constructor)) ErrorNotConstructor(constructor, symbol) + checkConstructorOf(constructor, symbol) new JavaConstructorMirror(outer, constructor) } def companion: Option[ModuleMirror] = symbol.companionModule match { diff --git a/test/files/run/t6323.check b/test/files/run/t6323.check new file mode 100644 index 0000000000..2219278a16 --- /dev/null +++ b/test/files/run/t6323.check @@ -0,0 +1 @@ +cannot reflect value a, because it's a member of a free type Test
diff --git a/test/files/run/t6323.scala b/test/files/run/t6323.scala new file mode 100644 index 0000000000..625cfaae20 --- /dev/null +++ b/test/files/run/t6323.scala @@ -0,0 +1,21 @@ +import scala.reflect.runtime.universe._ +import scala.reflect.runtime.{currentMirror => m} +import scala.reflect.runtime.{universe => u} + +object Test extends App { + locally { + try { + case class Test(a:String,b:List[Int]) + + val lookAtMe = m.reflect(Test("a",List(5))) + val value = u.typeOf[Test] + val members = value.members + val member = value.members.filter(_.name.encoded == "a") + val aAccessor = lookAtMe.reflectMethod(member.head.asMethod) + val thisShouldBeA = aAccessor.apply() + println(thisShouldBeA) + } catch { + case ScalaReflectionException(msg) => println(msg) + } + } +}
\ No newline at end of file |