summaryrefslogtreecommitdiff
path: root/sources/scalac/transformer/LambdaLift.java
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2003-09-25 10:11:17 +0000
committerMartin Odersky <odersky@gmail.com>2003-09-25 10:11:17 +0000
commitd564a5473c6d901f85a2bc82c4589da5b800011b (patch)
tree731e1a6684ac2748b6e2ecabb9109c6c39284657 /sources/scalac/transformer/LambdaLift.java
parent423ecdde9b683f8b32624e5e08930c7f461dca4e (diff)
downloadscala-d564a5473c6d901f85a2bc82c4589da5b800011b.tar.gz
scala-d564a5473c6d901f85a2bc82c4589da5b800011b.tar.bz2
scala-d564a5473c6d901f85a2bc82c4589da5b800011b.zip
*** empty log message ***
Diffstat (limited to 'sources/scalac/transformer/LambdaLift.java')
-rw-r--r--sources/scalac/transformer/LambdaLift.java36
1 files changed, 31 insertions, 5 deletions
diff --git a/sources/scalac/transformer/LambdaLift.java b/sources/scalac/transformer/LambdaLift.java
index c12b7c8a79..209be84626 100644
--- a/sources/scalac/transformer/LambdaLift.java
+++ b/sources/scalac/transformer/LambdaLift.java
@@ -63,7 +63,30 @@ public class LambdaLift extends OwnerTransformer
return sym.kind == CLASS ? sym.primaryConstructor() : sym;
}
- /** `asFunction' applied to the next enclosing function or class owner.
+ /** Is symbol local relative to owner?
+ * Primary constructor parameters are local iff owner (contained in)
+ * the primary constructor.
+ */
+ static boolean isLocal(Symbol sym, Symbol owner) {
+ if ((sym.flags & PARAM) != 0 &&
+ sym.owner().isPrimaryConstructor() &&
+ sym.owner().constructorClass().kind == CLASS &&
+ !((owner.flags & PARAM) != 0 && owner.owner() == sym)) {
+ Symbol encl = sym.owner().owner();
+ Symbol clazz = sym.owner().constructorClass();
+ //System.out.println("isLocal " + sym + " " + encl + " " + clazz + " " + owner);//DEBUG
+ while (owner != encl &&
+ owner.kind != NONE &&
+ owner != clazz) {
+ owner = owner.owner();
+ //System.out.println(":" + owner);//DEBUG
+ }
+ return owner != clazz;
+ }
+ return sym.isLocal();
+ }
+
+ /** Propagate free fariables from all called functions. /** `asFunction' applied to the next enclosing function or class owner.
*/
static Symbol enclFun(Symbol owner) {
Symbol sym = owner;
@@ -178,9 +201,12 @@ public class LambdaLift extends OwnerTransformer
private Type.Map traverseTypeMap = new Type.Map() {
public Type apply(Type tp) {
+ if (global.debug) global.log("traverse " + tp);//debug
switch (tp) {
case TypeRef(ThisType(_), Symbol sym, Type[] targs):
- if (sym.isLocal() && sym.kind == TYPE && !excluded.contains(sym))
+ if (isLocal(sym, currentOwner) &&
+ sym.kind == TYPE &&
+ !excluded.contains(sym))
markFree(sym, currentOwner);
break;
case PolyType(Symbol[] tparams, Type restp):
@@ -196,7 +222,7 @@ public class LambdaLift extends OwnerTransformer
};
public Tree transform(Tree tree) {
- //if (global.debug) global.debugPrinter.print("free ").print(tree).println().end();//DEBUG
+ if (global.debug) global.log("free " + tree);//debug
assert tree.type != null : tree;
traverseTypeMap.apply(tree.type.widen());
Symbol sym = tree.symbol();
@@ -227,7 +253,7 @@ public class LambdaLift extends OwnerTransformer
transform(rhs, currentOwner));
case Ident(_):
- if (sym.isLocal()) {
+ if (isLocal(sym, currentOwner)) {
if (sym.isMethod()) {
Symbol f = enclFun(currentOwner);
if (f.name.length() > 0) // it is not a template function {
@@ -435,7 +461,7 @@ public class LambdaLift extends OwnerTransformer
case Ident(Name name):
Symbol sym = tree.symbol();
- if (sym.isLocal() &&
+ if (isLocal(sym, currentOwner) &&
(sym.kind == TYPE || (sym.kind == VAL && !sym.isMethod()))) {
sym = descr.proxy(sym, currentOwner);
}