summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpaltherr <paltherr@epfl.ch>2004-05-13 13:13:54 +0000
committerpaltherr <paltherr@epfl.ch>2004-05-13 13:13:54 +0000
commitf475e1a49a406cfe88f4224cb3eb7299d6ec21c0 (patch)
treee47ca57162f6809a98cb764058896c3b7c693143
parenta405a10c05aa36eeb2d904382d05bb429cca9bea (diff)
downloadscala-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.java12
-rw-r--r--sources/scalac/transformer/AddAccessorsPhase.java25
-rw-r--r--sources/scalac/transformer/ExplicitOuterClassesPhase.java88
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);