diff options
author | paltherr <paltherr@epfl.ch> | 2004-05-13 13:13:54 +0000 |
---|---|---|
committer | paltherr <paltherr@epfl.ch> | 2004-05-13 13:13:54 +0000 |
commit | f475e1a49a406cfe88f4224cb3eb7299d6ec21c0 (patch) | |
tree | e47ca57162f6809a98cb764058896c3b7c693143 | |
parent | a405a10c05aa36eeb2d904382d05bb429cca9bea (diff) | |
download | scala-f475e1a49a406cfe88f4224cb3eb7299d6ec21c0.tar.gz scala-f475e1a49a406cfe88f4224cb3eb7299d6ec21c0.tar.bz2 scala-f475e1a49a406cfe88f4224cb3eb7299d6ec21c0.zip |
- Moved phase AddAccessors before phase Explici...
- Moved phase AddAccessors before phase ExplicitOuter
-rw-r--r-- | sources/scalac/CompilerPhases.java | 12 | ||||
-rw-r--r-- | sources/scalac/transformer/AddAccessorsPhase.java | 25 | ||||
-rw-r--r-- | sources/scalac/transformer/ExplicitOuterClassesPhase.java | 88 |
3 files changed, 100 insertions, 25 deletions
diff --git a/sources/scalac/CompilerPhases.java b/sources/scalac/CompilerPhases.java index 7b6c089ff6..f2989b39bc 100644 --- a/sources/scalac/CompilerPhases.java +++ b/sources/scalac/CompilerPhases.java @@ -29,8 +29,8 @@ public abstract class CompilerPhases { // public final PhaseDescriptor OPTIMIZE; public final PhaseDescriptor TRANSMATCH; public final PhaseDescriptor LAMBDALIFT; - public final PhaseDescriptor EXPLICITOUTER; public final PhaseDescriptor ADDACCESSORS; + public final PhaseDescriptor EXPLICITOUTER; public final PhaseDescriptor ADDCONSTRUCTORS; public final PhaseDescriptor TAILCALL; public final PhaseDescriptor ADDINTERFACES; @@ -116,16 +116,16 @@ public abstract class CompilerPhases { "lambda lifter", "lambda lifting", LAMBDALIFT_PHASE()), - this.EXPLICITOUTER = new PhaseDescriptor( - "explicitouterclasses", - "make links from inner classes to enclosing one explicit", - "made outer links explicit", - EXPLICITOUTER_PHASE()), this.ADDACCESSORS = new PhaseDescriptor( "addaccessors", "add accessors for constructor arguments", "added accessors", ADDACCESSORS_PHASE()), + this.EXPLICITOUTER = new PhaseDescriptor( + "explicitouterclasses", + "make links from inner classes to enclosing one explicit", + "made outer links explicit", + EXPLICITOUTER_PHASE()), this.ADDCONSTRUCTORS = new PhaseDescriptor( "addconstructors", "add explicit constructor for each class", diff --git a/sources/scalac/transformer/AddAccessorsPhase.java b/sources/scalac/transformer/AddAccessorsPhase.java index 9fe48d52e0..c33c405c25 100644 --- a/sources/scalac/transformer/AddAccessorsPhase.java +++ b/sources/scalac/transformer/AddAccessorsPhase.java @@ -59,6 +59,9 @@ public class AddAccessorsPhase extends Phase { /** The parameter to accessor method map */ private final Map/*<Symbol,Symbol>*/ methods = new HashMap(); + /** The current method */ + private Symbol method; + /** Creates an accessor field symbol for given parameter. */ private Symbol createAccessorField(Symbol param) { int flags = Modifiers.PRIVATE | Modifiers.STABLE; @@ -88,8 +91,11 @@ public class AddAccessorsPhase extends Phase { case ClassDef(_, _, _, _, _, Template impl): { Symbol clasz = tree.symbol(); // transform parents and body + Symbol backup = this.method; + this.method = clasz.primaryConstructor(); Tree[] parents = transform(impl.parents); Tree[] body = transform(impl.body); + this.method = backup; // create accessor field & method trees TreeList accessors = new TreeList(); Symbol[] params = clasz.valueParams(); @@ -111,12 +117,19 @@ public class AddAccessorsPhase extends Phase { impl = gen.Template(clasz.pos, impl.symbol(), parents, body); return gen.ClassDef(clasz, impl); } - case Select(Tree qualifier, _): - if (!tree.symbol().owner().isPrimaryConstructor()) break; - qualifier = transform(qualifier); - Symbol method = (Symbol)methods.get(tree.symbol()); - if (method == null) - method = createAccessorMethod(tree.symbol()); + case DefDef(_, _, _, _, _, _): + Symbol backup = this.method; + this.method = tree.symbol(); + tree = super.transform(tree); + this.method = backup; + return tree; + case Ident(_): + Symbol symbol = tree.symbol(); + if (!symbol.owner().isPrimaryConstructor()) break; + if (symbol.owner() == this.method) break; + Symbol method = (Symbol)methods.get(symbol); + if (method == null) method = createAccessorMethod(symbol); + Tree qualifier = gen.This(tree.pos, method.owner()); return gen.Apply(gen.Select(tree.pos, qualifier, method)); } return super.transform(tree); diff --git a/sources/scalac/transformer/ExplicitOuterClassesPhase.java b/sources/scalac/transformer/ExplicitOuterClassesPhase.java index a63d2c2456..caf52ec499 100644 --- a/sources/scalac/transformer/ExplicitOuterClassesPhase.java +++ b/sources/scalac/transformer/ExplicitOuterClassesPhase.java @@ -45,11 +45,15 @@ import scalac.util.Names; * - Adds all missing qualifiers. */ // !!! needs to be cleaned +// !!! create outer fields lazyly public class ExplicitOuterClassesPhase extends Phase { //######################################################################## // Private Fields + /** A map from class symbols to class contexts */ + private final Map/*<Symbol,ClassContext>*/ classes = new HashMap(); + /** A map from constructor symbols to type contexts */ private final Map/*<Symbol,TypeContext>*/ contexts = new HashMap(); @@ -112,6 +116,32 @@ public class ExplicitOuterClassesPhase extends Phase { //######################################################################## // Private Methods + /** Returns the class context for the given symbol. */ + private ClassContext getClassContext(Symbol clasz, TypeContext[] outers) { + assert clasz.isClassType(): Debug.show(clasz); + ClassContext context = (ClassContext)classes.get(clasz); + if (context == null) { + context = createClassContext(clasz, outers); + classes.put(clasz, context); + } + return context; + } + + /** Creates the context for the given class. */ + private ClassContext createClassContext(Symbol clasz, TypeContext[] outers) { + // create outer value link + Symbol vfield = null; + if (outers.length > 0 && (outers[0].vlink != null || !outers[0].isStable)) { + int index = 0; + while (outers[index].isStable) index++; + int vflags = Modifiers.SYNTHETIC | Modifiers.PRIVATE | Modifiers.STABLE; + vfield = clasz.newField(clasz.pos, vflags, Names.OUTER(clasz)); + vfield.setInfo(outers[index].clasz.thisType()); + clasz.members().enter(vfield); + } + return new ClassContext(vfield); + } + /** Returns the type context for the given symbol. */ private TypeContext getTypeContextFor(Symbol symbol) { while (!symbol.isClassType() && !(symbol.isConstructor() && symbol.constructorClass().isClassType())) // !!! isClassType -> isClass ? @@ -154,6 +184,7 @@ public class ExplicitOuterClassesPhase extends Phase { // create outer value link Symbol vlink = null; + ClassContext context = null; if (outers.length > 0 && (outers[0].vlink != null || !outers[0].isStable)) { int index = 0; while (outers[index].isStable) index++; @@ -161,6 +192,7 @@ public class ExplicitOuterClassesPhase extends Phase { Name vname = Names.OUTER(constructor); vlink = constructor.newVParam(constructor.pos, vflags, vname); vlink.setInfo(outers[index].clasz.thisType()); + context = getClassContext(clasz, outers); } // create new type parameters @@ -182,7 +214,7 @@ public class ExplicitOuterClassesPhase extends Phase { tparams.put(oldtparam, newtparam.type()); } - return new TypeContext(clasz, outers, tlinks, vlink, constructor.typeParams(), tparams); + return new TypeContext(clasz, outers, tlinks, vlink, context, constructor.typeParams(), tparams); } @@ -223,6 +255,21 @@ public class ExplicitOuterClassesPhase extends Phase { } //######################################################################## + // Private Class - Class context + + private class ClassContext { + + /** The outer value field (null if all outer contexts are stable) */ + private final Symbol vfield; + + /** !!! */ + public ClassContext(Symbol vfield) { + this.vfield = vfield; + } + + } + + //######################################################################## // Private Class - Type transformer context private class TypeContext { @@ -237,6 +284,8 @@ public class ExplicitOuterClassesPhase extends Phase { private final Symbol[] tlinks; /** The outer value link (null if all outer contexts are stable) */ private final Symbol vlink; + /** !!! */ + private final ClassContext context; /** The old type parameters of the context class */ private Symbol[] oldtparams; @@ -244,12 +293,13 @@ public class ExplicitOuterClassesPhase extends Phase { private TypeTransformer transformer; // !!! type /** !!! */ - public TypeContext(Symbol clasz, TypeContext[] outers, Symbol[] tlinks, Symbol vlink, Symbol[] oldtparams, Map tparams) { + public TypeContext(Symbol clasz, TypeContext[] outers, Symbol[] tlinks, Symbol vlink, ClassContext context, Symbol[] oldtparams, Map tparams) { this.clasz = clasz; this.isStable = clasz.isPackageClass(); this.outers = outers; this.tlinks = tlinks; this.vlink = vlink; + this.context = context; this.oldtparams = oldtparams; this.transformer = new TypeTransformer(this, tparams); } @@ -336,9 +386,6 @@ public class ExplicitOuterClassesPhase extends Phase { /** The current context */ private Context context; - /** True if currently in a method */ - public boolean inMethod; - /** Transforms the given tree. */ public Tree transform(Tree tree) { switch (tree) { @@ -350,6 +397,14 @@ public class ExplicitOuterClassesPhase extends Phase { Tree[] body = transform(impl.body); body = Tree.concat(body, genAccessMethods(false)); body = Tree.concat(body, genAccessMethods(true)); + if (context.context.vlink != null) { + body = Tree.cloneArray(1, body); + body[0] = gen.ValDef( + context.context.context.vfield, + gen.Ident( + context.context.context.vfield.pos, + context.context.vlink)); + } context = context.outer; return gen.ClassDef(clasz, parents, impl.symbol(), body); @@ -358,10 +413,9 @@ public class ExplicitOuterClassesPhase extends Phase { Context backup = context; if (method.isConstructor()) context = context.getConstructorContext(method); - else - inMethod = true; + context.method = method; rhs = transform(rhs); - inMethod = false; + context.method = null; context = backup; return gen.DefDef(method, rhs); @@ -428,7 +482,7 @@ public class ExplicitOuterClassesPhase extends Phase { } if (owner.isPrimaryConstructor()) { Symbol clasz = owner.constructorClass(); - if (clasz != context.clasz || inMethod) { + if (clasz != context.clasz) { Tree qualifier = genOuterRef(tree.pos, clasz); return gen.Select(qualifier, symbol); } @@ -490,6 +544,9 @@ public class ExplicitOuterClassesPhase extends Phase { for (; context != null; context = context.outer) if (svper != null ? context.clasz == svper + : member.isPrivate() + ? context.clasz == member.owner() + // !!! This is incorrect without static access methods : context.clasz.isSubClass(member.owner())) break; assert context != null: Debug.show(this.context, " - ", member); if (context == this.context) return member; @@ -559,9 +616,9 @@ public class ExplicitOuterClassesPhase extends Phase { } else { assert context.context.vlink != null: Debug.show(clasz, " -- ", context.clasz); - Tree tree = inMethod - ? gen.Select(gen.This(pos, context.clasz), context.context.vlink) - : gen.Ident(pos, context.context.vlink); + Tree tree = context.method == null || context.method.isConstructor() + ? gen.Ident(pos, context.context.vlink) + : gen.Select(gen.This(pos, context.clasz), context.context.context.vfield); Context context = this.context; while (true) { context = context.outer; @@ -573,7 +630,9 @@ public class ExplicitOuterClassesPhase extends Phase { Debug.show(clasz, " -- ", this.context.clasz); } if (context.clasz == clasz) return tree; - tree = gen.Select(tree, context.context.vlink); + Symbol access = getAccessSymbol(context.context.context.vfield, null); + assert access != context.context.context.vfield: Debug.show(access) + " - " + Debug.show(this.context.clasz); + tree = gen.Apply(gen.Select(tree, access)); } } } @@ -596,6 +655,9 @@ public class ExplicitOuterClassesPhase extends Phase { public final TypeContext context; + /** !!! The current method */ + public Symbol method; + /** Initializes this instance. */ public Context(Context outer, Symbol symbol, Map selfs, Map supers){ this.context = getTypeContextFor(symbol); |