From 139d9a3f87ad08f379fa774612a40b512c8c94de Mon Sep 17 00:00:00 2001 From: paltherr Date: Mon, 8 Sep 2003 01:12:33 +0000 Subject: - Rewrote ExplicitOuterClassesPhase to add type... - Rewrote ExplicitOuterClassesPhase to add type links for outer tparams --- config/list/compiler.lst | 1 - .../scalac/transformer/ExplicitOuterClasses.java | 295 --------------- .../transformer/ExplicitOuterClassesPhase.java | 421 ++++++++++++++++++--- 3 files changed, 362 insertions(+), 355 deletions(-) delete mode 100644 sources/scalac/transformer/ExplicitOuterClasses.java diff --git a/config/list/compiler.lst b/config/list/compiler.lst index b07277c4ab..d14aa81552 100644 --- a/config/list/compiler.lst +++ b/config/list/compiler.lst @@ -91,7 +91,6 @@ transformer/AddInterfaces.java transformer/AddInterfacesPhase.java transformer/Erasure.java transformer/ErasurePhase.java -transformer/ExplicitOuterClasses.java transformer/ExplicitOuterClassesPhase.java transformer/ExpandMixins.java transformer/ExpandMixinsPhase.java diff --git a/sources/scalac/transformer/ExplicitOuterClasses.java b/sources/scalac/transformer/ExplicitOuterClasses.java deleted file mode 100644 index 6a64127b5c..0000000000 --- a/sources/scalac/transformer/ExplicitOuterClasses.java +++ /dev/null @@ -1,295 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ -// $OldId: ExplicitOuterClasses.java,v 1.22 2002/10/17 12:31:56 schinz Exp $ - -package scalac.transformer; - -import java.util.*; - -import scalac.*; -import scalac.ast.*; -import scalac.util.*; -import scalac.parser.*; -import scalac.symtab.*; -import scalac.typechecker.*; -import Tree.*; - -/** - * Make links from nested classes to their enclosing class explicit. - * - * @author Michel Schinz - * @version 1.0 - */ - -public class ExplicitOuterClasses extends Transformer { - protected final ExplicitOuterClassesPhase phase; - - // Mapping from class constructor symbols to owner field symbols. - protected final HashMap/**/ outerMap; - - public ExplicitOuterClasses(Global global, ExplicitOuterClassesPhase phase) { - super(global); - this.phase = phase; - this.outerMap = phase.outerMap; - } - - protected LinkedList/**/ classStack = new LinkedList(); - protected LinkedList/**/ outerLinks = new LinkedList(); - - /** - * Return the number of outer links to follow to find the given - * symbol. - */ - protected int outerLevel(Symbol sym) { - Iterator classIt = classStack.iterator(); - for (int level = 0; classIt.hasNext(); ++level) { - Symbol classSym = (Symbol)classIt.next(); - if (classSym == sym) - return level; - } - return -1; - } - - /** - * Return a tree referencing the "level"th outer class. - */ - protected Tree outerRef(int level) { - assert level >= 0 : level; - - if (level == 0) { - Symbol thisSym = (Symbol)classStack.getFirst(); - return gen.This(thisSym.pos, thisSym); - } else { - Iterator outerIt = outerLinks.iterator(); - Tree root = gen.Ident((Symbol)outerIt.next()); - - for (int l = 1; l < level; ++l) { - Symbol outerSym = (Symbol)outerIt.next(); - root = gen.mkStable(gen.Select(root, outerSym)); - } - - return root; - } - } - - protected LinkedList/*>*/ superSymsStack = - new LinkedList(); - - protected Symbol outerSuperSym(int level, Symbol funSym) { - assert level > 0 : level; - - HashMap symMap = (HashMap)superSymsStack.get(level); - Symbol outerSuperSym = (Symbol)symMap.get(funSym); - if (outerSuperSym == null) { - Name outerSuperName = - Name.fromString("super$" + funSym.name.toString()); - outerSuperSym = new TermSymbol(funSym.pos, - outerSuperName, - (Symbol)classStack.get(level), - Modifiers.PRIVATE); - - global.log("created forwarding symbol: " + Debug.show(outerSuperSym)); - - outerSuperSym.setInfo(funSym.info().cloneType(funSym, outerSuperSym)); - symMap.put(funSym, outerSuperSym); - } - return outerSuperSym; - } - - public Tree transform(Tree tree) { - switch (tree) { - case ClassDef(int mods, _, _, _, _, _) : { - // Add outer link - ClassDef classDef = (ClassDef) tree; - Symbol classSym = classDef.symbol(); - ValDef[][] newVParams; - - classStack.addFirst(classSym); - superSymsStack.addFirst(new HashMap()); - if (classStack.size() == 1 || Modifiers.Helper.isStatic(mods)) { - outerLinks.addFirst(null); - newVParams = classDef.vparams; - } else { - // Add the outer parameter to the tree (it is added to - // the type by transformInfo). - Symbol constSym = classSym.primaryConstructor(); - Symbol outerSym = phase.outerSym(constSym); - assert (outerSym.owner() == constSym) : outerSym; - outerLinks.addFirst(outerSym); - - ValDef[][] vparams = classDef.vparams; - ValDef[] newVParamsI; - if (vparams.length == 0) - newVParamsI = new ValDef[] { gen.mkParam(outerSym) }; - else { - newVParamsI = new ValDef[vparams[0].length + 1]; - newVParamsI[0] = gen.mkParam(outerSym); - System.arraycopy(vparams[0], 0, newVParamsI, 1, vparams[0].length); - } - newVParams = new ValDef[][] { newVParamsI }; - - classSym.flags |= Modifiers.STATIC; - } - - // Add forwarding "super" methods and add them to the - // class members. - Scope newMembers = new Scope(classSym.members()); - TreeList newBody = new TreeList(transform(classDef.impl.body)); - HashMap/**/ symMap = - (HashMap)superSymsStack.removeFirst(); - Iterator symIt = symMap.entrySet().iterator(); - while (symIt.hasNext()) { - Map.Entry symPair = (Map.Entry)symIt.next(); - Symbol funSym = (Symbol)symPair.getKey(); - Symbol fwdSym = (Symbol)symPair.getValue(); - - Symbol[] argsSym = fwdSym.valueParams(); - Tree[] args = new Tree[argsSym.length]; - for (int i = 0; i < argsSym.length; ++i) - args[i] = gen.mkRef(argsSym[i].pos, argsSym[i]); - Tree fwdBody = - gen.Apply(gen.Select(gen.Super(classSym.pos, classSym), - funSym), - args); - - newBody.append(gen.DefDef(fwdSym, fwdBody)); - newMembers.enter(fwdSym); - } - classSym.updateInfo(Type.compoundType(classSym.parents(), - newMembers, - classSym)); - - Tree[] newParents = transform(classDef.impl.parents); - - outerLinks.removeFirst(); - classStack.removeFirst(); - - return copy.ClassDef(classDef, - classSym, - transform(classDef.tparams), - transform(newVParams), - transform(classDef.tpe), - copy.Template(classDef.impl, - newParents, - newBody.toArray())); - } - - case DefDef(_, _, _, _, _, Tree rhs): { - Symbol sym = tree.symbol(); - if (sym.isConstructor()) { - // Temporarily set the outer link to the one passed to - // that constructor, to transform RHS. - Symbol mainOuterLink = (Symbol)outerLinks.removeFirst(); - outerLinks.addFirst(phase.outerSym(sym)); - Tree newRhs = transform(rhs); - outerLinks.removeFirst(); - outerLinks.addFirst(mainOuterLink); - - return gen.DefDef(tree.pos, sym, newRhs); - } else - return super.transform(tree); - } - - case Ident(_): { - if (! tree.symbol().name.isTermName()) - return super.transform(tree); - - // Follow "outer" links to fetch data in outer classes. - int level = outerLevel(tree.symbol().classOwner()); - if (level > 0) { - Tree root = outerRef(level); - return gen.mkStable(gen.Select(root, tree.symbol())); - } else { - return super.transform(tree); - } - } - - case This(_): { - // If "this" refers to some outer class, replace it by - // explicit reference to it. - int level = outerLevel(tree.symbol()); - if (level > 0) - return outerRef(level); - else - return super.transform(tree); - } - - case Select(Super(_, _), Name selector): { - // If "super" refers to an outer class, access the value - // (a method) through outer link(s). - int level = outerLevel(((Select)tree).qualifier.symbol()); - if (level > 0) - return gen.Select(outerRef(level), - outerSuperSym(level, tree.symbol())); - else - return super.transform(tree); - } - - case Apply(Tree fun, Tree[] args): { - // Add outer parameter to constructor calls. - Tree realFun; - Tree[] typeArgs; - - switch (fun) { - case TypeApply(Tree fun2, Tree[] tArgs): - realFun = fun2; typeArgs = tArgs; break; - default: - realFun = fun; typeArgs = null; break; - } - - Tree newFun = null, newArg = null; - - if (realFun.hasSymbol() && realFun.symbol().isConstructor()) { - switch (transform(realFun)) { - case Select(Tree qualifier, _): { - if (! (qualifier.hasSymbol() - && Modifiers.Helper.isNoVal(qualifier.symbol().flags))) { - newFun = make.Ident(qualifier.pos, realFun.symbol()) - .setType(realFun.type()); - newArg = qualifier; - } - } break; - - case Ident(_): { - int level = outerLevel(realFun.symbol().owner()); - if (level >= 0) { - newFun = realFun; - newArg = outerRef(level); - } - } break; - - default: - throw global.fail("unexpected node in constructor call"); - } - - if (newFun != null && newArg != null) { - Tree[] newArgs = new Tree[args.length + 1]; - newArgs[0] = newArg; - System.arraycopy(args, 0, newArgs, 1, args.length); - - Tree finalFun; - if (typeArgs != null) - finalFun = copy.TypeApply(fun, newFun, typeArgs); - else - finalFun = newFun; - - finalFun.type = - phase.addOuterValueParam(finalFun.type, realFun.symbol()); - return copy.Apply(tree, finalFun, transform(newArgs)); - } else - return super.transform(tree); - - } else - return super.transform(tree); - } - - default: - return super.transform(tree); - } - } -} diff --git a/sources/scalac/transformer/ExplicitOuterClassesPhase.java b/sources/scalac/transformer/ExplicitOuterClassesPhase.java index 2819c14ef7..590502f35c 100644 --- a/sources/scalac/transformer/ExplicitOuterClassesPhase.java +++ b/sources/scalac/transformer/ExplicitOuterClassesPhase.java @@ -5,94 +5,397 @@ \* */ // $Id$ -// $OldId: ExplicitOuterClassesPhase.java,v 1.8 2002/08/21 14:08:18 paltherr Exp $ package scalac.transformer; -import scalac.*; -import scalac.checkers.*; -import scalac.symtab.*; -import scalac.util.*; +import java.util.Map; import java.util.HashMap; +import java.util.Iterator; +import scalac.Global; +import scalac.Phase; +import scalac.PhaseDescriptor; +import scalac.Unit; +import scalac.ast.Transformer; +import scalac.ast.Tree; +import scalac.ast.Tree.Template; +import scalac.symtab.Modifiers; +import scalac.symtab.Symbol; +import scalac.symtab.TermSymbol; +import scalac.symtab.Type; +import scalac.util.Debug; +import scalac.util.Name; +import scalac.util.Names; + +/** + * This phase does the following: + * + * - In every nested class, adds to each of its constructor a new + * value parameter that contains a link to the outer class. + * + * - In every nested class, adds to each of its constructor a new type + * parameter for every type parameter appearing in outer classes. + * + * - In every class, adds a forwarding "super" method for every method + * that is accessed via "super" in a nested class. + * + * - Adds all missing qualifiers. + */ public class ExplicitOuterClassesPhase extends Phase { - // Mapping from class constructor symbols to owner field symbols. - protected final HashMap/**/ outerMap = new HashMap(); + + //######################################################################## + // Public Constructors /** Initializes this instance. */ public ExplicitOuterClassesPhase(Global global,PhaseDescriptor descriptor){ super(global, descriptor); } + //######################################################################## + // Public Methods + + /** Applies this phase to the given type for the given symbol. */ + public Type transformInfo(Symbol symbol, Type type) { + if (symbol.isJava() || symbol == Symbol.NONE) return type; + //System.out.println("!!! debug1 = " + Debug.show(symbol)); + //if (symbol.name.toString().equals("x")) new Error("!!!").printStackTrace(); + type = typeTransformer.apply(type); + if (symbol.isConstructor() && !symbol.isOverloaded()) { + Symbol[] tparams = type.typeParams(); + Symbol[] vparams = type.valueParams(); + Type result = type.resultType(); + // Add outer value link + if (hasOuterValueLink(symbol)) { + Name name = Names.OUTER(symbol); + Symbol vlink = new TermSymbol(symbol.pos, name, symbol, 0); + vlink.setInfo(getOuterClass(symbol).typeOfThis()); // !!! + vparams = Symbol.cloneArray(1, vparams); + vparams[0] = vlink; + } + // Add outer type links + if (hasOuterTypeLinks(symbol)) { + Symbol[] oldtparams = nextTypeParams(getOuterClass(symbol)); + Symbol[] tlinks = Symbol.cloneArray(oldtparams); + for (int i = 0; i < tlinks.length; i++) { + tlinks[i] = oldtparams[i].cloneSymbol(symbol); + tlinks[i].name = Names.OUTER(symbol, oldtparams[i]); + } + tparams = Symbol.concat(tlinks, tparams); + result = Type.getSubst(oldtparams, tlinks, true).apply(result); + } + type = Type.MethodType(vparams, result); + if (tparams.length != 0) type = Type.PolyType(tparams, type); + } else { + Symbol owner = symbol.isConstructor() + ? symbol.constructorClass() + : symbol.owner().isConstructor() + ? symbol.owner() + : symbol.enclClass(); + //System.out.println("!!! debug2 = " + Debug.show(symbol) + " - " + Debug.show(owner) + " --- " + (owner == Symbol.NONE) + " -- #" + owner.name + "#"); + //if (onwer.isJava() && owner != Symbol.NONE && owner.name.length() > 0) // !!! + if (owner.isClass() || owner.isConstructor()) + type = getOuterTypeSubst(owner, true).apply(type); + } + + /* + + String s1 = Debug.show(symbol); + String s2 = symbol.info().toString(); + //global.nextPhase(); + String s3 = type.toString(); + //global.prevPhase(); + System.out.println("!!! symbol = " + s1); + System.out.println("!!! type = " + s2 + " -- " + System.identityHashCode(s2)); + System.out.println("!!! new = " + s3 + " -- " + System.identityHashCode(s3)); + System.out.println("!!!"); + + */ + + return type; + } + /** Applies this phase to the given compilation units. */ public void apply(Unit[] units) { - for (int i = 0; i < units.length; i++) - new ExplicitOuterClasses(global, this).apply(units[i]); + treeTransformer.apply(units); } - public Checker[] postCheckers(Global global) { - return new Checker[] { - new CheckSymbols(global), - new CheckTypes(global), - new CheckOwners(global), - new CheckNames(global) - }; + //######################################################################## + // Private Methods - Outer class + + /** Returns the outer class of the given class or constructor. */ + private Symbol getOuterClass(Symbol symbol) { + assert symbol.isClass() || symbol.isConstructor(): Debug.show(symbol); + return symbol.owner(); } - public Type transformInfo(Symbol sym, Type tp) { - if (sym != Symbol.NONE - && sym.isConstructor() - && sym.owner().isClass() - && !(sym.isJava() || sym.owner().isRoot())) { - return addOuterValueParam(tp, sym); - } else - return tp; + /** Has the given class or constructor an outer value link? */ + private boolean hasOuterValueLink(Symbol symbol) { + assert symbol.isClass() || symbol.isConstructor(): Debug.show(symbol); + return !symbol.isJava() && getOuterClass(symbol).isClass(); } - /** - * Return the symbol for the outer parameter corresponding to the - * given constructor. - */ - protected Symbol outerSym(Symbol constSym) { - if (! outerMap.containsKey(constSym)) { - Symbol ownerSym = constSym.enclClass(); - Name outerName = - Global.instance.freshNameCreator.newName(Names.OUTER_PREFIX); - Symbol outerSym = - new TermSymbol(constSym.pos, outerName, constSym, 0); - outerSym.setInfo(ownerSym.type()); - - outerMap.put(constSym, outerSym); - } - return (Symbol)outerMap.get(constSym); + /** Returns the outer link of the given class or constructor. */ + private Symbol getOuterValueLink(Symbol symbol) { + if (!hasOuterValueLink(symbol)) return Symbol.NONE; + if (symbol.isClass()) symbol = symbol.primaryConstructor(); + return nextValueParams(symbol)[0]; + } + + /** Has the given class or constructor outer type links? */ + private boolean hasOuterTypeLinks(Symbol symbol) { + assert symbol.isClass() || symbol.isConstructor(): Debug.show(symbol); + if (symbol.isJava()) return false; + Symbol outer = getOuterClass(symbol); + return outer.isClass() && nextTypeParams(outer).length != 0; + } + + /** Returns the type substitution for the given class or constructor. */ + private Type.Map getOuterTypeSubst(Symbol symbol, boolean update) { + if (!hasOuterTypeLinks(symbol)) return Type.IdMap; + Symbol[] oldtparams = nextTypeParams(getOuterClass(symbol)); + Symbol[] newtparams = nextTypeParams(symbol); + Symbol[] tlinks = new Symbol[oldtparams.length]; + for (int i = 0; i < tlinks.length; i++) tlinks[i] = newtparams[i]; + return Type.getSubst(oldtparams, tlinks, update); } /** - * Add the given value parameter to the type, which must be the - * type of a method, as the first argument. + * Extracts from given prefix the outer type arguments for the + * given class or constructor. */ - protected Type addOuterValueParam(Type oldType, Symbol constr) { - switch (oldType) { - case MethodType(Symbol[] vparams, Type result): { - Symbol[] newVParams = new Symbol[vparams.length + 1]; - newVParams[0] = outerSym(constr); - System.arraycopy(vparams, 0, newVParams, 1, vparams.length); - return new Type.MethodType(newVParams, result); + private Type[] getOuterTypeArgs(Type prefix, Symbol symbol) { + if (!hasOuterTypeLinks(symbol)) return Type.EMPTY_ARRAY; + Symbol outer = getOuterClass(symbol); + global.nextPhase(); + Type[] targs = prefix.baseType(outer).widen().typeArgs(); + global.prevPhase(); + assert targs.length == nextTypeParams(outer).length: + "\nsymbol = " + Debug.show(symbol) + + "\nprefix = " + prefix; + return targs; + } + + //######################################################################## + // Private Methods - Helper methods + + /** Returns the given symbol's type parameters in next phase. */ + private Symbol[] nextTypeParams(Symbol symbol) { + global.nextPhase(); + Symbol[] tparams = symbol.typeParams(); + global.prevPhase(); + return tparams; + } + + /** Returns the given symbol's value parameters in next phase. */ + private Symbol[] nextValueParams(Symbol symbol) { + global.nextPhase(); + Symbol[] vparams = symbol.valueParams(); + global.prevPhase(); + return vparams; + } + + //######################################################################## + // Private Class - Type transformer + + /** The type transformer */ + private final Type.Map typeTransformer = new Type.MapOnlyTypes() { + public Type apply(Type type) { + switch (type) { + case TypeRef(Type prefix, Symbol symbol, Type[] targs): + if (!symbol.isClass()) break; + prefix = apply(prefix); + targs = Type.concat(getOuterTypeArgs(prefix, symbol), targs); + return Type.TypeRef(prefix, symbol, targs); + } + return map(type); } + }; - case PolyType(Symbol[] tparams, Type result): - return new Type.PolyType(tparams, - addOuterValueParam(result, constr)); + //######################################################################## + // Private Class - Tree transformer - case OverloadedType(Symbol[] alts, Type[] altTypes): { - Type[] newAltTypes = new Type[altTypes.length]; - for (int i = 0; i < newAltTypes.length; ++i) - newAltTypes[i] = addOuterValueParam(altTypes[i], alts[i]); - return new Type.OverloadedType(alts, newAltTypes); + /** The tree transformer */ + private final Transformer treeTransformer = new Transformer(global) { + + /** The current context */ + private Context context; + + /** Transforms the given tree. */ + public Tree transform(Tree tree) { + switch (tree) { + + case ClassDef(_, _, _, _, _, Template impl): + Symbol clasz = tree.symbol(); + context = new Context(context, clasz, new HashMap()); + Tree[] parents = transform(impl.parents); + Tree[] members = transform(impl.body); + members = Tree.concat(members, genSuperMethods()); + context = context.outer; + if (context != null) clasz.flags |= Modifiers.STATIC; + return gen.ClassDef(clasz, parents, impl.symbol(), members); + + case DefDef(_, _, _, _, _, Tree rhs): + Symbol symbol = tree.symbol(); + if (!symbol.isConstructor()) break; + Context backup = context; + context = context.getConstructorContext(symbol); + rhs = transform(rhs); + context = backup; + return gen.DefDef(tree.pos, symbol, rhs); + + case This(_): + return genOuterRef(tree.pos, tree.symbol()); + + 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.mkStable(gen.Select(qualifier, symbol)); + } + if (!owner.isConstructor()) break; + Symbol clasz = owner.constructorClass(); + if (clasz == context.clasz) break; + Tree qualifier = genOuterRef(tree.pos, clasz); + return gen.mkStable(gen.Select(qualifier, symbol)); + + case Select(Super(_, _), _): + Tree qualifier = ((Tree.Select)tree).qualifier; + Symbol clasz = qualifier.symbol(); + if (clasz == context.clasz) break; + Symbol symbol = getSuperMethod(clasz, tree.symbol()); + qualifier = genOuterRef(qualifier.pos, clasz); + return gen.mkStable(gen.Select(tree.pos, qualifier, symbol)); + + case Apply(Tree vfun, Tree[] vargs): + switch (vfun) { + case TypeApply(Tree tfun, Tree[] targs): + if (!tfun.symbol().isConstructor()) break; + return transform(tree, vargs, vfun, targs, tfun); + default: + if (!vfun.symbol().isConstructor()) break; + return transform(tree, vargs, vfun, Tree.EMPTY_ARRAY,vfun); + } + } + + Type type = typeTransformer.apply(tree.type()); + if (context != null) type = context.subst.apply(type); + return super.transform(tree).setType(type); + } + + /* Add outer type and value arguments to constructor calls. */ + private Tree transform(Tree vapply, Tree[] vargs, Tree tapply, + Tree[] targs, Tree tree) + { + Symbol symbol = tree.symbol(); + targs = transform(targs); + vargs = transform(vargs); + switch (transform(tree)) { + case Select(Tree qualifier, _): + if (hasOuterValueLink(symbol)) { + vargs = Tree.cloneArray(1, vargs); + vargs[0] = qualifier; + } + Type[] types = getOuterTypeArgs(qualifier.type(), symbol); + if (types.length != 0) { + targs = Tree.cloneArray(types.length, targs); + for (int i = 0; i < types.length; i++) + targs[i] = gen.mkType(tapply.pos, types[i]); + } + } + tree = gen.Ident(tree.pos, symbol); + if (targs.length != 0) tree = gen.TypeApply(tapply.pos,tree,targs); + return gen.Apply(vapply.pos, tree, vargs); + } + + /** + * Returns the forwarding "super" method of the given class + * that invokes the given method. If the symbol does not yet + * exist, it is created and added to the class members. + */ + private Symbol getSuperMethod(Symbol clasz, Symbol method) { + Context context = this.context; + for (; context.clasz != clasz; context = context.outer) + assert context.outer != null : Debug.show(clasz); + Symbol forward = (Symbol)context.supers.get(method); + if (forward == null) { + Name name = Names.SUPER(method); + int flags = Modifiers.PRIVATE | Modifiers.FINAL; + forward = new TermSymbol(method.pos, name, clasz, flags); + forward.setInfo(method.nextType().cloneType(method, forward)); + context.supers.put(method, forward); + clasz.nextInfo().members().enter(forward); + assert Debug.log("created forwarding method: ", forward); + } + return forward; } - default: - throw Global.instance.fail("invalid type", oldType); + /** Generates the trees of the forwarding "super" methods. */ + private Tree[] genSuperMethods() { + if (context.supers.size() == 0) return Tree.EMPTY_ARRAY; + Tree[] trees = new Tree[context.supers.size()]; + Iterator entries = context.supers.entrySet().iterator(); + for (int i = 0; i < trees.length; i++) { + Map.Entry entry = (Map.Entry)entries.next(); + Symbol method = (Symbol)entry.getKey(); + Symbol forward = (Symbol)entry.getValue(); + int pos = forward.pos; + Tree[] targs = gen.mkTypeIdents(pos, nextTypeParams(forward)); + Tree[] vargs = gen.mkIdents(pos, nextValueParams(forward)); + Tree fun = gen.Select(gen.Super(pos, context.clasz), method); + trees[i] = gen.DefDef(forward, gen.mkApply(fun, targs, vargs)); + } + return trees; } + + /** Returns a tree referencing the given outer class. */ + private Tree genOuterRef(int pos, Symbol clasz) { + if (context.clasz == clasz) return gen.This(pos, clasz); + Tree tree = gen.mkStable(gen.Ident(pos, context.link)); + for (Context context = this.context.outer;;context =context.outer){ + assert context != null: Debug.show(clasz); + if (context.clasz == clasz) return tree; + tree = gen.mkStable(gen.Select(tree, context.link)); + } + } + + }; + + //######################################################################## + // Private Class - Tree transformer context + + /** This class represents the tree transformation context. */ + private class Context { + + /** The outer context */ + public final Context outer; + /** The class symbol */ + public final Symbol clasz; + /** The super methods (maps invoked to forwarding methods) */ + public final Map/**/ supers; + /** The outer type parameter substitution */ + public final Type.Map subst; + /** The link to the outer class */ + public final Symbol link; + + /** Initializes this instance. */ + public Context(Context outer, Symbol symbol, Map supers) { + this.outer = outer; + this.clasz = symbol.constructorClass(); + this.supers = supers; + this.subst = getOuterTypeSubst(symbol, false); + this.link = getOuterValueLink(symbol); + } + + /** Returns a context for the given constructor. */ + public Context getConstructorContext(Symbol constructor) { + assert constructor.constructorClass() == clasz; + return new Context(outer, constructor, supers); + } + } + + //######################################################################## } -- cgit v1.2.3