diff options
author | paltherr <paltherr@epfl.ch> | 2004-08-31 12:23:42 +0000 |
---|---|---|
committer | paltherr <paltherr@epfl.ch> | 2004-08-31 12:23:42 +0000 |
commit | 84a4f81380ba66a577c159a30053db08dfe22125 (patch) | |
tree | bddafce6a27e961cd6ee5e1757764cef305f9b30 | |
parent | 09415a6af5f94a1f1ee919e81e28fade7ffdb559 (diff) | |
download | scala-84a4f81380ba66a577c159a30053db08dfe22125.tar.gz scala-84a4f81380ba66a577c159a30053db08dfe22125.tar.bz2 scala-84a4f81380ba66a577c159a30053db08dfe22125.zip |
- Removed type contexts
-rw-r--r-- | sources/scalac/transformer/ExplicitOuterClassesPhase.java | 301 |
1 files changed, 109 insertions, 192 deletions
diff --git a/sources/scalac/transformer/ExplicitOuterClassesPhase.java b/sources/scalac/transformer/ExplicitOuterClassesPhase.java index 213b165c55..cec8becc1b 100644 --- a/sources/scalac/transformer/ExplicitOuterClassesPhase.java +++ b/sources/scalac/transformer/ExplicitOuterClassesPhase.java @@ -51,8 +51,8 @@ public class ExplicitOuterClassesPhase extends Phase { //######################################################################## // Private Fields - /** A map from constructor symbols to type contexts */ - private final Map/*<Symbol,TypeContext>*/ contexts = new HashMap(); + /** A map from constructor symbols to type transformers */ + private final Map/*<Symbol,TypeTransformer>*/ transformers = new HashMap(); //######################################################################## // Public Constructors @@ -70,53 +70,87 @@ public class ExplicitOuterClassesPhase extends Phase { treeTransformer.apply(units); } - private boolean show = false; // !!! - /** Applies this phase to the given type for the given symbol. */ public Type transformInfo(Symbol symbol, Type type) { - if (show && !symbol.isPackageClass()) System.out.println("!!! <<< transformInfo - symbol: " + Debug.show(symbol)); - if (show && !symbol.isPackageClass()) System.out.println("!!! <<< transformInfo - type : " + Debug.show(type)); - if (symbol.isPackage()) return type; // !!! - if (symbol.isPackageClass()) return type; // !!! - if (symbol.isConstructor() && symbol.constructorClass().isPackageClass()) return type; // !!! - TypeContext context = getTypeContextFor(symbol); - if (symbol.isConstructor() && symbol.constructorClass().isClassType() && !symbol.constructorClass().isCompoundSym()) { // !!! isClassType -> isClass ? + if (symbol.isConstructor()) { Symbol clasz = symbol.constructorClass(); - Symbol[] tparams = type.typeParams(); - Symbol[] vparams = type.valueParams(); - Type result = type.resultType(); - result = context.transformer.apply(result); - if (context.vlink != null) { - vparams = Symbol.cloneArray(1, vparams); - vparams[0] = context.vlink; - } - Type prefix = clasz.owner().thisType(); - Type[] args = Symbol.type(tparams); - // !!! use getNewTypeArgs ? - Type self = Type.typeRef(prefix, clasz, args); - Type s = self; - self = context.transformer.apply(self); - tparams = Type.symbol(self.typeArgs()); - for (int i = 0; i < tparams.length; i++) - assert tparams[i].isParameter() && tparams[i].owner() == symbol: - Debug.show(symbol, clasz, self); - type = Type.MethodType(vparams, result); - if (tparams.length != 0) type = Type.PolyType(tparams, type); - } else { - Type t = type; - type = context.transformer.apply(type); - assert type != null: Debug.show(symbol) + " -- " + t; + if (clasz.isClass() && !clasz.isCompoundSym()) + return transformInfo(clasz, symbol, type); } - if (show && !symbol.isPackageClass()) System.out.println("!!! >>> transformInfo - symbol: " + Debug.show(symbol)); - if (show && !symbol.isPackageClass()) System.out.println("!!! >>> transformInfo - type : " + Debug.show(type)); - return type; + return getTypeTransformerFor(symbol).apply(type); } //######################################################################## // Private Methods - /** Returns the type context for the given symbol. */ - private TypeContext getTypeContextFor(Symbol symbol) { + /** + * Computes and returns the new type of the constructor. As a side + * effect, creates and stores the type transformer corresponding + * to this constructor. + */ + private Type transformInfo(Symbol clasz, Symbol constructor, Type type) { + Symbol[] tparams = type.typeParams(); + Symbol[] vparams = type.valueParams(); + int depth = getClassDepth(clasz); + + Map/*<Symbol,Type>*/ table = new HashMap(); + table.put(clasz, clasz.thisType()); + for (int i = 0; i < tparams.length; i++) + table.put(tparams[i], tparams[i].type()); + + Symbol[] owners = new Symbol[depth]; + Symbol[][] tparamss = new Symbol[depth][]; + + Symbol vlink = null; + if (depth > 0) { + int count = depth; + Symbol owner = clasz.owner(); + for (int i = depth - 1; i >= 0; i--) { + owners[i] = owner; + tparamss[i] = owner.typeParams(); + count += tparamss[i].length; + owner = owner.owner(); + } + + // create outer value link + vparams = Symbol.cloneArray(1, vparams); + int vflags = Modifiers.SYNTHETIC; + Name vname = Names.OUTER(constructor); + vlink = constructor.newVParam(constructor.pos, vflags, vname); + vlink.setInfo(clasz.owner().thisType()); + vparams[0] = vlink; + + int o = 0; + tparams = Symbol.cloneArray(count, tparams); + for (int i = 0; i < depth; i++) { + // create new type parameters + for (int j = 0; j < tparamss[i].length; j++) { + Symbol oldtparam = tparamss[i][j]; + Symbol newtparam = oldtparam.cloneSymbol(constructor); + newtparam.name = Names.OUTER(constructor, oldtparam); + table.put(oldtparam, newtparam.type()); + tparams[o++] = newtparam; + } + // create outer type links + int tflags = Modifiers.PARAM | Modifiers.COVARIANT | Modifiers.SYNTHETIC | Modifiers.STABLE; + Name tname = Names.OUTER(constructor, owners[i]); + Symbol tlink = constructor.newTParam( + constructor.pos, tflags, tname, owners[i].typeOfThis()); + table.put(owners[i], tlink.type()); + tparams[o++] = tlink; + } + + } + + transformers.put(constructor, new TypeTransformer(table)); + type = Type.typeRef(Type.NoPrefix, clasz, Symbol.type(tparams)); + type = Type.MethodType(vparams, type); + if (tparams.length > 0) type = Type.PolyType(tparams, type); + return type; + } + + /** Returns the type transformer for the given symbol. */ + private TypeTransformer getTypeTransformerFor(Symbol symbol) { while (true) { Symbol test = symbol; if (test.isConstructor()) test = test.constructorClass(); @@ -129,66 +163,17 @@ public class ExplicitOuterClassesPhase extends Phase { // symbol = symbol.owner(); if (symbol.isClassType()) symbol = symbol.primaryConstructor(); - if (symbol.constructorClass().isPackageClass()) return new TypeContext(null, null, null, Collections.EMPTY_MAP); // !!! - TypeContext context = (TypeContext)contexts.get(symbol); + if (symbol.constructorClass().isPackageClass()) + return topLevelTypeTransformer; + TypeTransformer context = (TypeTransformer)transformers.get(symbol); if (context == null) { - context = createTypeContext(symbol); - contexts.put(symbol, context); + symbol.nextInfo(); + context = (TypeTransformer)transformers.get(symbol); + assert context != null: Debug.show(symbol); } return context; } - /** Creates the context for the given constructor. */ - private TypeContext createTypeContext(Symbol constructor) { - Symbol clasz = constructor.constructorClass(); - - Map/*<Symbol,Type>*/ tparams = new HashMap(); - tparams.put(clasz, Type.ThisType(clasz)); - - // get outer contexts - TypeContext outer = clasz.owner().isPackageClass() - ? null - : getTypeContextFor(clasz.owner()); - - // create outer type links - int tflags = Modifiers.PARAM | Modifiers.COVARIANT | Modifiers.SYNTHETIC | Modifiers.STABLE; - for (TypeContext o = outer; o != null; o = o.outer) { - Name tname = Names.OUTER(constructor, o.clasz); - Symbol tlink = constructor.newTParam( - constructor.pos, tflags, tname, o.clasz.typeOfThis()); - tparams.put(o.clasz, tlink.type()); - } - - // create outer value link - Symbol vlink = null; - if (outer != null) { - int vflags = Modifiers.SYNTHETIC; - Name vname = Names.OUTER(constructor); - vlink = constructor.newVParam(constructor.pos, vflags, vname); - vlink.setInfo(outer.clasz.thisType()); - } - - // create new type parameters - for (TypeContext o = outer; o != null; o = o.outer) { - Symbol[] oldtparams = o.clasz.typeParams(); - for (int i = 0; i < oldtparams.length; i++) { - Symbol oldtparam = oldtparams[i]; - Symbol newtparam = oldtparam.cloneSymbol(constructor); - newtparam.name = Names.OUTER(constructor, oldtparam); - tparams.put(oldtparam, newtparam.type()); - } - } - // !!! duplicated code - Symbol[] oldtparams = constructor.typeParams(); - for (int i = 0; i < oldtparams.length; i++) { - Symbol oldtparam = oldtparams[i]; - Symbol newtparam = oldtparam; - tparams.put(oldtparam, newtparam.type()); - } - - return new TypeContext(clasz, outer, vlink, tparams); - } - //######################################################################## // Private Functions @@ -206,13 +191,6 @@ public class ExplicitOuterClassesPhase extends Phase { return depth; } - /** Tests whether the class is enclosed in the specified class. */ - private static boolean isEnclosedIn(Symbol clasz, Symbol outer) { - for (; !clasz.isRoot(); clasz = clasz.owner()) - if (clasz == outer) return true; - return false; - } - /** * Returns the type arguments of the flattened version of the * specified type reference. This functions takes and returns @@ -257,42 +235,12 @@ public class ExplicitOuterClassesPhase extends Phase { } //######################################################################## - // Private Class - Type transformer context - - private class TypeContext { - - /** The context class */ - private final Symbol clasz; - /** The outer context */ - private final TypeContext outer; - /** The outer value link (null if all outer contexts are stable) */ - private final Symbol vlink; - - - /** !!! */ - private TypeTransformer transformer; // !!! type - - /** !!! */ - public TypeContext(Symbol clasz, TypeContext outer, Symbol vlink, Map tparams) { - this.clasz = clasz; - this.outer = outer; - this.vlink = vlink; - this.transformer = new TypeTransformer(tparams); - } - - public String toString() { - return - "\nclasz = " + Debug.show(clasz) + - "\nvlink = " + Debug.show(vlink) + - "\ntparams = " + Debug.show(transformer.tparams) + - "\nouter : " + "\n" + outer; - } - - } - - //######################################################################## // Private Class - Type transformer + /** The type transformer for top-level types */ + private static final TypeTransformer topLevelTypeTransformer = + new TypeTransformer(Collections.EMPTY_MAP); + /** The type transformer */ private static final class TypeTransformer extends Type.MapOnlyTypes { @@ -351,9 +299,12 @@ public class ExplicitOuterClassesPhase extends Phase { /** The current context */ private Context context; + /** The current method */ + private Symbol method; + /** Transforms the given type. */ public Type transform(Type type) { - return context.context.transformer.apply(type); + return context.transformer.apply(type); } /** Transforms the given tree. */ @@ -371,7 +322,7 @@ public class ExplicitOuterClassesPhase extends Phase { body = Tree.cloneArray(1, body); body[0] = gen.ValDef( context.vfield, - gen.Ident(context.vfield.pos, context.context.vlink)); + gen.Ident(context.vfield.pos, context.vparam)); } context = context.outer; return gen.ClassDef(clasz, parents, impl.symbol(), body); @@ -381,9 +332,9 @@ public class ExplicitOuterClassesPhase extends Phase { Context backup = context; if (method.isConstructor()) context = context.getConstructorContext(method); - context.method = method; + this.method = method; rhs = transform(rhs); - context.method = null; + this.method = null; context = backup; return gen.DefDef(method, rhs); @@ -410,8 +361,6 @@ public class ExplicitOuterClassesPhase extends Phase { case This(_): return genOuterRef(tree.pos, tree.symbol()); -// Symbol clasz = tree.symbol(); -// return clasz.isRoot() ? tree : genOuterRef(tree.pos, clasz); case Select(Tree qualifier, _): Symbol symbol = tree.symbol(); @@ -439,24 +388,6 @@ public class ExplicitOuterClassesPhase extends Phase { tree = gen.mkApply__(tree); return tree; - case Ident(_): - Symbol symbol = tree.symbol(); - Symbol owner = symbol.owner(); - if (owner.isClass()) { - // !!! A this node is missing here. This should - // never happen if all trees were correct. - Tree qualifier = genOuterRef(tree.pos, owner); - return gen.Select(qualifier, symbol); - } - if (owner.isPrimaryConstructor()) { - Symbol clasz = owner.constructorClass(); - if (clasz != context.clasz) { - Tree qualifier = genOuterRef(tree.pos, clasz); - return gen.Select(qualifier, symbol); - } - } - return gen.Ident(tree.pos, symbol); - default: return super.transform(tree); } @@ -553,27 +484,14 @@ public class ExplicitOuterClassesPhase extends Phase { /** Returns a tree referencing the given outer class. */ private Tree genOuterRef(int pos, Symbol clasz) { if (context.clasz == clasz) return gen.This(pos, clasz); - TypeContext tcontext = null; - for (TypeContext o = context.context; o != null; o = o.outer) - if (o.clasz == clasz) - tcontext = o; - assert tcontext != null: Debug.show(clasz, context.clasz); - { // !!! - assert context.context.vlink != null: - Debug.show(clasz, context.clasz); - Tree tree = context.method == null || context.method.isConstructor() - ? gen.Ident(pos, context.context.vlink) - : gen.Select(gen.This(pos, context.clasz), context.getVField()); - Context context = this.context; - while (true) { - context = context.outer; - assert context != null: - Debug.show(clasz, this.context.clasz); - if (context.clasz == clasz) return tree; - Symbol access = getAccessSymbol(context.getVField(), null); - assert access != context.getVField(): Debug.show(access) + " - " + Debug.show(this.context.clasz); - tree = gen.Apply(gen.Select(tree, access)); - } + Tree tree = method == null || method.isConstructor() + ? gen.Ident(pos, context.vparam) + : gen.Select(gen.This(pos, context.clasz),context.getVField()); + for (Context c = context.outer;; c = c.outer) { + assert c != null: Debug.show(clasz, context.clasz); + if (c.clasz == clasz) return tree; + Symbol access = getAccessSymbol(c.getVField(), null); + tree = gen.Apply(gen.Select(tree, access)); } } @@ -599,29 +517,27 @@ public class ExplicitOuterClassesPhase extends Phase { /** The outer context */ public final Context outer; - /** The current class symbol */ + /** The context class */ public final Symbol clasz; + /** The context type transformer */ + public final TypeTransformer transformer; /** The self access methods (maps members to accessors) */ public final Map/*<Symbol,Symbol>*/ selfs; /** The super access methods (maps members to accessors) */ public final Map/*<Symbol,Symbol>*/ supers; - - // !!! - public final TypeContext context; - - /** The outer value field (null if not yet created) */ + /** The context outer paramater (null if none) */ + public final Symbol vparam; + /** The context outer field (null if none or not yet used) */ private Symbol vfield; - /** !!! The current method */ - public Symbol method; - /** Initializes this instance. */ - public Context(Context outer, Symbol symbol, Map selfs, Map supers){ - this.context = getTypeContextFor(symbol); + public Context(Context outer, Symbol symbol, Map selfs, Map supers) { this.outer = outer; this.clasz = symbol.constructorClass(); + this.transformer = getTypeTransformerFor(symbol); this.selfs = selfs; this.supers = supers; + this.vparam = outer != null ? symbol.nextValueParams()[0] : null; } /** Returns a context for the given constructor. */ @@ -635,6 +551,7 @@ public class ExplicitOuterClassesPhase extends Phase { * fly if it does not yet exist. */ private Symbol getVField() { + assert outer != null: Debug.show(clasz); if (vfield == null) { int flags = Modifiers.SYNTHETIC | Modifiers.PRIVATE | Modifiers.STABLE; |