summaryrefslogtreecommitdiff
path: root/sources/scala/tools/nsc/transform/LambdaLift.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2005-09-13 14:35:48 +0000
committerMartin Odersky <odersky@gmail.com>2005-09-13 14:35:48 +0000
commitb058c90501ec726024b2af18fd163f01567911aa (patch)
tree724d395d16ebd2ed1bd1732bcda013e38b37a855 /sources/scala/tools/nsc/transform/LambdaLift.scala
parentb6f8d5a603fab46e6e8e30fc85a35d36fda6f05e (diff)
downloadscala-b058c90501ec726024b2af18fd163f01567911aa.tar.gz
scala-b058c90501ec726024b2af18fd163f01567911aa.tar.bz2
scala-b058c90501ec726024b2af18fd163f01567911aa.zip
*** empty log message ***
Diffstat (limited to 'sources/scala/tools/nsc/transform/LambdaLift.scala')
-rwxr-xr-xsources/scala/tools/nsc/transform/LambdaLift.scala52
1 files changed, 36 insertions, 16 deletions
diff --git a/sources/scala/tools/nsc/transform/LambdaLift.scala b/sources/scala/tools/nsc/transform/LambdaLift.scala
index 353baf620b..e4647a41f2 100755
--- a/sources/scala/tools/nsc/transform/LambdaLift.scala
+++ b/sources/scala/tools/nsc/transform/LambdaLift.scala
@@ -13,8 +13,8 @@ import collection.mutable.HashMap;
abstract class LambdaLift extends InfoTransform {
import global._;
import definitions._;
- import typer.{typed}; // methods to type trees
- import posAssigner.atPos; // for filling in tree positions
+ import typer.{typed, typedOperator};
+ import posAssigner.atPos;
/** the following two members override abstract members in Transform */
val phaseName: String = "lambdalift";
@@ -127,15 +127,24 @@ abstract class LambdaLift extends InfoTransform {
liftedDefs(tree.symbol) = new ListBuffer;
if (sym.isLocal) renamable addEntry sym;
case DefDef(_, _, _, _, _, _) =>
- if (sym.isLocal) renamable addEntry sym;
- if (sym.isPrimaryConstructor) symSet(called, sym) addEntry sym.owner;
+ if (sym.isLocal) {
+ renamable addEntry sym;
+ sym setFlag (PRIVATE | LOCAL | FINAL)
+ } else if (sym.isPrimaryConstructor) {
+ symSet(called, sym) addEntry sym.owner
+ }
case Ident(name) =>
if (sym == NoSymbol) {
assert(name == nme.WILDCARD)
} else if (sym.isLocal) {
val owner = enclMethOrClass(currentOwner);
- if (owner.isMethod && sym.isMethod) symSet(called, owner) addEntry sym;
- else if (sym.isTerm) markFree(sym, owner)
+ if (sym.isTerm && !sym.isMethod) markFree(sym, owner)
+ else if (owner.isMethod && sym.isMethod) symSet(called, owner) addEntry sym;
+ }
+ case Select(_, _) =>
+ if (sym.isConstructor && sym.owner.isLocal) {
+ val owner = enclMethOrClass(currentOwner);
+ if (owner.isMethod) symSet(called, owner) addEntry sym;
}
case _ =>
}
@@ -203,14 +212,20 @@ abstract class LambdaLift extends InfoTransform {
else searchIn(currentOwner)
}
+ private def memberRef(sym: Symbol) = {
+ val clazz = sym.owner.enclClass;
+ val qual = if (clazz == currentOwner.enclClass) gen.This(clazz)
+ else {
+ sym resetFlag(LOCAL | PRIVATE);
+ if (clazz.isStaticOwner) gen.mkQualifier(clazz.thisType)
+ else outerPath(outerValue, clazz)
+ }
+ Select(qual, sym) setType sym.tpe
+ }
+
private def proxyRef(sym: Symbol) = {
val psym = proxy(sym);
- if (psym.isLocal) gen.Ident(psym)
- else if (psym.owner == currentOwner.enclClass) gen.mkRef(psym)
- else {
- psym resetFlag (PRIVATE | LOCAL);
- Select(outerPath(outerValue, psym.owner), psym) setType psym.tpe
- }
+ if (psym.isLocal) gen.Ident(psym) else memberRef(psym)
}
private def addFreeArgs(pos: int, sym: Symbol, args: List[Tree]) = {
@@ -237,10 +252,12 @@ abstract class LambdaLift extends InfoTransform {
private def liftDef(tree: Tree): Tree = {
val sym = tree.symbol;
- if (sym.isMethod) sym setFlag (PRIVATE | LOCAL);
sym.owner = sym.owner.enclClass;
+ if (sym.isClass) sym.owner = sym.owner.toInterface;
+ if (sym.isMethod) sym setFlag LIFTED;
liftedDefs(sym.owner) += tree;
sym.owner.info.decls enter sym;
+ if (settings.debug.value) log("lifted: " + sym + sym.locationString);
EmptyTree
}
@@ -281,9 +298,12 @@ abstract class LambdaLift extends InfoTransform {
copy.Assign(tree, qual, rhs)
case Ident(name) =>
val tree1 =
- if (sym != NoSymbol && sym.isLocal && sym.isTerm && !sym.isMethod &&
- enclMethOrClass(sym.owner) != enclMethOrClass(currentOwner))
- atPos(tree.pos)(proxyRef(sym))
+ if (sym != NoSymbol && sym.isTerm && !sym.isLabel)
+ if (sym.isMethod)
+ atPos(tree.pos)(memberRef(sym))
+ else if (sym.isLocal && enclMethOrClass(sym.owner) != enclMethOrClass(currentOwner))
+ atPos(tree.pos)(proxyRef(sym))
+ else tree
else tree;
if (sym hasFlag CAPTURED)
atPos(tree.pos) {