diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Definitions.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/StdNames.scala | 1 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/CleanUp.scala | 32 | ||||
-rw-r--r-- | test/files/run/structural.check | 1 | ||||
-rw-r--r-- | test/files/run/structural.scala | 22 |
5 files changed, 47 insertions, 11 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala index d31092d6b4..2528181e0e 100644 --- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala +++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala @@ -50,6 +50,8 @@ trait Definitions { lazy val ThrowableClass: Symbol = getClass(sn.Throwable) lazy val NullPointerExceptionClass: Symbol = getClass(sn.NPException) lazy val NonLocalReturnExceptionClass: Symbol = getClass(sn.NLRException) + lazy val InvocationTargetExceptionClass: Symbol = + getClass("java.lang.reflect.InvocationTargetException") // java is hard coded because only used by structural values // System.ValueType lazy val ValueTypeClass: Symbol = getClass(sn.ValueType) diff --git a/src/compiler/scala/tools/nsc/symtab/StdNames.scala b/src/compiler/scala/tools/nsc/symtab/StdNames.scala index 1a2921bc1c..f3953792f3 100644 --- a/src/compiler/scala/tools/nsc/symtab/StdNames.scala +++ b/src/compiler/scala/tools/nsc/symtab/StdNames.scala @@ -282,6 +282,7 @@ trait StdNames { val forName = newTermName(if (forMSIL) "GetType" else "forName") val foreach = newTermName("foreach") val get = newTermName("get") + val getCause = newTermName("getCause") val getClass_ = newTermName("getClass") val getMethod_ = newTermName("getMethod") val hasAsInstance = newTermName("hasAsInstance") diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala index ea6e66344b..20b1e0d664 100644 --- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala +++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala @@ -121,7 +121,7 @@ abstract class CleanUp extends Transform { } val rmmeth = owner.newMethod(pos, unit.fresh.newName("reflMethod$Method")) - .setFlag(PRIVATE | STATIC | SYNTHETIC) + .setFlag(STATIC | SYNTHETIC) .setInfo(MethodType(List(ClassClass.tpe), MethodClass.tpe)) owner.info.decls.enter(rmmeth) val rmmdef = @@ -409,18 +409,28 @@ abstract class CleanUp extends Transform { } def callAsMethod(paramTypes: List[Type], resType: Type): Tree = localTyper.typed { - Apply( - Select( - Apply( - gen.mkAttributedRef(reflectiveMethodCache(tree.pos, ad.symbol.name.toString, paramTypes)), - List(Apply(Select(qual, ObjectClass.tpe.member(nme.getClass_)), Nil)) + val invokeExc = + currentOwner.newValue(tree.pos, newTermName(unit.fresh.newName)) setInfo InvocationTargetExceptionClass.tpe + Try( + Apply( + Select( + Apply( + gen.mkAttributedRef(reflectiveMethodCache(tree.pos, ad.symbol.name.toString, paramTypes)), + List(Apply(Select(qual, ObjectClass.tpe.member(nme.getClass_)), Nil)) + ), + MethodClass.tpe.member(nme.invoke_) ), - MethodClass.tpe.member(nme.invoke_) + List( + qual, + ArrayValue(TypeTree(ObjectClass.tpe), fixParams(params, paramTypes)) + ) ), - List( - qual, - ArrayValue(TypeTree(ObjectClass.tpe), fixParams(params, paramTypes)) - ) + List(CaseDef( + Bind(invokeExc, Typed(Ident(nme.WILDCARD), TypeTree(InvocationTargetExceptionClass.tpe))), + EmptyTree, + Throw(Apply(Select(Ident(invokeExc), nme.getCause), Nil)) + )), + EmptyTree ) } diff --git a/test/files/run/structural.check b/test/files/run/structural.check index 34d31ada59..52292fcb36 100644 --- a/test/files/run/structural.check +++ b/test/files/run/structural.check @@ -32,3 +32,4 @@ 3 4 5 +caught diff --git a/test/files/run/structural.scala b/test/files/run/structural.scala index 6ced0e569a..d6b2b3d09f 100644 --- a/test/files/run/structural.scala +++ b/test/files/run/structural.scala @@ -150,7 +150,29 @@ object test2 { x5.f() } +object test3 { + + case class Exc extends Exception + + object Rec { + def f = throw Exc() + } + + def m(r: { def f: Nothing }) = + try { + r.f + } + catch { + case e: Exc => println("caught") + case e => println(e) + } + + m(Rec) + +} + object Test extends Application { test1 test2 + test3 } |