diff options
Diffstat (limited to 'sources/scalac/transformer/AddInterfaces.java')
-rw-r--r-- | sources/scalac/transformer/AddInterfaces.java | 304 |
1 files changed, 0 insertions, 304 deletions
diff --git a/sources/scalac/transformer/AddInterfaces.java b/sources/scalac/transformer/AddInterfaces.java deleted file mode 100644 index 1e922a8165..0000000000 --- a/sources/scalac/transformer/AddInterfaces.java +++ /dev/null @@ -1,304 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -// TODO find a good way to change symbol flags (PRIVATE, DEFERRED, -// INTERFACE). In particular find how to make sure that the -// modifications are not made too early, for example before the symbol -// is cloned. - -package scalac.transformer; - -import java.util.Map; -import java.util.HashMap; - -import scalac.Global; -import scalac.ast.GenTransformer; -import scalac.ast.Tree; -import scalac.ast.Tree.Template; -import scalac.ast.TreeGen; -import scalac.ast.TreeList; -import scalac.symtab.Type; -import scalac.symtab.Scope; -import scalac.symtab.Symbol; -import scalac.symtab.SymbolSubstTypeMap; -import scalac.util.Debug; - -/** - * Add, for each class, an interface with the same name, to be used - * later by mixin expansion. More specifically: - * - * - at the end of the name of every class, the string "$class" is - * added, - * - * - an interface with the original name of the class is created, and - * contains all directly bound members of the class (as abstract - * members), - * - * - the interface is added to the mixin base classes of the class. - * - * @author Michel Schinz - * @version 1.0 - */ -public class AddInterfaces extends GenTransformer { - - //######################################################################### - // Private Fields - - /** The AddInterface phase */ - private final AddInterfacesPhase phase; - - /** The current class (null is none) */ - private Symbol clasz; - - /** The current member (null is none) */ - private Symbol member; - - /** The current class substitution (null is none) */ - private Type.Map classSubst; - - /** The current parameter substitution (null is none) */ - private SymbolSubstTypeMap paramSubst; - - //######################################################################### - // Public Constructors - - /** Initializes this instance. */ - public AddInterfaces(Global global, AddInterfacesPhase phase) { - super(global); - this.phase = phase; - } - - //######################################################################### - // Public Methods - - /** Transforms the given symbol. - * - * @param tree - * @return - */ - public Symbol getSymbolFor(Tree tree) { - switch (tree) { - case Create(_, _): - return phase.getClassSymbol(tree.symbol()); - case Return(_): - return member; - case This(_): - case Super(_, _): - return clasz; - case Select(Super(_, _), _): - Symbol symbol = tree.symbol(); - if (symbol.isInitializer()) return getClassMember(symbol); - return getClassMember(symbol, true); - case Select(_, _): - Symbol symbol = tree.symbol(); - if (symbol.isInitializer()) return getClassMember(symbol); - return symbol; - case Ident(_): - Symbol symbol = tree.symbol(); - if (symbol.isInitializer()) return getClassMember(symbol); - if (symbol.isParameter() && !symbol.owner().isStatic()) - return getClassVParam(symbol); - return symbol; - default: - return tree.symbol(); - } - } - - /** Transforms the given type. */ - public Type transform(Type type) { - if (classSubst != null) type = classSubst.apply(type); - if (paramSubst != null) type = paramSubst.apply(type); - return type; - } - - /** Transforms the given trees. */ - public Tree[] transform(Tree[] trees) { - if (member != null) return super.transform(trees); - TreeList list = new TreeList(); - for (int i = 0; i < trees.length; i++) template(list, trees[i]); - return list.toArray(); - } - - /** Transforms the given tree. */ - public Tree transform(Tree tree) { - switch (tree) { - case ValDef(_, _, _, _): - case LabelDef(_, _, _): - Symbol symbol = tree.symbol(); - if (symbol.owner() != member) { - symbol.updateInfo(transform(symbol.info())); - symbol.setOwner(member); - } - return super.transform(tree); - case Select(Tree qualifier, _): - Type prefix = qualifier.type(); - qualifier = transform(qualifier); - Symbol symbol = getSymbolFor(tree); - if (symbol.isJava() && !symbol.owner().isInterface()) { - if (qualifier.type().widen().symbol().isInterface()) { - Type baseType = prefix.baseType(symbol.owner()); - assert baseType != Type.NoType: tree; - qualifier = gen.mkAsInstanceOf(qualifier, baseType); - } - } - return gen.Select(tree.pos, qualifier, symbol); - default: - return super.transform(tree); - } - } - - //######################################################################### - // Private Methods - - /** Transforms the given template and adds it to given list. - * - * @param trees - * @param tree - */ - private void template(TreeList trees, Tree tree) { - switch (tree) { - case Empty: - return; - case PackageDef(_, _): - trees.append(super.transform(tree)); - return; - case ClassDef(_, _, _, _, _, Template(_, Tree[] body)): - TreeList list = new TreeList(transform(body)); - this.clasz = tree.symbol(); - Map methods = new HashMap(); - if (phase.needInterface(clasz)) { - Symbol clone = phase.getClassSymbol(clasz); - trees.append(getClassTree(clasz, list, methods)); - list = new TreeList(); - this.classSubst = new Type.SubstThisMap(clasz, clone); - this.paramSubst = phase.getClassSubst(clone); - this.clasz = clone; - } - for (int i = 0; i < body.length; i++) member(methods, body[i]); - trees.append(getClassTree(clasz, list, methods)); - assert methods.isEmpty(): Debug.show(methods.keySet().toArray()); - this.paramSubst = null; - this.classSubst = null; - this.clasz = null; - return; - case DefDef(_, _, _, _, _, _): - case ValDef(_, _, _, _): - return; - default: - throw Debug.abort("illegal tree", tree); - } - } - - /** - * Transforms the given class member. Methods with a non-empty - * body are added to the given method map. All other members are - * dropped. - * - * @param methods - * @param tree - */ - private void member(Map methods, Tree tree) { - switch (tree) { - case ClassDef(_, _, _, _, _, _): - return; - case DefDef(_, _, _, _, _, Tree rhs): - if (rhs == Tree.Empty) return; - Symbol symbol = tree.symbol(); - this.member = getClassMember(symbol); - if (member != symbol) { - paramSubst.insertSymbol( - symbol.typeParams(), member.nextTypeParams()); - paramSubst.insertSymbol( - symbol.valueParams(), member.nextValueParams()); - } - methods.put(member, gen.DefDef(member, transform(rhs))); - if (member != symbol) { - paramSubst.removeSymbol(symbol.valueParams()); - paramSubst.removeSymbol(symbol.typeParams()); - } - this.member = null; - return; - case ValDef(_, _, _, Tree rhs): - assert rhs == Tree.Empty: tree; - return; - default: - throw Debug.abort("illegal tree", tree); - } - } - - /** - * Returns the tree of the given class. Its body is built by - * adding its members to the provided body. Non-abstract methods - * are removed from the provided method map. All other members are - * generated from their symbol. - * - * @param clasz - * @param body - * @param methods - * @return - */ - private Tree getClassTree(Symbol clasz, TreeList body, Map methods) { - Scope members = clasz.nextInfo().members(); - for (Scope.SymbolIterator i = members.iterator(); i.hasNext(); ) { - Symbol member = i.next(); - if (!member.isTerm()) continue; - body.append(getMemberTree(clasz, member, methods)); - } - Tree[] array = body.toArray(); - if (!clasz.isInterface()) phase.classToBody.put(clasz, array); - return gen.ClassDef(clasz, array); - } - - /** - * Returns the tree of the given member. Non-abstract methods are - * removed from the given method map. All other members are - * generated from their symbol. - * - * @param clasz - * @param member - * @param methods - * @return - */ - private Tree getMemberTree(Symbol clasz, Symbol member, Map methods) { - if (!member.isMethod()) return gen.ValDef(member, Tree.Empty); - if (member.isDeferred()) return gen.DefDef(member, Tree.Empty); - Tree method = (Tree)methods.remove(member); - assert method != null: Debug.show(clasz + "." + member + ":" + member.info() + member.locationString()); - return method; - } - - /** Returns the symbol of given parameter in current class. - * - * @param vparam - * @return - */ - private Symbol getClassVParam(Symbol vparam) { - if (paramSubst == null) return vparam; - Symbol clone = (Symbol)paramSubst.lookupSymbol(vparam); - assert clone != null: Debug.show(vparam, clasz, member); - return clone; - } - - /** Returns the symbol of given member in current class. */ - private Symbol getClassMember(Symbol member) { - return getClassMember(member, false); - } - // !!! Try to remove version with lazy argument. It is currently - // needed for super calls to abstract method (possible in mixins). - private Symbol getClassMember(Symbol member, boolean lazy) { - Symbol owner = member.owner(); - assert owner.isClass(): Debug.show(member); - if (!phase.needInterface(owner)) return member; - Symbol clasz = phase.getClassSymbol(owner); - Symbol clone = (Symbol)phase.getClassMemberMap(clasz).get(member); - assert clone != null || lazy: Debug.show(member, " not in ", clasz); - return clone != null ? clone : member; - } - - //######################################################################### -} |