summaryrefslogtreecommitdiff
path: root/sources/scala/tools/nsc/transform/UnCurry.scala
diff options
context:
space:
mode:
authorIulian Dragos <jaguarul@gmail.com>2005-11-16 16:41:21 +0000
committerIulian Dragos <jaguarul@gmail.com>2005-11-16 16:41:21 +0000
commitb1944462af631940ffc8fe53c9ecc338df5d6309 (patch)
tree9616b78ad1315ad2404209a6958f48f0cec5493d /sources/scala/tools/nsc/transform/UnCurry.scala
parent306e0e4e7a88a00eaac88820649aec407b170fbe (diff)
downloadscala-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-xsources/scala/tools/nsc/transform/UnCurry.scala88
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 =