diff options
author | Iulian Dragos <jaguarul@gmail.com> | 2005-11-16 16:41:21 +0000 |
---|---|---|
committer | Iulian Dragos <jaguarul@gmail.com> | 2005-11-16 16:41:21 +0000 |
commit | b1944462af631940ffc8fe53c9ecc338df5d6309 (patch) | |
tree | 9616b78ad1315ad2404209a6958f48f0cec5493d /sources/scala/tools/nsc/transform/UnCurry.scala | |
parent | 306e0e4e7a88a00eaac88820649aec407b170fbe (diff) | |
download | scala-b1944462af631940ffc8fe53c9ecc338df5d6309.tar.gz scala-b1944462af631940ffc8fe53c9ecc338df5d6309.tar.bz2 scala-b1944462af631940ffc8fe53c9ecc338df5d6309.zip |
Fixed lifting of try-catches in expressions.
Diffstat (limited to 'sources/scala/tools/nsc/transform/UnCurry.scala')
-rwxr-xr-x | sources/scala/tools/nsc/transform/UnCurry.scala | 88 |
1 files changed, 66 insertions, 22 deletions
diff --git a/sources/scala/tools/nsc/transform/UnCurry.scala b/sources/scala/tools/nsc/transform/UnCurry.scala index 97d35b0004..4a22f9711f 100755 --- a/sources/scala/tools/nsc/transform/UnCurry.scala +++ b/sources/scala/tools/nsc/transform/UnCurry.scala @@ -37,6 +37,8 @@ abstract class UnCurry extends InfoTransform { def newTransformer(unit: CompilationUnit): Transformer = new UnCurryTransformer(unit); override def changesBaseClasses = false; + var needTryLift = false; + private val uncurry = new TypeMap { def apply(tp: Type): Type = tp match { case MethodType(formals, MethodType(formals1, restpe)) => @@ -194,28 +196,70 @@ abstract class UnCurry extends InfoTransform { } } - def mainTransform(tree: Tree): Tree = (tree match { - case Apply(Select(Block(List(), Function(vparams, body)), nme.apply), args) => - // perform beta-reduction; this helps keep view applications small - mainTransform(new TreeSubstituter(vparams map (.symbol), args).transform(body)) - case Apply(fn, args) => - val formals = fn.tpe.paramTypes; - copy.Apply(tree, transform(fn), transformTrees(transformArgs(tree.pos, args, formals))) - case CaseDef(pat, guard, body) => - inPattern = true; - val pat1 = transform(pat); - inPattern = false; - copy.CaseDef(tree, pat1, transform(guard), transform(body)) - case fun @ Function(_, _) => - mainTransform(transformFunction(fun)) - case _ => - assert(!tree.isInstanceOf[Function]); - val tree1 = super.transform(tree); - if (isByNameRef(tree1)) - typed(atPos(tree1.pos)( - Apply(Select(tree1 setType functionType(List(), tree1.tpe), nme.apply), List()))) - else tree1; - }) setType uncurryTreeType(tree.tpe); + def mainTransform(tree: Tree): Tree = { + def withNeedLift(needLift: Boolean)(f: => Tree): Tree = { + val savedNeedTryLift = needTryLift; + needTryLift = needLift; + val t = f; + needTryLift = savedNeedTryLift; + t + } + + tree match { + case DefDef(_, _, _, _, _, _) => + withNeedLift(false) { super.transform(tree) } + + case ValDef(_, _, _, rhs) + if (!tree.symbol.owner.isSourceMethod) => + withNeedLift(true) { super.transform(tree) } + + + case Apply(Select(Block(List(), Function(vparams, body)), nme.apply), args) => + // perform beta-reduction; this helps keep view applications small + withNeedLift(true) { + mainTransform(new TreeSubstituter(vparams map (.symbol), args).transform(body)) + } + + case Apply(fn, args) => + withNeedLift(true) { + val formals = fn.tpe.paramTypes; + copy.Apply(tree, transform(fn), transformTrees(transformArgs(tree.pos, args, formals))) + } + + case Assign(Select(_, _), _) => + withNeedLift(true) { super.transform(tree) } + + case Try(block, catches, finalizer) => + if (needTryLift) { + if (settings.debug.value) + log("lifting try at: " + unit.position(tree.pos)); + + val sym = currentOwner.newMethod(tree.pos, unit.fresh.newName("liftedTry")); + sym.setInfo(MethodType(List(), tree.tpe)); + new ChangeOwnerTraverser(currentOwner, sym).traverse(tree); + + transform(typed(atPos(tree.pos)( + Block(List(DefDef(sym, List(List()), tree)), + Apply(Ident(sym), Nil))))) + } else + super.transform(tree) + + case CaseDef(pat, guard, body) => + inPattern = true; + val pat1 = transform(pat); + inPattern = false; + copy.CaseDef(tree, pat1, transform(guard), transform(body)) + case fun @ Function(_, _) => + mainTransform(transformFunction(fun)) + case _ => + assert(!tree.isInstanceOf[Function]); + val tree1 = super.transform(tree); + if (isByNameRef(tree1)) + typed(atPos(tree1.pos)( + Apply(Select(tree1 setType functionType(List(), tree1.tpe), nme.apply), List()))) + else tree1; + } + } setType uncurryTreeType(tree.tpe); def postTransform(tree: Tree): Tree = atPhase(phase.next) { def applyUnary(tree: Tree): Tree = |