From 90d2bee45b25844f809f8c5300aefcb1bfe9e336 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Wed, 2 May 2012 01:18:27 -0700 Subject: Fixs for reflection and getSimpleName. Since getSimpleName will be crashing us indefinitely, took the expedient route and wrapped the call. --- .../scala/reflect/runtime/JavaToScala.scala | 25 +++++++++++- test/files/run/reflection-simple.check | 45 ++++++++++++++++++++++ test/files/run/reflection-simple.scala | 11 ++++++ 3 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 test/files/run/reflection-simple.check create mode 100644 test/files/run/reflection-simple.scala diff --git a/src/compiler/scala/reflect/runtime/JavaToScala.scala b/src/compiler/scala/reflect/runtime/JavaToScala.scala index 6688d77985..e11f6140c9 100644 --- a/src/compiler/scala/reflect/runtime/JavaToScala.scala +++ b/src/compiler/scala/reflect/runtime/JavaToScala.scala @@ -314,6 +314,27 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable => private def followStatic(clazz: Symbol, mods: Int) = if (jModifier.isStatic(mods)) clazz.companionModule.moduleClass else clazz + /** Methods which need to be wrapped because they either are getSimpleName + * or call getSimpleName: + * + * public String getSimpleName() + * public boolean isAnonymousClass() + * public boolean isLocalClass() + * public boolean isMemberClass() + * public String getCanonicalName() + * + * TODO - find all such calls and wrap them. + * TODO - create mechanism to avoid the recurrence of unwrapped calls. + */ + private def wrapClassCheck[T](alt: T)(body: => T): T = + try body catch { case x: InternalError if x.getMessage == "Malformed class name" => alt } + + private def wrapIsLocalClass(clazz: jClass[_]): Boolean = + wrapClassCheck(false)(clazz.isLocalClass) + + private def wrapGetSimpleName(clazz: jClass[_]): String = + wrapClassCheck("")(clazz.getSimpleName) + /** * The Scala owner of the Scala class corresponding to the Java class `jclazz` */ @@ -322,7 +343,7 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable => val jEnclosingClass = jclazz.getEnclosingClass val sEnclosingClass = classToScala(jEnclosingClass) followStatic(sEnclosingClass, jclazz.getModifiers) - } else if (jclazz.isLocalClass) { + } else if (wrapIsLocalClass(jclazz)) { val jEnclosingMethod = jclazz.getEnclosingMethod if (jEnclosingMethod != null) { methodToScala(jEnclosingMethod) @@ -494,7 +515,7 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable => val sym = { if (jclazz.isMemberClass && !nme.isImplClassName(jname)) { lookup - } else if (jclazz.isLocalClass || invalidClassName(jname)) { + } else if (wrapIsLocalClass(jclazz) || invalidClassName(jname)) { // local classes and implementation classes not preserved by unpickling - treat as Java jclassAsScala(jclazz) } else if (jclazz.isArray) { diff --git a/test/files/run/reflection-simple.check b/test/files/run/reflection-simple.check new file mode 100644 index 0000000000..671d9d2716 --- /dev/null +++ b/test/files/run/reflection-simple.check @@ -0,0 +1,45 @@ +Running +constructor Foo$3 +constructor Object +method != +method != +method ## +method $asInstanceOf +method $init$ +method $isInstanceOf +method == +method == +method _1 +method _2 +method _3 +method a +method asInstanceOf +method b +method c +method canEqual +method clone +method copy +method copy$default$1 +method copy$default$2 +method copy$default$3 +method eq +method equals +method finalize +method getClass +method hashCode +method isInstanceOf +method ne +method notify +method notifyAll +method productArity +method productElement +method productIterator +method productPrefix +method synchronized +method toString +method wait +method wait +method wait +value a +value b +value c diff --git a/test/files/run/reflection-simple.scala b/test/files/run/reflection-simple.scala new file mode 100644 index 0000000000..fb3feec3cb --- /dev/null +++ b/test/files/run/reflection-simple.scala @@ -0,0 +1,11 @@ +// a.scala +// Wed May 2 01:01:22 PDT 2012 + +object Test { + def main(args: Array[String]) { + System.out.println("Running") + case class Foo(a: Int, b: Int, c: Int) + val props = reflect.mirror.classToType(classOf[Foo]).members.filter(_.isTerm).map(_.toString) + props.toList.sorted foreach System.out.println + } +} -- cgit v1.2.3