diff options
author | Martin Odersky <odersky@gmail.com> | 2003-07-08 13:19:33 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2003-07-08 13:19:33 +0000 |
commit | fedbced652b533da4baeea37c39c058d2cd2afd8 (patch) | |
tree | 6abfe4284db8f92c12fba14d671de6f7b827068e /sources | |
parent | 639f1084419fb54acf6ee9f6c405e302ba21abd3 (diff) | |
download | scala-fedbced652b533da4baeea37c39c058d2cd2afd8.tar.gz scala-fedbced652b533da4baeea37c39c058d2cd2afd8.tar.bz2 scala-fedbced652b533da4baeea37c39c058d2cd2afd8.zip |
*** empty log message ***
Diffstat (limited to 'sources')
-rw-r--r-- | sources/scalac/symtab/Modifiers.java | 1 | ||||
-rw-r--r-- | sources/scalac/symtab/Type.java | 6 | ||||
-rw-r--r-- | sources/scalac/transformer/LambdaLift.java | 83 |
3 files changed, 71 insertions, 19 deletions
diff --git a/sources/scalac/symtab/Modifiers.java b/sources/scalac/symtab/Modifiers.java index 00509ad16b..5948dc2157 100644 --- a/sources/scalac/symtab/Modifiers.java +++ b/sources/scalac/symtab/Modifiers.java @@ -48,6 +48,7 @@ public interface Modifiers { int ACCESSOR = 0x04000000; // function is an access function for a // value or variable int BRIDGE = 0x08000000; // function is a bridge method. + int LIFTED = BRIDGE; // transient flag for lambdalift int SNDTIME = BRIDGE; // debug int INTERFACE = 0x10000000; // symbol is a Java interface diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java index 430bcaa5e9..ae2960bb4e 100644 --- a/sources/scalac/symtab/Type.java +++ b/sources/scalac/symtab/Type.java @@ -29,7 +29,7 @@ public class Type implements Modifiers, Kinds, TypeTags { public case ThisType(Symbol sym); /** pre.sym.type - * sym represents a value + * sym represents a valueS */ public case SingleType(Type pre, Symbol sym) { assert this instanceof ExtSingleType; @@ -1272,7 +1272,9 @@ public class Type implements Modifiers, Kinds, TypeTags { case TypeRef(Type pre1, Symbol sym1, Type[] args1): switch (this) { case TypeRef(Type pre, Symbol sym, Type[] args): - if (sym.name == sym1.name && pre.isSubType(pre1) && + boolean samepre = pre.isSameAs(pre1); + if ((samepre && sym == sym1 /* fast case */ || + !samepre && pre.isSubType(pre1) && sym == pre.rebind(sym1)) && isSubArgs(args, args1, sym.typeParams()) || sym.kind == TYPE && pre.memberInfo(sym).isSubType(that)) diff --git a/sources/scalac/transformer/LambdaLift.java b/sources/scalac/transformer/LambdaLift.java index 1e90f95624..a86c39c793 100644 --- a/sources/scalac/transformer/LambdaLift.java +++ b/sources/scalac/transformer/LambdaLift.java @@ -50,6 +50,7 @@ public class LambdaLift extends OwnerTransformer public void apply(Unit unit) { global.log(unit.source.toString()); free.initialize(unit); + currentOwner = global.definitions.ROOT_CLASS; unit.body = transformTemplateStats(unit.body, currentOwner); } @@ -315,42 +316,49 @@ public class LambdaLift extends OwnerTransformer tree.type = descr.transform(tree.type, currentOwner); //System.out.println(tree.type);//DEBUG switch (tree) { - case ClassDef(_, _, TypeDef[] tparams, ValDef[][] vparams, Tree tpe, Template impl): + case Block(Tree[] stats): + for (int i = 0; i < stats.length; i++) + liftSymbol(stats[i]); + return copy.Block(tree, transform(stats)); + + case ClassDef(int mods, _, TypeDef[] tparams, ValDef[][] vparams, Tree tpe, Template impl): Symbol sym = tree.symbol(); - if (sym.isLocal()) { - Symbol[] newtparams = ftvsParams(sym.constructor()); - Symbol[] newparams = fvsParams(sym.constructor()); - liftSymbol(sym, newtparams, newparams); + if ((mods & LIFTED) != 0) { + ((ClassDef) tree).mods &= ~LIFTED; Tree tree1 = copy.ClassDef( tree, sym, - addTypeParams(transform(tparams, sym), newtparams), - new ValDef[][]{addParams(transform(vparams, sym)[0], newparams)}, + addTypeParams(transform(tparams, sym), newtparams(sym.constructor())), + new ValDef[][]{ + addParams(transform(vparams, sym)[0], newparams(sym.constructor()))}, transform(tpe, sym), transform(impl, sym)); liftedDefs.append(tree1); return Tree.Empty; } else { + assert !sym.isLocal() : sym; return copy.ClassDef( tree, sym, - transform(tparams, sym), transform(vparams, sym), transform(tpe, sym), + transform(tparams, sym), + transform(vparams, sym), + transform(tpe, sym), transform(impl, sym)); } - case DefDef(_, _, TypeDef[] tparams, ValDef[][] vparams, Tree tpe, Tree rhs): + case DefDef(int mods, _, TypeDef[] tparams, ValDef[][] vparams, Tree tpe, Tree rhs): Symbol sym = tree.symbol(); - if (sym.isLocal()) { - Symbol[] newtparams = ftvsParams(sym); - Symbol[] newparams = fvsParams(sym); - liftSymbol(sym, newtparams, newparams); + if ((mods & LIFTED) != 0) { + ((DefDef) tree).mods &= ~LIFTED; Tree tree1 = copy.DefDef( tree, sym, - addTypeParams(transform(tparams, sym), newtparams), - new ValDef[][]{addParams(transform(vparams, sym)[0], newparams)}, + addTypeParams(transform(tparams, sym), newtparams(sym)), + new ValDef[][]{ + addParams(transform(vparams, sym)[0], newparams(sym))}, transform(tpe, sym), transform(rhs, sym)); liftedDefs.append(tree1); return Tree.Empty; } else { + assert !sym.isLocal() : sym; return copy.DefDef( tree, sym, transform(tparams, sym), transform(vparams, sym), transform(tpe, sym), @@ -400,7 +408,8 @@ public class LambdaLift extends OwnerTransformer default: Tree[] targs = addFreeArgs( tree.pos, get(free.ftvs, fsym), Tree.EMPTY_ARRAY); - if (targs.length > 0) fn1 = gen.TypeApply(fn1, targs); + if (targs.length > 0) + fn1 = gen.TypeApply(fn1, targs); } Tree[] args1 = transform(args); return copy.Apply( @@ -451,11 +460,47 @@ public class LambdaLift extends OwnerTransformer return params; } - /** change symbol so that + Symbol[] newtparams(Symbol owner) { + Symbol[] tparams = owner.typeAt(descr.nextPhase).typeParams(); + int nfree = get(free.ftvs, owner).size(); + assert nfree == tparams.length - owner.type().typeParams().length + : owner + " " + nfree + " " + tparams.length + " " + owner.type().firstParams().length; + Symbol[] newtparams = new Symbol[nfree]; + System.arraycopy(tparams, tparams.length - nfree, newtparams, 0, nfree); + return newtparams; + } + + Symbol[] newparams(Symbol owner) { + Symbol[] params = owner.typeAt(descr.nextPhase).firstParams(); + int nfree = get(free.fvs, owner).size(); + assert nfree == params.length - owner.type().firstParams().length; + Symbol[] newparams = new Symbol[nfree]; + System.arraycopy(params, params.length - nfree, newparams, 0, nfree); + return newparams; + } + + /** change symbol of tree so that * owner = currentClass * newparams are added * enter symbol in scope of currentClass */ + void liftSymbol(Tree tree) { + switch (tree) { + case ClassDef(_, _, _, _, _, _): + ((ClassDef) tree).mods |= LIFTED; + Symbol sym = tree.symbol(); + assert sym.isLocal() : sym; + liftSymbol(sym, ftvsParams(sym.constructor()), fvsParams(sym.constructor())); + break; + + case DefDef(_, _, _, _, _, _): + ((DefDef) tree).mods |= LIFTED; + Symbol sym = tree.symbol(); + assert sym.isLocal() : sym; + liftSymbol(sym, ftvsParams(sym), fvsParams(sym)); + } + } + void liftSymbol(Symbol sym, Symbol[] newtparams, Symbol[] newparams) { Symbol enclClass = sym.owner().enclClass(); if (!sym.isPrimaryConstructor()) sym.setOwner(enclClass); @@ -491,6 +536,10 @@ public class LambdaLift extends OwnerTransformer } } + boolean isLocal() { + return currentOwner.kind == VAL && currentOwner.name != Name.EMPTY; + } + Type addParams(Type tp, Symbol[] newparams) { if (newparams.length == 0) return tp; switch (tp) { |