diff options
author | Gilles Dubochet <gilles.dubochet@epfl.ch> | 2005-12-18 18:33:03 +0000 |
---|---|---|
committer | Gilles Dubochet <gilles.dubochet@epfl.ch> | 2005-12-18 18:33:03 +0000 |
commit | d3819b93ab8b2de3d5cc35c33b8258ccdb5a931a (patch) | |
tree | dfc6f7f497e58ea3321e6f687b11313d2afa86b5 /sources/scalac/transformer | |
parent | 0e82079908655682e5140ad521cef0572cb6d2a4 (diff) | |
download | scala-d3819b93ab8b2de3d5cc35c33b8258ccdb5a931a.tar.gz scala-d3819b93ab8b2de3d5cc35c33b8258ccdb5a931a.tar.bz2 scala-d3819b93ab8b2de3d5cc35c33b8258ccdb5a931a.zip |
Removed old Scalac code in sources and various ...
Removed old Scalac code in sources and various other obsolete elements.
Diffstat (limited to 'sources/scalac/transformer')
17 files changed, 0 insertions, 6008 deletions
diff --git a/sources/scalac/transformer/AddAccessorsPhase.java b/sources/scalac/transformer/AddAccessorsPhase.java deleted file mode 100644 index 2f684e1acb..0000000000 --- a/sources/scalac/transformer/AddAccessorsPhase.java +++ /dev/null @@ -1,146 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: AddAccessorsPhase.java,v 1.1 2002/10/17 12:27:11 schinz Exp $ -// $Id$ - -package scalac.transformer; - -import java.util.Map; -import java.util.HashMap; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; -import scalac.CompilationUnit; -import scalac.ast.GenTransformer; -import scalac.ast.Tree; -import scalac.ast.Tree.Template; -import scalac.ast.TreeList; -import scalac.symtab.Modifiers; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Name; -import scalac.util.Debug; - - -/** - * This phase adds private accessor fields and methods for all class - * constructor arguments which are accessed from within the class' - * methods, or nested classes. - */ -public class AddAccessorsPhase extends Phase { - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public AddAccessorsPhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - } - - //######################################################################## - // Public Methods - - /** Applies this phase to the given compilation unit. */ - public void apply(CompilationUnit unit) { - treeTransformer.apply(unit); - } - - //######################################################################## - // Private Class - Tree transformer - - /** The tree transformer */ - private final GenTransformer treeTransformer = new GenTransformer(global) { - - /** 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; - Name name = Name.fromString(param.name + "$"); - Symbol owner = param.owner().constructorClass(); - Symbol field = owner.newField(param.pos, flags, name); - field.setType(param.type()); - owner.members().enterOrOverload(field); - return field; - } - - /** Creates an accessor method symbol for given parameter. */ - private Symbol createAccessorMethod(Symbol param) { - int flags = Modifiers.PRIVATE | Modifiers.STABLE | Modifiers.ACCESSOR; - Name name = param.name; - Symbol owner = param.owner().constructorClass(); - Symbol method = owner.newMethod(param.pos, flags, name); - method.setType(Type.MethodType(Symbol.EMPTY_ARRAY, param.type())); - owner.members().enterOrOverload(method); - methods.put(param, method); - return method; - } - - /** Transforms the given tree. */ - public Tree transform(Tree tree) { - switch (tree) { - 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(); - for (int i = 0; i < params.length; ++i) { - Symbol param = params[i]; - Symbol method = (Symbol)methods.remove(param); - if (method == null) continue; - Symbol field = createAccessorField(param); - accessors.append( - gen.ValDef( - field, - gen.Ident(param.pos, param))); - accessors.append( - gen.DefDef( - method, - gen.Select(gen.This(param.pos, clasz), field))); - } - body = Tree.concat(accessors.toArray(), body); - impl = gen.Template(clasz.pos, impl.symbol(), parents, body); - return gen.ClassDef(clasz, impl); - } - case AbsTypeDef(_, _, _, _): - case AliasTypeDef(_, _, _, _): - return Tree.Empty; // eliminate - case Typed(Tree expr, _): - return transform(expr); // eliminate - 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/AddConstructors.java b/sources/scalac/transformer/AddConstructors.java deleted file mode 100644 index 5440c68ebf..0000000000 --- a/sources/scalac/transformer/AddConstructors.java +++ /dev/null @@ -1,295 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.transformer; - -import java.util.ArrayList; -import java.util.HashMap; - -import scalac.Global; -import scalac.ast.GenTransformer; -import scalac.ast.Tree; -import scalac.ast.Tree.Template; -import scalac.symtab.Modifiers; -import scalac.symtab.Symbol; -import scalac.symtab.SymbolSubstTypeMap; -import scalac.symtab.Type; -import scalac.util.Debug; - -/** - * This phase adds to all classes one initializer method per - * constructor. Initializers have the same value parameters as their - * corresponding constructor but no type parameters. - * - * An initializer may be used in the body of another initializer - * either to invoke another initializer of the same class or to invoke - * an initailizer of the superclass. In that case, the initializer - * must appear in a Select node whose qualifier is either a This node - * or a Super node. The type of such a Select node is the type of the - * initializer. - * - * An initializer may also be used in a new operation. In that case, - * the initializer must appear in an Ident node. The type of such an - * Ident node is a PolyType whose arguments are the type arguments of - * the initializer's class and whose result type is the initializer's - * type. - * - * This phase does the following in the tree: - * - * - replaces all non-primary constructors definitions by initializer - * definitions with the same body, - * - * - for each non-interface class creates an primary initializer - * method corresponding to the primary constructor, - * - * - moves the call to the super constructor into the primary - * initializer, - * - * - moves all class fields initialization code (rhs of ValDefs) into - * the primary initializer, - * - * - moves all class-level expressions into the primary initializer, - * - * - replaces all constructor invocations by initializer invocations, - * except in the parents field of class templates. - * - * @author Nikolay Mihaylov - * @version 1.2 - */ -public class AddConstructors extends GenTransformer { - - /** A constructor to initializer map */ - private final HashMap/*<Symbol,Symbol>*/ initializers; - - /** A constructor to initializer parameter substitution */ - private final SymbolSubstTypeMap subst; - - /** The current primary initializer or null */ - private Symbol primaryInitializer; - - /** - * ... - * - * @param global - * @param initializers - */ - public AddConstructors(Global global, HashMap initializers) { - super(global); - this.initializers = initializers; - this.subst = new SymbolSubstTypeMap(); - } - - /** - * Returns the initializer corresponding to the given constructor. - * - * @param constructor - * @return - */ - private Symbol getInitializer(Symbol constructor) { - assert constructor.isConstructor(): Debug.show(constructor); - Symbol initializer = (Symbol)initializers.get(constructor); - if (initializer == null) { - assert !constructor.constructorClass().isInterface(): - "found interface constructor " + Debug.show(constructor); - int flags = constructor.isPrivate() - ? (constructor.flags & ~Modifiers.PRIVATE) | Modifiers.PROTECTED - : constructor.flags; - initializer = constructor.constructorClass().newMethod( - constructor.pos, - flags & Modifiers.ACCESSFLAGS, - constructor.name); - initializer.setInfo( - Type.MethodType( - constructor.valueParams(), - global.definitions.void_TYPE()) - .cloneType(constructor, initializer)); - initializer.owner().members().enterOrOverload(initializer); - initializers.put(constructor, initializer); - } - return initializer; - } - - /** - * Process the tree. - */ - public Tree transform(Tree tree) { - return transform(tree, false); - } - - /** - * ... - * - * @param tree - * @param inNew - * @return - */ - private Tree transform(Tree tree, boolean inNew) { - switch (tree) { - case ClassDef(_, _, _, _, _, Template impl): - Symbol clasz = tree.symbol(); - - if (clasz.isInterface()) - return gen.ClassDef(clasz, transform(impl.body)); - - // expressions that go before the call to the super constructor - final ArrayList constrBody = new ArrayList(); - - // expressions that go after the call to the super constructor - final ArrayList constrBody2 = new ArrayList(); - - // the body of the class after the transformation - final ArrayList classBody = new ArrayList(); - - Symbol local = impl.symbol(); - for (int i = 0; i < impl.body.length; i++) { - Tree member = impl.body[i]; - if (member.definesSymbol() && member.symbol().owner()!=local) { - switch (member) { - case ValDef(_, _, _, Tree rhs): - // move initialization code into initializer - Symbol field = member.symbol(); - if (rhs == Tree.Empty) break; - member = gen.ValDef(field, Tree.Empty); - Tree assign = gen.Assign( - gen.Select(gen.This(member.pos, clasz),field),rhs); - if (rhs.hasSymbol() && rhs.symbol().isParameter()) { - constrBody.add(assign); - } else { - constrBody2.add(assign); - } - } - classBody.add(member); - } else { - // move class-level code into initializer - constrBody2.add(member); - } - } - - // inline the call to the super constructor - for (int i = 0; i < impl.parents.length; i++) { - switch (impl.parents[i]) { - case Apply(TypeApply(Tree fun, Tree[] targs), Tree[] args): - assert fun.symbol().isConstructor(): impl.parents[i]; - if (fun.symbol().constructorClass().isInterface()) continue; - int pos = impl.parents[i].pos; - Tree superConstr = gen.Select - (gen.Super(pos, clasz), getInitializer(fun.symbol())); - constrBody.add(gen.mkApply_V(superConstr, args)); - break; - case Apply(Tree fun, Tree[] args): - assert fun.symbol().isConstructor(): impl.parents[i]; - if (fun.symbol().constructorClass().isInterface()) continue; - int pos = impl.parents[i].pos; - Tree superConstr = gen.Select - (gen.Super(pos, clasz), getInitializer(fun.symbol())); - constrBody.add(gen.mkApply_V(superConstr, args)); - break; - default: - throw Debug.abort("illegal case", impl.parents[i]); - } - } - - // add valdefs and class-level expression to the constructor body - constrBody.addAll(constrBody2); - - Tree constrTree = gen.mkUnitBlock( - clasz.primaryConstructor().pos, - (Tree[])constrBody.toArray(new Tree[constrBody.size()])); - - classBody.add(gen.DefDef(clasz.primaryConstructor(), constrTree)); - - Tree[] newBody = (Tree[]) classBody.toArray(Tree.EMPTY_ARRAY); - - // transform the bodies of all members in order to substitute - // the constructor references with the new ones - return gen.ClassDef(clasz, transform(newBody)); - - case DefDef(_, _, _, _, _, Tree rhs): - if (!tree.symbol().isConstructor()) return super.transform(tree); - // replace constructor by initializer - Symbol constructor = tree.symbol(); - Symbol initializer = getInitializer(constructor); - subst.insertSymbol( - constructor.typeParams(), - constructor.constructorClass().typeParams()); - subst.insertSymbol( - constructor.valueParams(), - initializer.valueParams()); - if (constructor.isPrimaryConstructor()) - primaryInitializer = initializer; - rhs = transform(rhs); - primaryInitializer = null; - subst.removeSymbol(constructor.valueParams()); - subst.removeSymbol(constructor.typeParams()); - // add consistent result expression - rhs = gen.mkUnitBlock(rhs); - return gen.DefDef(initializer, rhs); - - case ValDef(_, _, _, _): - case LabelDef(_, _, _): - Symbol symbol = tree.symbol(); - if (symbol.owner().isConstructor()) { - // update symbols like x in these examples - // ex 1: class C { { val x = ...; ... } } - // ex 2: class C { def this(i: Int) { val x = i; ... } } - symbol.setOwner(getInitializer(symbol.owner())); - symbol.updateInfo(subst.apply(symbol.info())); - } - return super.transform(tree); - - case New(Tree init): - return gen.New(transform(init, true)); - - case TypeApply(Tree fun, Tree[] args): - if (!fun.symbol().isConstructor()) return super.transform(tree); - if (!inNew) return transform(fun); - assert fun instanceof Tree.Ident: tree; - return transform(tree, fun.symbol(), transform(args)); - - case Apply(Tree fun, Tree[] args): - return gen.Apply(transform(fun, inNew), transform(args)); - - case Ident(_): - Symbol symbol = tree.symbol(); - if (inNew) return transform(tree, symbol, Tree.EMPTY_ARRAY); - if (symbol.isConstructor()) { - symbol = getInitializer(symbol); - Symbol clasz = symbol.owner(); - return gen.Select(gen.This(tree.pos, clasz), symbol); - } - else if (symbol.owner().isConstructor()) { - symbol = subst.lookupSymbol(symbol); - } - return gen.Ident(tree.pos, symbol); - - case TypeTerm(): - return gen.TypeTerm(tree.pos, subst.apply(tree.getType())); - - default: - return super.transform(tree); - } // switch(tree) - - } // transform() - - /** - * Transforms the new instance creation. - * - * @param tree - * @param constructor - * @param targs - * @return - */ - private Tree transform(Tree tree, Symbol constructor, Tree[] targs) { - assert constructor.isConstructor(): tree; - Symbol initializer = getInitializer(constructor); - Symbol clasz = initializer.owner(); - Tree instance = gen.Create(tree.pos, Tree.Empty, clasz, targs); - return gen.Select(tree.pos, instance, initializer); - } - -} // class AddConstructors diff --git a/sources/scalac/transformer/AddConstructorsPhase.java b/sources/scalac/transformer/AddConstructorsPhase.java deleted file mode 100644 index 1dfb10e344..0000000000 --- a/sources/scalac/transformer/AddConstructorsPhase.java +++ /dev/null @@ -1,63 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -//package scala.compiler.backend; -package scalac.transformer; - -import java.util.HashMap; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; -import scalac.CompilationUnit; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Debug; - -public class AddConstructorsPhase extends Phase { - - //######################################################################## - // Private Fields - - /** A map from old constructor symbols to new ones */ - private final HashMap/*<Symbol,Symbol>*/ constructors = new HashMap(); - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public AddConstructorsPhase(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.isConstructor()) { - switch (type) { - case PolyType(Symbol[] tparams, MethodType(_, Type result)): - result = Type.MethodType(Symbol.EMPTY_ARRAY, result); - return Type.PolyType(tparams, result); - case MethodType(_, Type result): - return Type.MethodType(Symbol.EMPTY_ARRAY, result); - default: - throw Debug.abort("illegal case", type); - } - } - return type; - } - - /** Applies this phase to the given compilation unit. */ - public void apply(CompilationUnit unit) { - new AddConstructors(global, constructors).apply(unit); - } - - //######################################################################## -} 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; - } - - //######################################################################### -} diff --git a/sources/scalac/transformer/AddInterfacesPhase.java b/sources/scalac/transformer/AddInterfacesPhase.java deleted file mode 100644 index 026ac5feda..0000000000 --- a/sources/scalac/transformer/AddInterfacesPhase.java +++ /dev/null @@ -1,313 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -// TODO try to use setInfo instead of updateInfo for cloned symbols, -// to avoid the need to use nextPhase/nextInfo. - -package scalac.transformer; - -import java.util.HashMap; -import java.util.Map; - -import scalac.*; -import scalac.symtab.*; -import scalac.util.Debug; -import scalac.util.Name; - -public class AddInterfacesPhase extends Phase { - - /** Initializes this instance. */ - public AddInterfacesPhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - } - - /** Applies this phase to the given compilation unit. */ - public void apply(CompilationUnit unit) { - new AddInterfaces(global, this).apply(unit); - } - - public Type transformInfo(Symbol sym, Type tp) { - if (sym.isConstructor() || sym.owner().isConstructor()) { - return tp; - } else if (sym.isClass() && !sym.isJava()) { - Definitions definitions = global.definitions; - if (sym == definitions.ANY_CLASS) return tp; - Type[] oldParents = tp.parents(); - assert oldParents.length > 0 : Debug.show(sym); - for (int i = 1; i < oldParents.length; ++i) { - Symbol oldSym = oldParents[i].symbol(); - assert !oldSym.isJava() || oldSym.isInterface() : - Debug.show(sym) + " <: " + Debug.show(oldSym); - } - - boolean ifaceReqrd = needInterface(sym); - Type[] newParents; - Scope newMembers = new Scope(); - - Scope.SymbolIterator oldMembersIt = - tp.members().iterator(); - while (oldMembersIt.hasNext()) { - Symbol member = oldMembersIt.next(); - - if (ifaceReqrd - && (member.isInitializer() || !memberGoesInInterface(member))) - continue; - - if (member.isPrivate() && !member.isClass()) { - member.name = uniqueName(member); - member.flags ^= Modifiers.PRIVATE; - } else if (member.isProtected()) - member.flags ^= Modifiers.PROTECTED; - - newMembers.enterOrOverload(member); - } - - if (ifaceReqrd) { - // Before this phase, the symbol is a class, but after - // it will be an interface. Its type has to be changed - // so that: - // - // 1. Java classes are removed from its parents, - // - // 2. only members which will end up in the - // interface are kept, and private ones are made - // public and renamed. - sym.flags |= Modifiers.INTERFACE; - newParents = oldParents; - } else { - // The symbol is the one of a class which doesn't need - // an interface. We need to fix its parents to use - // class symbols instead of interface symbols. - newParents = new Type[oldParents.length]; - for (int i = 0; i < oldParents.length; ++i) { - switch (oldParents[i]) { - case TypeRef(Type pre, Symbol oldSym, Type[] args): - newParents[i] = !needInterface(oldSym) - ? oldParents[i] - : Type.typeRef(pre, getClassSymbol(oldSym), args); - break; - default: - throw Debug.abort("illegal case", oldParents[i]); - } - } - } - - return Type.compoundType(newParents, newMembers, sym); - } else if (sym.owner().isClass() || sym.isParameter()) { - getClassSymbol(sym.enclClass()); - return sym.info(); - } else - return tp; - } - - protected boolean memberGoesInInterface(Symbol member) { - return !member.isStatic() && (member.isType() || member.isMethod()); - } - - protected final SymbolNameWriter uniqueNameWriter = new SymbolNameWriter() - .setAllSeparators('$') - .setRootSeparator('\0'); - protected Name uniqueName(Symbol sym) { - Name name = Name.fromString(uniqueNameWriter.toString(sym)); - return sym.name.isTypeName() ? name.toTypeName() : name; - } - - // Terminology: in the following code, the symbol which was used - // until this phase for the class, and will now be used for the - // interface is called the "interface symbol". The symbol created - // by this phase for the class is called the "class symbol". - - /** True iff the given class symbol needs an interface. */ - protected boolean needInterface(Symbol classSym) { - assert classSym.isClass() - : Debug.show(classSym) + " is not a class (kind " + classSym.kind + ")"; - return !(classSym.isJava() - || classSym.isModuleClass() - || classSym.isAnonymousClass() - || hasInterfaceSymbol(classSym) - || classSym == global.definitions.ANY_CLASS - || classSym == global.definitions.ANYREF_CLASS - || classSym == global.definitions.ALL_CLASS - || classSym == global.definitions.ALLREF_CLASS); - } - - protected final static String CLASS_SUFFIX = "$class"; - protected Name className(Name ifaceName) { - Name className = Name.fromString(ifaceName.toString() + CLASS_SUFFIX); - if (ifaceName.isTypeName()) return className.toTypeName(); - else return className; - } - - protected final HashMap/*<Symbol,Symbol>*/ ifaceToClass = new HashMap(); - protected final HashMap/*<Symbol,Symbol>*/ classToIFace = new HashMap(); - protected final HashMap/*<Symbol,Tree[]>*/ classToBody = new HashMap(); - - /** Return the class symbol corresponding to the given interface - * symbol. If the class does not need an interface, return the - * given symbol. - * - * @param ifaceSym - * @return - */ - protected Symbol getClassSymbol(Symbol ifaceSym) { - assert ifaceSym.isClass(): Debug.show(ifaceSym); - if (!needInterface(ifaceSym)) - return ifaceSym; - - Symbol classSym = (Symbol)ifaceToClass.get(ifaceSym); - if (classSym == null) { - classSym = ifaceSym.cloneSymbol(ifaceSym.owner()); - classSym.name = className(ifaceSym.name); - ifaceSym.flags &= ~Modifiers.FINAL; - classSym.flags &= ~Modifiers.INTERFACE; - - Scope ifaceOwnerMembers = ifaceSym.owner().members(); - ifaceOwnerMembers.enter(classSym); - - Type.SubstThisMap thisTypeMap = - new Type.SubstThisMap(ifaceSym, classSym); - - // Create class substitution map. - SymbolSubstTypeMap classSubst = newClassSubst(classSym); - Map classMemberMap = newClassMemberMap(classSym); - - Symbol[] ifaceTParams = ifaceSym.typeParams(); - Symbol[] classTParams = classSym.typeParams(); - classSubst.insertSymbol(ifaceTParams, classTParams); - - // Clone all members, entering them in the class scope. - Scope classMembers = new Scope(); - Scope.SymbolIterator ifaceMembersIt = - ifaceSym.members().iterator(); - while (ifaceMembersIt.hasNext()) { - Symbol ifaceMemberSym = ifaceMembersIt.next(); - - if (ifaceMemberSym.isType() - || ifaceMemberSym.isDeferred()) - continue; - - Symbol classMemberSym; - if (memberGoesInInterface(ifaceMemberSym)) { - if (ifaceMemberSym.isPrivate()) { - ifaceMemberSym.name = uniqueName(ifaceMemberSym); - ifaceMemberSym.flags |= Modifiers.FINAL; - ifaceMemberSym.flags ^= Modifiers.PRIVATE; - } else if (ifaceMemberSym.isProtected()) - ifaceMemberSym.flags ^= Modifiers.PROTECTED; - - classMemberSym = ifaceMemberSym.cloneSymbol(classSym); - ifaceMemberSym.flags &= ~Modifiers.FINAL; - classMemberSym.setInfo( - thisTypeMap.applyParams( - classSubst.applyParams( - classMemberSym.info().cloneType( - ifaceMemberSym, classMemberSym)))); - - ifaceMemberSym.flags |= Modifiers.DEFERRED; - } else { - // Member doesn't go in interface, we just make it - // owned by the class. - classMemberSym = ifaceMemberSym; - - // [HACK] the following forces the evaluation of - // the type of all value parameters, which might - // otherwise become invalid once the owner is - // changed. - classMemberSym.info(); - if (classMemberSym.isMethod()) { - Symbol[] vp = classMemberSym.valueParams(); - for (int i = 0; i < vp.length; ++i) - vp[i].info(); - } - - classMemberSym.setOwner(classSym); - classMemberSym.updateInfo( - thisTypeMap.apply( - classSubst.apply( - classMemberSym.info()))); - } - - classMemberMap.put(ifaceMemberSym, classMemberSym); - classMembers.enterOrOverload(classMemberSym); - } - - // Give correct type to the class symbol by using class - // symbols for its parents, and by adding the interface - // among them. - Type[] oldClassParents = classSym.parents(); - int oldParentsCount = oldClassParents.length; - Type[] newClassParents = new Type[oldParentsCount + 1]; - for (int i = 0; i < oldParentsCount; ++i) { - switch (oldClassParents[i]) { - case TypeRef(Type pre, Symbol sym, Type[] args): - Type newTp = Type.typeRef(pre, getClassSymbol(sym), args); - newClassParents[i] = classSubst.apply(newTp); - break; - default: - throw Debug.abort("unexpected type for parent", oldClassParents[i]); - } - } - newClassParents[oldParentsCount] = classSubst.apply(ifaceSym.type()); - // TODO setInfo cannot be used here because the type then - // goes through transformInfo. Maybe setInfo should behave - // like updateInfo. - classSym.updateInfo(Type.compoundType(newClassParents, - classMembers, - classSym)); - ifaceToClass.put(ifaceSym, classSym); - classToIFace.put(classSym, ifaceSym); - - // move attributes to the implementing class - AttributeInfo attr = global.removeAttributes(ifaceSym); - if (attr != null) { - global.setAttribute(classSym, attr); - } - } - return classSym; - } - - public boolean hasInterfaceSymbol(Symbol classSym) { - return classToIFace.containsKey(classSym); - } - - public Symbol getInterfaceSymbol(Symbol classSym) { - return (Symbol)classToIFace.get(classSym); - } - - HashMap/*<Symbol,SymbolSubstTypeMap>*/ classSubstitutions = new HashMap(); - protected SymbolSubstTypeMap newClassSubst(Symbol classSym) { - SymbolSubstTypeMap subst = new SymbolSubstTypeMap(); - classSubstitutions.put(classSym, subst); - return subst; - } - - /** Return symbol substitution for the class (a mapping from the - * interface's type and value parameters to the class' equivalent) - */ - public SymbolSubstTypeMap getClassSubst(Symbol classSym) { - SymbolSubstTypeMap classSubst = - (SymbolSubstTypeMap)classSubstitutions.get(classSym); - assert classSubst != null; - return classSubst; - } - - HashMap/*<Symbol, HashMap>*/ classMemberMaps = new HashMap(); - protected HashMap newClassMemberMap(Symbol classSym) { - HashMap map = new HashMap(); - classMemberMaps.put(classSym, map); - return map; - } - - /** Return symbol substitution for the class (a mapping from the - * interface's type and value parameters to the class' equivalent) - */ - public Map getClassMemberMap(Symbol classSym) { - return (Map)classMemberMaps.get(classSym); - } - -} diff --git a/sources/scalac/transformer/Erasure.java b/sources/scalac/transformer/Erasure.java deleted file mode 100644 index 67a462b1f4..0000000000 --- a/sources/scalac/transformer/Erasure.java +++ /dev/null @@ -1,759 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: Erasure.java,v 1.48 2003/01/16 14:21:19 schinz Exp $ -// $Id$ - -package scalac.transformer; - -import java.util.Iterator; -import java.util.Map; -import java.util.HashMap; -import java.util.Set; -import java.util.HashSet; - -import scalac.Global; -import scalac.Phase; -import scalac.CompilationUnit; -import scalac.ast.Tree; -import scalac.ast.Tree.Ident; -import scalac.ast.Tree.Template; -import scalac.ast.Tree.AbsTypeDef; -import scalac.ast.Tree.AliasTypeDef; -import scalac.ast.Tree.ValDef; -import scalac.ast.TreeList; -import scalac.ast.GenTransformer; -import scalac.atree.AConstant; -import scalac.symtab.Definitions; -import scalac.symtab.Kinds; -import scalac.symtab.Type; -import scalac.symtab.TypeTags; -import scalac.symtab.Modifiers; -import scalac.symtab.Scope; -import scalac.symtab.Scope.SymbolIterator; -import scalac.symtab.SymSet; -import scalac.symtab.Symbol; -import scalac.symtab.SymbolTablePrinter; -import scalac.backend.Primitive; -import scalac.backend.Primitives; -import scalac.util.Name; -import scalac.util.Names; -import scalac.util.Debug; - -/** A transformer for type erasure and bridge building - * - * @author Martin Odersky - * @version 1.0 - * - * What it does: - * (1) Map every type to its erasure. - * (2) If method A overrides a method B, and the erased type ETA of A is - * different from the erased type ETB of B seen as a member of A's class, - * add a bridge method with the same name as A,B, with signature ETB - * which calls A after casting parameters. - */ -public class Erasure extends GenTransformer implements Modifiers { - - //######################################################################## - // Private Constants - - /** The unboxed types */ - private static final Type - UNBOXED_UNIT = Type.unboxedType(TypeTags.UNIT), - UNBOXED_BOOLEAN = Type.unboxedType(TypeTags.BOOLEAN), - UNBOXED_BYTE = Type.unboxedType(TypeTags.BYTE), - UNBOXED_SHORT = Type.unboxedType(TypeTags.SHORT), - UNBOXED_CHAR = Type.unboxedType(TypeTags.CHAR), - UNBOXED_INT = Type.unboxedType(TypeTags.INT), - UNBOXED_LONG = Type.unboxedType(TypeTags.LONG), - UNBOXED_FLOAT = Type.unboxedType(TypeTags.FLOAT), - UNBOXED_DOUBLE = Type.unboxedType(TypeTags.DOUBLE); - - //######################################################################## - // Private Fields - - /** The global definitions */ - private final Definitions definitions; - - /** The global primitives */ - private final Primitives primitives; - - /** The current unit */ - private CompilationUnit unit; - - private final boolean forMSIL; - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public Erasure(Global global) { - super(global); - this.definitions = global.definitions; - this.primitives = global.primitives; - this.forMSIL = global.target == global.TARGET_MSIL; - } - - //######################################################################## - // Public Methods - - /** Transforms the given unit. */ - public void apply(CompilationUnit unit) { - this.unit = unit; - super.apply(unit); - } - - /** Transforms the given tree. */ - public Tree transform(Tree tree) { - switch (tree) { - - case ClassDef(_, _, _, _, _, Template(_, Tree[] body)): - Symbol clasz = tree.symbol(); - TreeList members = new TreeList(transform(body)); - addBridges(clasz, members); - return gen.ClassDef(clasz, members.toArray()); - - case ValDef(_, _, _, Tree rhs): - Symbol field = tree.symbol(); - if (rhs != Tree.Empty) rhs = transform(rhs, field.nextType()); - return gen.ValDef(field, rhs); - - case DefDef(_, _, _, _, _, Tree rhs): - Symbol method = tree.symbol(); - if (rhs != Tree.Empty) - rhs = transform(rhs, method.nextType().resultType()); - return gen.DefDef(method, rhs); - - case LabelDef(_, Ident[] params, Tree body): - Symbol label = tree.symbol(); - body = transform(body, label.nextType().resultType()); - return gen.LabelDef(label, Tree.symbolOf(params), body); - - case Assign(Tree lhs, Tree rhs): - lhs = transform(lhs); - rhs = transform(rhs, lhs.type); - return gen.Assign(tree.pos, lhs, rhs); - - case Return(Tree expr): - Symbol method = tree.symbol(); - Type type = method.nextType().resultType(); - return gen.Return(tree.pos, method, transform(expr, type)); - - case New(Tree init): - if (tree.getType().symbol() == definitions.ARRAY_CLASS) { - switch (init) { - case Apply(_, Tree[] args): - assert args.length == 1: tree; - Type element = getArrayElementType(tree.getType()).erasure(); - Tree size = transform(args[0]); - return genNewUnboxedArray(tree.pos, element, size); - default: - throw Debug.abort("illegal case", tree); - } - } - return gen.New(tree.pos, transform(init)); - - case Create(_, _): - return gen.Create(tree.pos, Tree.Empty, tree.symbol()); - - case Apply(TypeApply(Tree fun, Tree[] targs), Tree[] vargs): - fun = transform(fun); - vargs = transform(vargs); - Symbol symbol = fun.symbol(); - if (symbol == definitions.ANY_AS_ERASED) { - assert targs.length == 1 && vargs.length == 0: tree; - return coerce(getQualifier(fun), targs[0].getType().erasure()); - } - if (symbol == definitions.ANY_IS_ERASED) { - assert targs.length == 1 && vargs.length == 0: tree; - Type type = targs[0].type.erasure(); - if (isUnboxedSimpleType(type)) type = targs[0].type; - return gen.mkIsInstanceOf(tree.pos, getQualifier(fun), type); - } - return genApply(tree.pos, fun, vargs); - - case Apply(Tree fun, Tree[] vargs): - fun = transform(fun); - vargs = transform(vargs); - switch (fun) { - case Select(Apply(Tree bfun, Tree[] bargs), _): - Symbol bsym = bfun.symbol(); - if (primitives.getPrimitive(bsym) != Primitive.BOX) break; - assert bargs.length == 1: fun; - switch (primitives.getPrimitive(fun.symbol())) { - case COERCE: - assert vargs.length == 0: tree; - Tree value = bargs[0]; - return coerce(value, fun.type().resultType()); - case LENGTH: - assert vargs.length == 0: tree; - Tree array = bargs[0]; - return genUnboxedArrayLength(tree.pos, array); - case APPLY: - assert vargs.length == 1: tree; - Tree array = bargs[0]; - Tree index = vargs[0]; - return genUnboxedArrayGet(tree.pos, array, index); - case UPDATE: - assert vargs.length == 2: tree; - Tree array = bargs[0]; - Tree index = vargs[0]; - Tree value = vargs[1]; - return genUnboxedArraySet(tree.pos, array, index, value); - } - } - return genApply(tree.pos, fun, vargs); - - case Select(Tree qualifier, _): - Symbol symbol = tree.symbol(); - Type prefix = qualifier.type().baseType(symbol.owner()).erasure(); - assert prefix != Type.NoType: tree + " -- " + Debug.show(symbol); - qualifier = transform(qualifier); - qualifier = coerce(qualifier, prefix); - - // Might end up with "box(unbox(...))". That's needed by backend. - if (isUnboxedType(prefix)) qualifier = box(qualifier, true); - return gen.Select(tree.pos, qualifier, symbol); - - case Literal(AConstant.ZERO): - return gen.mkNullLit(tree.pos); - - case Block(_, _): - case If(_, _, _): - case Switch(_, _, _, _): - return transform(tree, tree.getType().fullErasure()); - - default: - return super.transform(tree); - } - } - - //######################################################################## - // Private Methods - Tree transformation - - /** Transforms the given trees with given prototype. */ - private Tree[] transform(Tree[] trees, Type pt) { - for (int i = 0; i < trees.length; i++) { - Tree tree = transform(trees[i], pt); - if (tree == trees[i]) continue; - Tree[] array = new Tree[trees.length]; - for (int j = 0; j < i ; j++) array[j] = trees[j]; - array[i] = tree; - while (++i < trees.length) array[i] = transform(trees[i], pt); - return array; - } - return trees; - } - - /** Transforms the given tree with given prototype. */ - private Tree transform(Tree tree, Type pt) { - switch (tree) { - - case Block(Tree[] stats, Tree value): - return gen.Block(tree.pos, transform(stats), transform(value, pt)); - - case If(Tree cond, Tree thenp, Tree elsep): - cond = transform(cond, UNBOXED_BOOLEAN); - thenp = transform(thenp, pt); - elsep = transform(elsep, pt); - return gen.If(tree.pos, cond, thenp, elsep, pt); - - case Switch(Tree test, int[] tags, Tree[] bodies, Tree otherwise): - test = transform(test, UNBOXED_INT); - bodies = transform(bodies, pt); - otherwise = transform(otherwise, pt); - return gen.Switch(tree.pos, test, tags, bodies, otherwise, pt); - - case Return(_): - // !!! why do we build a block here? - Tree value = transform(gen.mkDefaultValue(tree.pos, pt), pt); - return gen.mkBlock(transform(tree), value); - - case LabelDef(_, _, _): - case Assign(_, _): - case New(_): - case Apply(_, _): - case Super(_, _): - case This(_): - case Select(_, _): - case Ident(_): - case Literal(_): - return coerce(transform(tree), pt); - - default: - throw Debug.abort("illegal case", tree); - } - } - - /** Transforms Unit literal with given prototype. */ - private Tree transformUnit(int pos, Type pt) { - Tree unit = pt.isSameAs(UNBOXED_UNIT) - ? gen.mkUnitLit(pos) - : gen.mkApply__(gen.mkGlobalRef(pos, primitives.BOX_UVALUE)); - return coerce(unit, pt); - } - - /** Coerces the given tree to the given type. */ - private Tree coerce(Tree tree, Type pt) { - if (isSubType(tree.type(), pt)) { - if (tree.type().symbol() == definitions.ARRAY_CLASS) { - if (pt.symbol() != definitions.ARRAY_CLASS) { - Symbol symbol = primitives.UNBOX__ARRAY; - Tree unboxtree = gen.mkGlobalRef(tree.pos, symbol); - tree = gen.mkApply_V(unboxtree, new Tree[] {tree}); - return coerce(tree, pt); - } - } - return tree; - } - if (isUnboxedSimpleType(tree.type())) { - if (isUnboxedSimpleType(pt)) return convert(tree, pt); - Type to = pt.erasure(); - if (!isUnboxedSimpleType(to) || isSameAs(to, tree.type())) - return box(tree); - else - return coerce(convert(tree, to), pt); - } else if (isUnboxedArrayType(tree.type())) { - if (!isUnboxedArrayType(pt)) return check(box(tree), pt); - } else if (isUnboxedSimpleType(pt)) { - Type from = tree.type().erasure(); - if (isUnboxedSimpleType(from)) - return convert(unbox(tree, from), pt); - else - return unbox(coerce(tree, boxUnboxedType(pt)), pt); - } else if (isUnboxedArrayType(pt)) { - if (tree.type.symbol() == definitions.ARRAY_CLASS) - return coerce(unbox(tree, pt), pt); - } else if (pt.symbol() == definitions.ARRAY_CLASS) { - Tree boxtree = gen.mkGlobalRef(tree.pos, primitives.BOX__ARRAY); - return gen.mkApply_V(boxtree, new Tree[]{tree}); - } - return gen.mkAsInstanceOf(tree, pt); - } - - /** Checks that the given tree is of the given type. */ - private Tree check(Tree tree, Type pt) { - assert isSubType(tree.type(), pt): tree +" - "+ tree.type() +" - "+pt; - return tree; - } - - - /** Boxes the given tree. */ - private Tree box(Tree tree) { - return box(tree, false); - } - - /** Boxes the given tree. */ - private Tree box(Tree tree, boolean force) { - switch (tree) { - case Apply(Tree fun, Tree[] args): - if (primitives.getPrimitive(fun.symbol()) == Primitive.UNBOX) { - assert args.length == 1: tree; - if (!force) return args[0]; - } - } - Symbol symbol = primitives.getBoxValueSymbol(tree.getType()); - Tree boxtree = gen.mkGlobalRef(tree.pos, symbol); - return tree.getType().equals(UNBOXED_UNIT) - ? gen.mkBlock(tree, gen.mkApply__(boxtree)) - : gen.mkApply_V(boxtree, new Tree[]{tree}); - } - - /** Unboxes the given tree to the given type. */ - private Tree unbox(Tree tree, Type pt) { - switch (tree) { - case Apply(Tree fun, Tree[] args): - if (primitives.getPrimitive(fun.symbol()) == Primitive.BOX) { - assert args.length == 1: tree; - return args[0]; - } - } - Symbol symbol = primitives.getUnboxValueSymbol(pt); - return gen.mkApply_V( - gen.mkGlobalRef(tree.pos, symbol), new Tree[]{tree}); - } - - /** Converts the given tree to the given type. */ - private Tree convert(Tree tree, Type to) { - Symbol symbol = primitives.getConvertSymbol(tree.type(), to); - return gen.mkApply_V( - gen.mkGlobalRef(tree.pos, symbol), new Tree[]{tree}); - } - - //######################################################################## - // Private Methods - Tree generation - - /** Generates given bridge method forwarding to given method. */ - private Tree genBridgeMethod(Symbol bridge, Symbol method) { - Type type = bridge.nextType(); - Tree body = genApply(bridge.pos, - gen.Select(gen.This(bridge.pos, bridge.owner()), method), - gen.mkLocalRefs(bridge.pos, type.valueParams())); - return gen.DefDef(bridge, coerce(body, type.resultType())); - } - - /** Generates an application with given function and arguments. */ - private Tree genApply(int pos, Tree fun, Tree[] args) { - switch (fun.getType()) { - case MethodType(Symbol[] params, Type result): - Tree[] args1 = args; - for (int i = 0; i < args.length; i++) { - Tree arg = args[i]; - Tree arg1 = coerce(arg, params[i].nextType()); - if (arg1 != arg && args1 == args) { - args1 = new Tree[args.length]; - for (int j = 0; j < i; j++) args1[j] = args[j]; - } - args1[i] = arg1; - } - return gen.mkApply_V(pos, fun, args1); - default: - throw Debug.abort("illegal type " + fun.getType() + " for " + fun); - } - } - - /** - * Generates a new unboxed array of given size and with elements - * of given type. - */ - private Tree genNewUnboxedArray(int pos, Type element, Tree size) { - if (global.target == global.TARGET_INT) { - Tree[] targs = {gen.mkType(pos, element)}; - Tree[] vargs = {coerce(size, UNBOXED_INT)}; - Tree fun = gen.mkGlobalRef(pos, primitives.NEW_OARRAY); - return gen.mkApplyTV(fun, targs, vargs); - } - switch (element) { - case UnboxedType(int kind): return genNewUnboxedArray(pos, kind, size); - } - String name = primitives.getNameForClassForName(element); - Tree[] args = { coerce(size, UNBOXED_INT), gen.mkStringLit(pos,name) }; - Tree array = - gen.mkApply_V(gen.mkGlobalRef(pos,primitives.NEW_OARRAY), args); - return gen.mkAsInstanceOf(array, Type.UnboxedArrayType(element)); - } - - /** - * Generates a new unboxed array of given size and with elements - * of given unboxed type kind. - */ - private Tree genNewUnboxedArray(int pos, int kind, Tree size) { - Symbol symbol = primitives.getNewArraySymbol(kind); - Tree[] args = { coerce(size, UNBOXED_INT) }; - return gen.mkApply_V(gen.mkGlobalRef(pos, symbol), args); - } - - /** Generates an unboxed array length operation. */ - private Tree genUnboxedArrayLength(int pos, Tree array) { - assert isUnboxedArrayType(array.getType()): array; - Symbol symbol = primitives.getArrayLengthSymbol(array.getType()); - Tree[] args = { array }; - return gen.mkApply_V(gen.mkGlobalRef(pos, symbol), args); - } - - /** Generates an unboxed array get operation. */ - private Tree genUnboxedArrayGet(int pos, Tree array, Tree index) { - assert isUnboxedArrayType(array.getType()): array; - Symbol symbol = primitives.getArrayGetSymbol(array.getType()); - index = coerce(index, UNBOXED_INT); - Tree[] args = { array, index }; - return gen.mkApply_V(gen.mkGlobalRef(pos, symbol), args); - } - - /** Generates an unboxed array set operation. */ - private Tree genUnboxedArraySet(int pos, Tree array,Tree index,Tree value){ - assert isUnboxedArrayType(array.getType()): array; - Symbol symbol = primitives.getArraySetSymbol(array.getType()); - index = coerce(index, UNBOXED_INT); - value = coerce(value, getArrayElementType(array.getType())); - Tree[] args = { array, index, value }; - return gen.mkApply_V(gen.mkGlobalRef(pos, symbol), args); - } - - //######################################################################## - // Private Methods - Queries - - /** Returns the qualifier of the given tree. */ - private Tree getQualifier(Tree tree) { - switch (tree) { - case Select(Tree qualifier, _): - return qualifier; - default: - throw Debug.abort("no qualifier for tree", tree); - } - } - - /** Are the given erased types in a subtyping relation? */ - private boolean isSubType(Type tp1, Type tp2) { - global.nextPhase(); - boolean result = tp1.isSubType(tp2); - global.prevPhase(); - return result; - } - - /** Are the given erased types in an equality relation? */ - private boolean isSameAs(Type tp1, Type tp2) { - global.nextPhase(); - boolean result = tp1.isSameAs(tp2); - global.prevPhase(); - return result; - } - - /** Is the given type an unboxed type? */ - private boolean isUnboxedType(Type type) { - switch (type) { - case UnboxedType(_) : return true; - case UnboxedArrayType(_): return true; - default : return false; - } - } - - /** Is the given type an unboxed simple type? */ - private boolean isUnboxedSimpleType(Type type) { - switch (type) { - case UnboxedType(_) : return true; - default : return false; - } - } - - /** Is the given type an unboxed array type? */ - private boolean isUnboxedArrayType(Type type) { - switch (type) { - case UnboxedArrayType(_): return true; - default : return false; - } - } - - /** Returns the boxed version of the given unboxed type. */ - private Type boxUnboxedType(Type type) { - switch (type) { - case UnboxedType(TypeTags.UNIT): - return definitions.UNIT_CLASS.type(); - case UnboxedType(TypeTags.BOOLEAN): - return definitions.BOOLEAN_CLASS.type(); - case UnboxedType(TypeTags.BYTE): - return definitions.BYTE_CLASS.type(); - case UnboxedType(TypeTags.SHORT): - return definitions.SHORT_CLASS.type(); - case UnboxedType(TypeTags.CHAR): - return definitions.CHAR_CLASS.type(); - case UnboxedType(TypeTags.INT): - return definitions.INT_CLASS.type(); - case UnboxedType(TypeTags.LONG): - return definitions.LONG_CLASS.type(); - case UnboxedType(TypeTags.FLOAT): - return definitions.FLOAT_CLASS.type(); - case UnboxedType(TypeTags.DOUBLE): - return definitions.DOUBLE_CLASS.type(); - case UnboxedArrayType(Type element): - return Type.appliedType( - definitions.ARRAY_CLASS.type(), new Type[] {element}); - default: - throw Debug.abort("illegal case", type); - } - } - - /** Returns the element type of the given array type. */ - private Type getArrayElementType(Type type) { - switch (type) { - case TypeRef(_, Symbol symbol, Type[] args): - if (symbol != definitions.ARRAY_CLASS) break; - assert args.length == 1: type; - return args[0]; - case UnboxedArrayType(Type element): - return element; - } - throw Debug.abort("non-array type", type); - } - -////////////////////////////////////////////////////////////////////////////////// -// Bridge Building -///////////////////////////////////////////////////////////////////////////////// - - private TreeList bridges; - private HashMap bridgeSyms; - - /** Add bridge which Java-overrides `sym1' and which forwards to `sym' - */ - public void addBridge(Symbol owner, Symbol sym, Symbol sym1) { - Type bridgeType = sym1.nextType(); - - // create bridge symbol and add to bridgeSyms(sym) - // or return if bridge with required type already exists for sym. - SymSet bridgesOfSym = (SymSet) bridgeSyms.get(sym); - if (bridgesOfSym == null) bridgesOfSym = SymSet.EMPTY; - Symbol[] brs = bridgesOfSym.toArray(); - for (int i = 0; i < brs.length; i++) { - if (isSameAs(brs[i].type(), bridgeType)) return; - } - Symbol bridgeSym = sym.cloneSymbol(); - bridgeSym.flags |= (SYNTHETIC | BRIDGE); - bridgeSym.flags &= ~(JAVA | DEFERRED); - bridgesOfSym = bridgesOfSym.incl(bridgeSym); - bridgeSyms.put(sym, bridgesOfSym); - bridgeSym.setOwner(owner); - - // check that there is no overloaded symbol with same erasure as bridge - // todo: why only check for overloaded? - Symbol overSym = owner.members().lookup(sym.name); - switch (overSym.nextType()) { - case OverloadedType(Symbol[] alts, Type[] alttypes): - for (int i = 0; i < alts.length; i++) { - if (sym != alts[i] && isSameAs(bridgeType, alttypes[i])) { - unit.error(sym.pos, "overlapping overloaded alternatives; " + - "overridden " + sym1 + sym1.locationString() + - " has same erasure as " + alts[i] + - alttypes[i] + alts[i].locationString()); - } - } - } - - switch (bridgeType) { - case MethodType(Symbol[] params, Type restp): - // assign to bridge symbol its bridge type - // where owner of all parameters is bridge symbol itself. - Symbol[] params1 = new Symbol[params.length]; - for (int i = 0; i < params.length; i++) { - params1[i] = params[i].cloneSymbol(bridgeSym); - } - bridgeSym.setType(Type.MethodType(params1, restp)); - - bridges.append(genBridgeMethod(bridgeSym, sym)); - } - - } - - /** Add an "empty bridge" (abstract method declaration) to satisfy - * CLR's requirement that classes should provide declaration - * for all methods of the interfaces they implement - */ - /* - public void addEmptyBridge(Symbol owner, Symbol method) { - Type bridgeType = method.nextType(); - Symbol bridgeSym = method.cloneSymbol(owner); - bridgeSym.flags = bridgeSym.flags & ~JAVA | SYNTHETIC | DEFERRED; - //bridgeSym.setOwner(owner); - switch (bridgeType) { - case MethodType(Symbol[] params, Type restp): - // assign to bridge symbol its bridge type - // where owner of all parameters is bridge symbol itself. - Symbol[] params1 = new Symbol[params.length]; - for (int i = 0; i < params.length; i++) { - params1[i] = params[i].cloneSymbol(bridgeSym); - } - bridgeSym.setType(Type.MethodType(params1, restp)); - Tree bridge = gen.DefDef(bridgeSym, Tree.Empty); - bridges.append(bridge); - } - } - */ - - private final Map interfaces/*<Symbol,Set<Symbol>>*/ = new HashMap(); - - private Set getInterfacesOf(Symbol clasz) { - assert clasz.isClass(): Debug.show(clasz); - Set set = (Set)interfaces.get(clasz); - if (set == null) { - set = new HashSet(); - interfaces.put(clasz, set); - Type parents[] = clasz.parents(); - for (int i = 0; i < parents.length; i++) - set.addAll(getInterfacesOf(parents[i].symbol())); - if (clasz.isInterface()) set.add(clasz); - } - return set; - } - - private void addInterfaceBridges_(Symbol clasz) { - assert clasz.isClass() && !clasz.isInterface(): Debug.show(clasz); - assert clasz.parents().length > 0: Debug.show(clasz)+": "+clasz.info(); - Symbol svper = clasz.parents()[0].symbol(); - assert svper.isClass() && !svper.isInterface(): Debug.show(clasz); - Set interfaces = new HashSet(getInterfacesOf(clasz)); - interfaces.removeAll(getInterfacesOf(svper)); - for (Iterator i = interfaces.iterator(); i.hasNext(); ) { - Symbol inter = (Symbol)i.next(); - addInterfaceBridgesAux(clasz, inter.members()); - } - } - - private void addInterfaceBridgesAux(Symbol owner, Scope symbols) { - for (Scope.SymbolIterator i = symbols.iterator(); - i.hasNext();) { - Symbol member = i.next(); - if (!member.isTerm() || !member.isDeferred()) continue; - addInterfaceBridges(owner, member); - } - } - - - private Symbol getOverriddenMethod(Symbol method) { - Type[] parents = method.owner().parents(); - if (parents.length == 0) return Symbol.NONE; - return method.overriddenSymbol(parents[0]); - } - - public void addBridgeMethodsTo(Symbol method) { - assert method.owner().isClass() && !method.owner().isInterface(); - Symbol overridden = getOverriddenMethod(method); - if (!overridden.isNone() && !isSameAs(overridden.nextType(), method.nextType())) - addBridge(method.owner(), method, overridden); - } - - public void addInterfaceBridges(Symbol owner, Symbol method) { - assert owner.isClass() && !owner.isInterface(): Debug.show(owner); - Symbol overriding = method.overridingSymbol(owner.thisType()); - if (overriding == method) { - Symbol overridden = method.overriddenSymbol(owner.thisType().parents()[0], owner); - if (!overridden.isNone() && !isSameAs(overridden.nextType(), method.nextType())) - addBridge(owner, method, overridden); - // moved this into the TypeCreator class of the MSIL backend - //if (forMSIL && (overridden.isNone() || overridden.owner() != owner)) - // addEmptyBridge(owner, method); - } else if (!overriding.isNone() && !isSameAs(overriding.nextType(), method.nextType())) - addBridge(owner, overriding, method); - } - - private void addBridges(Symbol clasz, TreeList members) { - TreeList savedBridges = bridges; - HashMap savedBridgeSyms = bridgeSyms; - bridges = new TreeList(); - bridgeSyms = new HashMap(); - - int length = members.length(); - if (!clasz.isInterface()) { - for (int i = 0; i < length; i++) { - switch (members.get(i)) { - case DefDef(_, _, _, _, _, Tree rhs): - addBridgeMethodsTo(members.get(i).symbol()); - } - } - addInterfaceBridges_(clasz); - } - - members.append(bridges); - if (bridges.length() > 0) { - Type info = clasz.nextInfo(); - switch (info) { - case CompoundType(Type[] parts, Scope members_): - members_ = members_.cloneScope(); - for (int i = 0; i < bridges.length(); i++) { - Tree bridge = (Tree)bridges.get(i); - members_.enterOrOverload(bridge.symbol()); - } - clasz.updateInfo(Type.compoundType(parts, members_, info.symbol())); - break; - default: - throw Debug.abort("class = " + Debug.show(clasz) + ", " + - "info = " + Debug.show(info)); - } - } - bridgeSyms = savedBridgeSyms; - bridges = savedBridges; - } - - -} diff --git a/sources/scalac/transformer/ErasurePhase.java b/sources/scalac/transformer/ErasurePhase.java deleted file mode 100644 index c0669e22f2..0000000000 --- a/sources/scalac/transformer/ErasurePhase.java +++ /dev/null @@ -1,135 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: ErasurePhase.java,v 1.13 2002/11/14 15:58:22 schinz Exp $ -// $Id$ - -package scalac.transformer; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; -import scalac.CompilationUnit; -import scalac.backend.Primitive; -import scalac.backend.Primitives; -import scalac.symtab.Definitions; -import scalac.symtab.Modifiers; -import scalac.symtab.Scope; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Name; -import scalac.util.Debug; - -public class ErasurePhase extends Phase { - - //######################################################################## - // Private Fields - - private final Definitions definitions; - private final Primitives primitives; - private final Erasure erasure; - - //######################################################################## - // Public Constructors - - public ErasurePhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - this.definitions = global.definitions; - this.primitives = global.primitives; - this.erasure = new Erasure(global); - } - - //######################################################################## - // Public Methods - - public void apply(CompilationUnit unit) { - erasure.apply(unit); - } - - public Type transformInfo(Symbol sym, Type tp) { - if (sym.isConstructor() && sym.constructorClass().isSubClass(definitions.ANYVAL_CLASS)) return tp; - if (sym.isClass()) { - if (sym == definitions.ANY_CLASS) return tp; - if (sym.isJava() && sym.isModuleClass()) return tp; - if (sym.isSubClass(definitions.ANYVAL_CLASS)) - if (sym != definitions.ANYVAL_CLASS) return tp; - switch (tp) { - case CompoundType(Type[] parents, Scope members): - assert parents.length != 0: Debug.show(sym) + " -- " + tp; - if (sym.isInterface()) { - Symbol superclass = parents[0].symbol(); - if (superclass.isJava() && !superclass.isInterface()) { - parents = Type.cloneArray(parents); - parents[0] = definitions.ANYREF_TYPE(); - tp = Type.compoundType(parents, members, sym); - } - } - return Type.erasureMap.map(tp); - default: - throw Debug.abort("illegal case", tp); - } - } - if (sym.isTerm() && sym.isParameter()) { - if (primitives.getPrimitive(sym.owner()) == Primitive.BOX) - return eraseUnboxMethodType(tp); - if (primitives.getPrimitive(sym.owner()) == Primitive.UNBOX) - return eraseBoxMethodType(tp); - } - if (sym.isType()) return tp; - if (sym.isThisSym()) return sym.owner().nextType(); - // if (sym == definitions.NULL) return tp.resultType().erasure(); - if (global.target == global.TARGET_INT && sym ==primitives.NEW_OARRAY){ - // !!! hack for interpreter - Name name = Name.fromString("element").toTypeName(); - Symbol tparam = sym.newTParam(sym.pos, 0, name, definitions.ANY_TYPE()); - return Type.PolyType(new Symbol[]{tparam}, tp); - } - switch (primitives.getPrimitive(sym)) { - case Primitive.IS : return Type.PolyType(tp.typeParams(), Type.MethodType(tp.valueParams(), tp.resultType().erasure())); - case Primitive.AS : return tp; - case Primitive.BOX: return eraseBoxMethodType(tp); - case Primitive.UNBOX: return eraseUnboxMethodType(tp); - default : return tp.erasure(); - } - } - - //######################################################################## - // Private Methods - - private Type eraseBoxMethodType(Type type) { - switch (type) { - case PolyType(_, Type result): - return eraseBoxMethodType(result); - case MethodType(Symbol[] params, Type result): - return Type.MethodType(params, eraseBoxMethodType(result)); - case TypeRef(Type prefix, Symbol clasz, Type[] args): - return Type.typeRef(prefix, clasz, Type.EMPTY_ARRAY); - default: - throw Debug.abort("illegal case", type); - } - } - - private Type eraseUnboxMethodType(Type type) { - switch (type) { - case PolyType(_, Type result): - return eraseUnboxMethodType(result); - case MethodType(Symbol[] params, Type result): - return Type.MethodType(params, eraseUnboxMethodType(result)); - case TypeRef(_, Symbol clasz, Type[] args): - if (clasz == definitions.ARRAY_CLASS) { - Symbol element = args[0].symbol(); - if (element.isAbstractType()) - if (element.info().symbol() == definitions.ANY_CLASS) - return definitions.ANYREF_CLASS.nextType(); - } - return type.fullErasure(); - default: - throw Debug.abort("illegal case", type); - } - } - - //######################################################################## -} diff --git a/sources/scalac/transformer/ExpandMixinsPhase.java b/sources/scalac/transformer/ExpandMixinsPhase.java deleted file mode 100644 index 969080039a..0000000000 --- a/sources/scalac/transformer/ExpandMixinsPhase.java +++ /dev/null @@ -1,473 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: ExpandMixinsPhase.java,v 1.8 2002/05/02 10:59:35 schinz Exp $ -// $Id$ - -package scalac.transformer; - -import java.util.Arrays; -import java.util.Iterator; -import java.util.Map; -import java.util.HashMap; -import java.util.Set; -import java.util.HashSet; -import java.util.LinkedList; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; -import scalac.CompilationUnit; -import scalac.ast.Tree; -import scalac.ast.Tree.Template; -import scalac.ast.TreeGen; -import scalac.ast.TreeInfo; -import scalac.ast.TreeList; -import scalac.ast.Traverser; -import scalac.ast.Transformer; -import scalac.ast.GenTransformer; -import scalac.ast.GenTreeCloner; -import scalac.symtab.Scope; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Debug; - -import scalac.util.Name; -import scalac.util.Names; -import scalac.symtab.Modifiers; -import scalac.symtab.Scope.SymbolIterator; -import scalac.symtab.SymbolCloner; -import scalac.symtab.SymbolSubstTypeMap; - -// TODO do not copy hidden members which are not accessible via -// "super". - -/** - * A phase to expand mixins using code copying. We assume that links - * to outer classes have been made explicit by a previous phase. - */ -// !!! needs to be cleaned -public class ExpandMixinsPhase extends Phase { - - //######################################################################## - // Private Fields - - /** A map from classes to their interface */ - private final Map/*<Symbol,Symbol>*/ interfaces; - - /** A map from classes to their type transformer */ - private final Map/*<Symbol,TypeTransformer>*/ transformers; - - /** A map from classes to their expanded body */ - private final Map/*<Symbol,Tree[]>*/ expansions; - - /** A map from classes to their original (unexpanded) body */ - private final Map/*<Symbol,Tree[]>*/ bodies; - - /** A map from members to their original member */ - private final Map/*<Symbol,Symbol>*/ origins; - - - /** A transformer that expands classes that have mixins */ - private final GenTransformer expander; - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public ExpandMixinsPhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - Phase addinterfaces = global.PHASE.ADDINTERFACES.phase(); - this.interfaces = ((AddInterfacesPhase)addinterfaces).classToIFace; - this.transformers = new HashMap(); - this.expansions = new HashMap(); - this.bodies = ((AddInterfacesPhase)addinterfaces).classToBody; - this.origins = new HashMap(); - this.expander = new TreeExpander(global); - } - - //######################################################################## - // Public Methods - - /** Applies this phase to the given compilation unit. */ - public void apply(CompilationUnit unit) { - expander.apply(unit); - } - - /** Applies this phase to the given type for the given symbol. */ - public Type transformInfo(Symbol symbol, Type type) { - while (true) { - if (symbol.isJava()) return type; - if (symbol.isInterface()) return type; - if (symbol.isCompoundSym()) return type; // !!! check - if (symbol.isClass()) { - return getTypeExpander(symbol).apply(type); - } - symbol = symbol.isConstructor() - ? symbol.constructorClass() - : symbol.owner(); - } - } - - //######################################################################## - // Private Methods - - //######################################################################## - // Private Class - Tree expander - - /** - * A tree transformer that expands class definitions and removes - * compiled units. - */ - private class TreeExpander extends GenTransformer { - public TreeExpander(Global global) { - super(global); - } - public void apply(CompilationUnit unit) { - if (unit.mixinOnly) { - assert Debug.log("removing unit " + unit); - unit.body = Tree.EMPTY_ARRAY; - } else { - super.apply(unit); - } - } - public Tree transform(Tree tree) { - switch (tree) { - case ClassDef(_, _, _, _, _, _): - Symbol clasz = tree.symbol(); - if (clasz.isInterface()) return super.transform(tree); - return gen.ClassDef(clasz, getExpandedBody(clasz)); - default: - return super.transform(tree); - } - } - } - - //######################################################################## - // Private Class - Tree inliner - - /** - * A Tree cloner that clones mixin bodies. It assumes that these - * bodies have already been expanded. References to mixin value - * parameters are replaced by references to newly-created inlined - * fields. The symbol of Super and This nodes is replaced by the - * symbol of the generated class. The symbol of super members is - * rebound if required. Note that as the input tree has already - * been expanded, it contains only super member to the first - * supertype of the mixin, all other super members have been - * removed during the expansion of the input tree. - */ - private static class TreeInliner extends GenTreeCloner { - private final Symbol clasz; - private final Type supertype; - private boolean initializer; - public TreeInliner(Global global, TypeTransformer transformer) { - super(global, transformer, transformer.cloner); - // !!! global.nextPhase(); - this.clasz = transformer.clasz; - // !!! global.prevPhase(); - this.supertype = clasz.nextInfo().parents()[0]; - } - public Symbol getSymbolFor(Tree tree) { - switch (tree) { - case Select(Super(_, _), _): - if (tree.symbol().isInitializer()) return tree.symbol(); // !!! - assert supertype.symbol().isSubClass(tree.symbol().owner()): - tree + " -- " + Debug.show(clasz); - global.nextPhase(); - Symbol symbol = tree.symbol().overriddenSymbol(supertype); - assert !symbol.isNone(): Debug.show(tree, clasz, supertype); - global.prevPhase(); - return symbol; - case Super(_, _): - case This(_): - return clasz; - default: - return super.getSymbolFor(tree); - } - } - public Tree transform(Tree tree) { - switch (tree) { - case ValDef(_, _, _, _): - if (tree.symbol().hasStaticAttribute()) - return Tree.Empty; - break; - case DefDef(_, _, _, _, _, _): - Symbol symbol = getSymbolFor(tree); - if (symbol.owner() != clasz || symbol.hasStaticAttribute()) - return Tree.Empty; - if (symbol.isInitializer()) initializer = true; - tree = super.transform(tree); - initializer = false; - return tree; - case Apply(Select(Super(_, _), _), _): - if (TreeInfo.methSymbol(tree).isInitializer() && !initializer) - return Tree.Empty; - break; - } - if (tree.hasSymbol() && tree.symbol().isParameter()) { - Symbol symbol = getSymbolFor(tree); - if (!symbol.isParameter()) { - assert tree instanceof Tree.Ident: tree; - return gen.Select(gen.This(tree.pos, clasz), symbol); - } - } - return super.transform(tree); - } - } - - //######################################################################## - // Private Class - Class tree expander - - /** - * A tree transformer that expands a class definitions. Super - * members are rebound and/or rewritten into normal members. - */ - private class ClassTreeExpander extends TreeExpander { - private final Symbol clasz; - private final Type[] parents; - private final Map clones; - public ClassTreeExpander(Global global, TypeTransformer transformer) { - super(global); - this.clasz = transformer.clasz; - this.parents = clasz.parents(); - this.clones = transformer.cloner.clones; - } - private Symbol getSuperMember(Symbol member) { - for (int i = 0; i < parents.length; i++) { - global.nextPhase(); - if (!parents[i].symbol().isSubClass(member.owner())) { - global.prevPhase(); // !!! - continue; - } - Symbol override = member.overridingSymbol(parents[i]); - global.prevPhase(); - assert !override.isNone(): - Debug.show(member, clasz, parents[i]); - if (i == 0) return override; - Symbol clone = (Symbol)clones.get(override); - assert clone != null: Debug.show(member, override, clasz); - return clone; - } - // !!! double loop - for (int i = 0; i < parents.length; i++) { - if (!parents[i].symbol().isSubClass(member.owner())) continue; - //global.nextPhase(); - Symbol override = member.overridingSymbol(parents[i]); - //global.prevPhase(); - assert !override.isNone(): - Debug.show(member, clasz, parents[i]); - if (i == 0) return override; - Symbol clone = (Symbol)clones.get(override); - assert clone != null: Debug.show(member, override, clasz); - return clone; - } - throw Debug.abort(Debug.show(member, clasz)); - } - public Tree transform(Tree tree) { - switch (tree) { - case Select(Super(_, _), _): - Symbol symbol = getSuperMember(tree.symbol()); - Tree qualifier = symbol.owner() == clasz - ? gen.This(tree.pos, clasz) - : gen.Super(tree.pos, clasz); - return gen.Select(tree.pos, qualifier, symbol); - default: - return super.transform(tree); - } - } - } - - - - - - - - - - - - - - - - /** Returns the type transformer to use for the given class. */ - private TypeTransformer getTypeExpander(Symbol clasz) { // !!! - assert clasz.isClass() && !clasz.isInterface(): Debug.show(clasz); - TypeTransformer transformer =(TypeTransformer)transformers.get(clasz); - if (transformer == null) { - transformer = new TypeTransformer(clasz); - transformers.put(clasz, transformer); - } - return transformer; - } - - /** Returns the expanded body of the given clasz. */ - private Tree[] getExpandedBody(Symbol clasz) { - Tree[] body = (Tree[])expansions.get(clasz); - if (body == null) { - body = (Tree[])bodies.remove(clasz); - assert body != null: Debug.show(clasz); - TypeTransformer transformer = getTypeExpander(clasz); - TreeList list = new TreeList(); - assert Debug.log("expanding tree ", clasz); - Type[] parents = clasz.parents(); - TreeInliner inliner = new TreeInliner(global, transformer); - for (int i = 1; i < parents.length; i++) { - Symbol mixin = parents[i].symbol(); - if (mixin.isInterface()) continue; - assert Debug.log("expanding tree ", clasz, ": inlining ", mixin); - list.append(inliner.transform(getExpandedBody(mixin))); - } - ClassTreeExpander expander = new ClassTreeExpander(global, transformer); - list.append(expander.transform(body)); - body = list.toArray(); - expansions.put(clasz, body); - } - return body; - } - - //######################################################################## - // Private Class - Collector - - private class TypeTransformer extends Type.MapOnlyTypes { - - public final Symbol clasz; - public final Type[] parents; - public final SymbolCloner cloner; - public final Map/*<Symbol,Type>*/ inlines; - - public TypeTransformer(Symbol clasz) { - this.clasz = clasz; - this.parents = clasz.parents(); - this.cloner = new SymbolCloner(); - this.inlines = new HashMap(); - initialize(); - } - - private void initialize() { - Type[] parents = clasz.parents(); - // !!! parents.length > 0 - if (parents.length > 0) parents[0].symbol().nextInfo(); // force - assert Debug.log("expanding type ", clasz); - for (int i = parents.length - 1; 0 < i; i--) { - switch (parents[i]) { - case TypeRef(Type prefix, Symbol mixin, Type[] args): - if (mixin.isInterface()) continue; - mixin.nextInfo(); // force - assert Debug.log("expanding type ", clasz, ": inlining ", mixin); - cloner.owners.put(mixin, clasz); - cloner.owners.put(mixin.primaryConstructor(), clasz); - // map mixin type parameters to mixin type arguments - Symbol[] tparams = mixin.typeParams(); - for (int j = 0; j < tparams.length; j++) - inlines.put(tparams[j], args[j]); - - createMixedInMemberSymbols(mixin.nextInfo().members()); - } - } - Set clones = new HashSet(cloner.clones.keySet()); -// cloner.clones.putAll(getTypeTransformerFor(parents[0].symbol()).cloner.clones); // !!! build closure - - // !!! remove ? - for (Iterator i = cloner.clones.values().iterator(); i.hasNext();){ - // !!! for (Iterator i = clones.iterator(); i.hasNext();){ - Symbol clone = (Symbol)i.next(); - clone.setInfo(apply(clone.info())); - } - } - - private Symbol getMemberOrigin(Symbol member) { - Object origin = origins.get(member); - return origin == null ? member : (Symbol)origin; - } - - private void createMixedInMemberSymbols(Scope symbols) { - Scope scope = clasz.members(); - for (SymbolIterator i = symbols.iterator(); i.hasNext();) { - Symbol member = i.next(); - boolean shadowed = member.isPrivate() || member.isInitializer() - || member.overridingSymbol(clasz.thisType()) != member; - Symbol origin = getMemberOrigin(member); - if (!shadowed && origin != null) { - Symbol overridden = member.overriddenSymbol(parents[0]); - if (origin == getMemberOrigin(overridden)) { - cloner.clones.put(member, overridden); - continue; - } - } - // !!! when the symbol is shadowed, inlining could be - // avoided if the original definition is accessible - // through super - assert Debug.log("expanding type ", clasz, ": cloning ", member); - Symbol clone = cloner.cloneSymbol(member); - if (shadowed) clone.name = Names.MIXIN(member); - if (shadowed) clone.flags &= ~Modifiers.OVERRIDE; - if (shadowed) clone.flags &= ~Modifiers.ACCESSFLAGS; - if (shadowed) clone.flags |= Modifiers.PRIVATE; - scope.enterOrOverload(clone); - origins.put(clone, origin != null ? origin : member); - } - } - - - public Type apply(Type type) { - switch (type) { - case TypeRef(Type prefix, Symbol symbol, Type[] args): - Type inline = (Type)inlines.get(symbol); - if (inline != null) return inline; - if (symbol.isParameter()) { - Symbol clone = (Symbol)cloner.clones.get(symbol); - if (clone != null) { - assert prefix == Type.NoPrefix && args.length == 0: - type; - return Type.typeRef(prefix, clone, args); - } - } - return map(type); - case SingleType(Type prefix, Symbol symbol): - Symbol clone = (Symbol)cloner.clones.get(symbol); - prefix = apply(prefix); - return Type.singleType(prefix, clone != null ? clone : symbol); - case ThisType(_): - return clasz.thisType(); - case CompoundType(Type[] parents, Scope members): - if (type.symbol() != clasz) return map(type); - if (parents.length <= 1) return type; - Symbol iface = (Symbol)interfaces.get(clasz); - if (iface == null) { - int i = 1; - while (i < parents.length && parents[i].symbol().isInterface()) i++; - if (i == parents.length) return type; - parents = Type.cloneArray(parents); - while (i < parents.length) { - if (!parents[i].symbol().isInterface()) - parents[i] = Type.typeRef(parents[i].prefix(), (Symbol)interfaces.get(parents[i].symbol()), parents[i].typeArgs()); - i++; - } - return Type.compoundType(parents, members, clasz); - } - assert parents[parents.length - 1].symbol() == iface: type; - if (parents.length == 2) return type; - for (int i = 1; i < parents.length - 1; i++) { - Symbol mixin = parents[i].symbol(); - Symbol imix = mixin.isInterface() - ? mixin - : (Symbol)interfaces.get(mixin); - assert iface.isSubClass(imix): type+" - "+i; - } - parents = new Type[] {parents[0], parents[parents.length - 1]}; - return Type.compoundType(parents, members, clasz); - default: - return map(type); - } - } - - } - - //######################################################################## -} diff --git a/sources/scalac/transformer/ExplicitOuterClassesPhase.java b/sources/scalac/transformer/ExplicitOuterClassesPhase.java deleted file mode 100644 index b1b05832a1..0000000000 --- a/sources/scalac/transformer/ExplicitOuterClassesPhase.java +++ /dev/null @@ -1,558 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.transformer; - -import java.util.Collections; -import java.util.Map; -import java.util.HashMap; -import java.util.Iterator; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; -import scalac.CompilationUnit; -import scalac.ast.GenTransformer; -import scalac.ast.Tree; -import scalac.ast.Tree.Template; -import scalac.symtab.Modifiers; -import scalac.symtab.Scope; -import scalac.symtab.Symbol; -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 type, adds to each of its constructor a new type - * parameter for every type parameter appearing in outer types. - * - * - In every class, adds a forwarding "super" method for every method - * that is accessed via "super" in a nested class. - * - * - Replaces all prefixes of TypeRefs by localThisTypes. - * - * - Adds all missing qualifiers. - */ -// !!! needs to be cleaned -public class ExplicitOuterClassesPhase extends Phase { - - //######################################################################## - // Private Fields - - /** A map from constructor symbols to type transformers */ - private final Map/*<Symbol,TypeTransformer>*/ transformers = new HashMap(); - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public ExplicitOuterClassesPhase(Global global,PhaseDescriptor descriptor){ - super(global, descriptor); - } - - //######################################################################## - // Public Methods - - /** Applies this phase to the given compilation unit. */ - public void apply(CompilationUnit unit) { - treeTransformer.apply(unit); - } - - /** Applies this phase to the given type for the given symbol. */ - public Type transformInfo(Symbol symbol, Type type) { - if (symbol.isConstructor()) { - Symbol clasz = symbol.constructorClass(); - if (clasz.isClass() && !clasz.isCompoundSym()) - return transformInfo(clasz, symbol, type); - } - return getTypeTransformerFor(symbol).apply(type); - } - - //######################################################################## - // Private Methods - - /** - * 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(); - // !!! isClassType -> isClass ? - if (test.isClassType() && !test.isCompoundSym()) break; - symbol = symbol.owner(); - } -// !!! -// while (!symbol.isClassType() && !(symbol.isConstructor() && symbol.constructorClass().isClassType())) // !!! isClassType -> isClass ? -// symbol = symbol.owner(); - if (symbol.isClassType()) - symbol = symbol.primaryConstructor(); - if (symbol.constructorClass().isPackageClass()) - return topLevelTypeTransformer; - TypeTransformer context = (TypeTransformer)transformers.get(symbol); - if (context == null) { - symbol.nextInfo(); - context = (TypeTransformer)transformers.get(symbol); - assert context != null: Debug.show(symbol); - } - return context; - } - - //######################################################################## - // Private Functions - - /** - * Returns the depth of the specified class. The depth of a class - * is: - * - -1 for a package class - * - 0 for a top-level class - * - the depth of the enclosing class plus 1 for an inner class - */ - private static int getClassDepth(Symbol clasz) { - assert clasz.isClass() || clasz.isPackageClass(): Debug.show(clasz); - int depth = -1; - while (!clasz.isPackageClass()) { clasz = clasz.owner(); depth++; } - return depth; - } - - /** - * Returns the type arguments of the flattened version of the - * specified type reference. This functions takes and returns - * non-transformed types. - */ - private static Type[] getFlatArgs(Type prefix, Symbol clasz, Type[] args) { - int depth = getClassDepth(clasz); - if (depth <= 0) return args; - Type[] prefixes = new Type[depth]; - Type[][] argss = new Type[depth][]; - int count = collect(prefix, clasz, prefixes, argss); - args = Type.cloneArray(count, args); - for (int i = 0, o = 0; i < depth; i++) { - for (int j = 0; j < argss[i].length; j++) - args[o++] = argss[i][j]; - args[o++] = prefixes[i]; - } - return args; - } - // where - private static int collect(Type prefix, Symbol clasz, Type[] prefixes, - Type[][] argss) - { - int count = prefixes.length; - for (int i = prefixes.length - 1; i >= 0; i--) { - prefixes[i] = prefix; - Symbol owner = clasz.owner(); - Type base = prefix.baseType(owner); - switch (base) { - case TypeRef(Type type, Symbol symbol, Type[] args): - assert symbol == owner: Debug.show(base); - count += args.length; - argss[i] = args; - prefix = type; - clasz = owner; - continue; - default: - throw Debug.abortIllegalCase(base); - } - } - return count; - } - - //######################################################################## - // 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 { - - private final Map/*<Symbol,Type>*/ tparams; - - public TypeTransformer(Map tparams) { - this.tparams = tparams; - } - - public Type apply(Type type) { - switch (type) { - case TypeRef(Type prefix, Symbol symbol, Type[] args): - if (symbol.isParameter() && symbol.owner().isConstructor()) { - assert prefix == Type.NoPrefix: type; - assert args.length == 0: type; - Object value = tparams.get(symbol); - return value != null ? (Type)value : type; - } - if (symbol.isClass() && !symbol.isCompoundSym()) { - args = map(getFlatArgs(prefix, symbol, args)); - prefix = Type.NoPrefix; - return Type.typeRef(prefix, symbol, args); - } - if (symbol.isPackageClass()) { - args = Type.EMPTY_ARRAY; - prefix = Type.NoPrefix; - return Type.typeRef(prefix, symbol, args); - } - return Type.typeRef(apply(prefix), symbol, map(args)); - case SingleType(Type prefix, Symbol symbol): - if (symbol.owner().isPackageClass()) - return Type.singleType(Type.NoPrefix, symbol); - return Type.singleType(apply(prefix), symbol); - case ThisType(Symbol clasz): - Object value = tparams.get(clasz); - if (value != null) return (Type)value; - assert clasz.isCompoundSym() || clasz.isPackageClass(): - Debug.show(clasz); - return type; - case CompoundType(Type[] parents, Scope members): - // !!! this case should not be needed - return Type.compoundType(map(parents), members, type.symbol()); - default: - return map(type); - } - } - - } - - //######################################################################## - // Private Class - Tree transformer - - /** The tree transformer */ - private final GenTransformer treeTransformer = new GenTransformer(global) { - - /** The current context */ - private Context context; - - /** The current method */ - private Symbol method; - - /** Transforms the given type. */ - public Type transform(Type type) { - return context.transformer.apply(type); - } - - /** Transforms the given tree. */ - public Tree transform(Tree tree) { - if (global.debug) global.log("transforming " + tree);//debug - switch (tree) { - - case ClassDef(_, _, _, _, _, Template impl): - Symbol clasz = tree.symbol(); - context = new Context(context, clasz, new HashMap(), new HashMap()); - Tree[] parents = transform(impl.parents); - Tree[] body = transform(impl.body); - body = Tree.concat(body, genAccessMethods(false)); - body = Tree.concat(body, genAccessMethods(true)); - if (context.vfield != null) { - body = Tree.cloneArray(1, body); - body[0] = gen.ValDef( - context.vfield, - gen.Ident(context.vfield.pos, context.vparam)); - } - context = context.outer; - return gen.ClassDef(clasz, parents, impl.symbol(), body); - - case DefDef(_, _, _, _, _, Tree rhs): - Symbol method = tree.symbol(); - Context backup = context; - if (method.isConstructor()) - context = context.getConstructorContext(method); - this.method = method; - rhs = transform(rhs); - this.method = null; - context = backup; - return gen.DefDef(method, rhs); - - 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); - } - return super.transform(tree); - - case This(_): - return genOuterRef(tree.pos, tree.symbol()); - - case Select(Tree qualifier, _): - Symbol symbol = tree.symbol(); - if (symbol.owner().isStaticOwner()) // !!! qualifier ignored - return gen.mkGlobalRef(tree.pos, symbol); - Symbol access; - switch (qualifier) { - case Super(_, _): - Symbol clasz = qualifier.symbol(); - if (clasz == context.clasz) { - access = symbol; - qualifier = gen.Super(tree.pos, qualifier.symbol()); - } else { - access = getAccessSymbol(symbol, clasz); - qualifier = genOuterRef(qualifier.pos, clasz); - } - break; - default: - access = getAccessSymbol(symbol, null); - qualifier = transform(qualifier); - break; - } - tree = gen.Select(tree.pos, qualifier, access); - if (access != symbol && !symbol.isMethod()) - tree = gen.mkApply__(tree); - return tree; - - default: - return super.transform(tree); - } - } - - /* Add outer type and value arguments to constructor calls. */ - private Tree transform(Tree vapply, Tree[] vargs, Tree tapply, - Tree[] targs, Tree tree) - { - switch (tree) { - case Select(Tree qualifier, _): - Symbol symbol = tree.symbol(); - Symbol clasz = symbol.constructorClass(); - if (getClassDepth(clasz) > 0) { - Type[] types = Tree.typeOf(targs); - types = getFlatArgs(qualifier.type(), clasz, types); - targs = gen.mkTypes(tapply.pos, types); - vargs = Tree.cloneArray(1, vargs); - vargs[0] = qualifier; - } else { - assert !containsValue(qualifier): tree; - } - tree = gen.Ident(tree.pos, symbol); - if (targs.length != 0) - tree = gen.TypeApply(tapply.pos, tree, transform(targs)); - return gen.Apply(vapply.pos, tree, transform(vargs)); - default: - throw Debug.abortIllegalCase(tree); - } - } - - /** - * Returns the symbol to access the specified member from the - * current context. If "svper" is non null, the member is - * selected from the superclass of the specified class. The - * returned symbol may be the same as the given one. - */ - private Symbol getAccessSymbol(Symbol member, Symbol svper) { - if (member.isPublic() && svper == null) return member; - Context context = this.context; - 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; - Map table = svper != null ? context.supers : context.selfs; - Symbol access = (Symbol)table.get(member); - if (access == null) { - // !!! generate static access methods ? - Name name = Names.ACCESS(member, svper != null); - access = context.clasz.newAccessMethod(context.clasz.pos,name); - global.nextPhase(); - Type info = member.isMethod() - ? member.info().cloneType(member, access) - : Type.MethodType(Symbol.EMPTY_ARRAY, member.info()); - access.setInfo(info); - global.prevPhase(); - table.put(member, access); - context.clasz.nextInfo().members().enter(access); - assert Debug.log("created access method: ", access); - } - return access; - } - - /** Generates the trees of the access methods. */ - private Tree[] genAccessMethods(boolean withSuper) { - Map table = withSuper ? context.supers : context.selfs; - if (table.size() == 0) return Tree.EMPTY_ARRAY; - Tree[] trees = new Tree[table.size()]; - Iterator entries = table.entrySet().iterator(); - for (int i = 0; i < trees.length; i++) { - Map.Entry entry = (Map.Entry)entries.next(); - Symbol member = (Symbol)entry.getKey(); - Symbol access = (Symbol)entry.getValue(); - int pos = access.pos; - Tree qualifier = withSuper - ? gen.Super(pos, context.clasz) - : gen.This(pos, context.clasz); - Tree select = gen.Select(qualifier, member); - Tree[] targs = gen.mkTypeRefs(pos, access.nextTypeParams()); - Tree[] vargs = gen.mkLocalRefs(pos, access.nextValueParams()); - Tree body = member.isMethod() - ? gen.mkApplyTV(select, targs, vargs) - : select; - trees[i] = gen.DefDef(access, body); - } - 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 = 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)); - } - } - - /** Tests whether the tree contains some value computation. */ - private boolean containsValue(Tree tree) { - switch (tree) { - case This(_): - return !tree.symbol().isPackageClass(); - case Select(Tree qualifier, _): - return containsValue(qualifier) || tree.symbol().isValue(); - default: - return false; - } - } - - }; - - //######################################################################## - // Private Class - Tree transformer context - - /** This class represents the tree transformation context. */ - private class Context { - - /** The outer context */ - public final Context outer; - /** 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; - /** 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; - - /** Initializes this instance. */ - 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. */ - public Context getConstructorContext(Symbol constructor) { - assert constructor.constructorClass() == clasz; - return new Context(outer, constructor, selfs, supers); - } - - /** - * Returns the outer value field. The field is created on the - * 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; - vfield = clasz.newField(clasz.pos, flags, Names.OUTER(clasz)); - vfield.setInfo(outer.clasz.thisType()); - clasz.members().enterNoHide(vfield); - } - return vfield; - } - - } - - //######################################################################## -} diff --git a/sources/scalac/transformer/ICodePhase.java b/sources/scalac/transformer/ICodePhase.java deleted file mode 100644 index 3274897641..0000000000 --- a/sources/scalac/transformer/ICodePhase.java +++ /dev/null @@ -1,42 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.transformer; - -import ch.epfl.lamp.util.CodePrinter; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; -import scalac.CompilationUnit; - -/** - * This class represents the ICode phase for the java version - * of the compiler. It doesn't do anything but permit to make - * a bridge between the java implementation of Socos et the - * scala one. See scala.tools.scalac.icode.ICodePhase for - * implementation - */ -public abstract class ICodePhase extends Phase { - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public ICodePhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - } - - //######################################################################## - // Public Methods - - /** Prints the given compilation units. */ - public abstract void print(CompilationUnit[] units, CodePrinter printer); - - //######################################################################## -} diff --git a/sources/scalac/transformer/LambdaLift.java b/sources/scalac/transformer/LambdaLift.java deleted file mode 100644 index fdf14e8d9b..0000000000 --- a/sources/scalac/transformer/LambdaLift.java +++ /dev/null @@ -1,763 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.transformer; - -import java.io.*; -import java.util.HashMap; - -import scalac.*; -import scalac.ast.*; -import scalac.symtab.*; -import scalac.util.*; -import Tree.*; - - -/** A lambda lifting transformer - * - * @author Martin Odersky - * @version 1.0 - * - * What it does: - * Lift every class and function that's contained in another function - * out to be a member to the next enclosing class. - * Pass free variables and type variables as parameters to class constructors. - * Variables and values that are free in some function or class - * are given new unique names. - * Free mutable variables are converted to reference cells. - * All types are updated so that proxies are passed for additional free - * type variables. - */ -public class LambdaLift extends OwnerTransformer - implements Modifiers, Kinds { - - final Global global; - final Definitions definitions; - final FreeVars free; - final LambdaLiftPhase descr; - private CompilationUnit unit; - - public LambdaLift(Global global, LambdaLiftPhase descr) { - super(global); - this.global = global; - this.definitions = global.definitions; - this.free = new FreeVars(global); - this.descr = descr; - } - - public void apply(CompilationUnit unit) { - this.unit = unit; - global.log(unit.source.toString()); - free.initialize(unit); - currentOwner = global.definitions.ROOT_CLASS; - unit.body = transformTemplateStats(unit.body, currentOwner); - } - - /** If `sym' is a class, return its primary constructor; - * otherwise current symbol itself - * - * @param sym - * @return - */ - static Symbol asFunction(Symbol sym) { - return sym.kind == CLASS ? sym.primaryConstructor() : sym; - } - - /** Is symbol local relative to owner? - * Primary constructor parameters are local iff owner (contained in) - * the primary constructor. - * - * @param sym - * @param owner - * @return <code>true</code> if the symbol <code>sym</code> - * is local relative to <code>owner</code> - */ - static boolean isLocal(Symbol sym, Symbol owner) { - if (sym.isParameter() && - sym.owner().isPrimaryConstructor() && - sym.owner().constructorClass().kind == CLASS && - !(owner.isParameter() && owner.owner() == sym)) { - Symbol encl = sym.owner().owner(); - Symbol clazz = sym.owner().constructorClass(); - //System.out.println("isLocal " + sym + " " + encl + " " + clazz + " " + owner);//DEBUG - while (owner != encl && - owner.kind != NONE && - owner != clazz) { - owner = owner.owner(); - //System.out.println(":" + owner);//DEBUG - } - return owner != clazz; - } - return sym.isLocal(); - } - - /** Propagate free variables from all called functions. - * `asFunction' applied to the next enclosing function or class owner. - * - * @param owner - * @return - */ - static Symbol enclFun(Symbol owner) { - Symbol sym = owner; - while (!asFunction(sym).isMethod()) sym = sym.owner(); - return asFunction(sym); - } - - /** Return SymSet from a hashmap. - * - * @param f - * @param sym - * @return - */ - private static SymSet get(HashMap f, Symbol sym) { - SymSet ss = (SymSet) f.get(sym); - return ss == null ? SymSet.EMPTY : ss; - } - - /** Compute free variables map `fvs'. - * Also assign unique names to all - * value/variable/let symbols that are free in some function or class, and to - * all class/function symbols that are owned by some function. - */ - static class FreeVars extends OwnerTransformer { - - private CompilationUnit unit; - - public FreeVars(Global global) { - super(global); - } - - /** A hashtable storing free variables of functions and class constructors. - */ - private HashMap/*<Symbol,SymSet>*/ fvs; - - /** A hashtable storing free type variables of functions and class constructors. - */ - private HashMap/*<Symbol,SymSet>*/ ftvs; - - /** A hashtable storing calls between functions and class constructors - */ - private HashMap/*<Symbol,SymSet>*/ called; - - /** The set of symbols that need to be renamed. - */ - private SymSet renamable; - - /** The set of symbols that bound by polytypes - * and therefore are not free type variables. - */ - private SymSet excluded; - - /** A flag to indicate whether new free variables have been found - */ - private boolean changedFreeVars; - - /** A flag to indicate whether we are in propagation phase - * (used in assertion). - */ - private boolean propagatePhase; - - /** Insert `sym' into the set of free variables of `owner' - * - * @param owner - * @param sym - */ - private void putFree(Symbol owner, Symbol sym) { - assert owner.isLocal(); - HashMap f = sym.isType() ? ftvs : fvs; - SymSet ss = get(f, owner); - if (!ss.contains(sym)) { - f.put(owner, ss.incl(sym)); - changedFreeVars = true; - if (global.debug) global.log(sym + " is free in " + owner); - } - } - - /** Insert `to' into the set of functions called by `from' - * - * @param from - * @param to - */ - private void putCall(Symbol from, Symbol to) { - SymSet ss = get(called, from); - if (!ss.contains(to)) { - called.put(from, ss.incl(to)); - } - } - - /** Mark symbol `sym' as being free in `owner', unless `sym' - * is defined in `owner' or there is a class between `owner's owner - * and the owner of `sym'. - * Return `true' if there is no class between `owner' and - * the owner of sym. - * - * @param sym - * @param owner - * @return - */ - private boolean markFree(Symbol sym, Symbol owner) { - if (global.debug) - global.log("mark " + sym + " of " + sym.owner() + - " free in " + owner);//debug - if (owner.kind == NONE) { - assert propagatePhase : sym + " in " + sym.owner(); - return false; - } else if (sym.owner() == owner) { - return true; - } else if (markFree(sym, owner.owner())) { - Symbol fowner = asFunction(owner); - if (fowner.isMethod()) { - putFree(fowner, sym); - renamable = renamable.incl(sym); - if (sym.isVariable()) sym.flags |= CAPTURED; - } - return owner.kind != CLASS; - } else { - return false; - } - } - - /** Assign unique name to symbol. - * If symbol is a class assign same name to its primary constructor. - */ - private void makeUnique(Symbol sym) { - sym.name = unit.fresh.newName(sym.name); - } - - private Type.Map traverseTypeMap = new Type.Map() { - public Type apply(Type tp) { - if (global.debug) global.log("traverse " + tp);//debug - switch (tp) { - case TypeRef(NoPrefix, Symbol sym, Type[] targs): - if (isLocal(sym, currentOwner) && - sym.kind == TYPE && - !excluded.contains(sym)) - markFree(sym, currentOwner); - break; - case SingleType(NoPrefix, Symbol sym): - if (isLocal(sym, currentOwner)) - markFree(sym, currentOwner); - break; - case PolyType(Symbol[] tparams, Type restp): - for (int i = 0; i < tparams.length; i++) - excluded = excluded.incl(tparams[i]); - Type tp1 = super.map(tp); - for (int i = 0; i < tparams.length; i++) - excluded = excluded.excl(tparams[i]); - return tp1; - } - return map(tp); - } - }; - - public Tree transform(Tree tree) { - if (global.debug) global.log("free " + tree);//debug - assert tree.type != null : tree; - traverseTypeMap.apply(tree.type.widen()); - Symbol sym = tree.symbol(); - switch(tree) { - case ClassDef(_, _, _, _, _, _): - case DefDef(_, _, _, _, _, _): - if (sym.isLocal()) { - renamable = renamable.incl(sym); - } - return super.transform(tree); - - case AbsTypeDef(int mods, Name name, Tree rhs, Tree lobound): - // ignore type definition as owner. - // reason: it might be in a refinement - // todo: handle type parameters? - return copy.AbsTypeDef( - tree, sym, - transform(rhs, currentOwner), - transform(lobound, currentOwner)); - - case AliasTypeDef(int mods, Name name, AbsTypeDef[] tparams, Tree rhs): - // ignore type definition as owner. - // reason: it might be in a refinement - // todo: handle type parameters? - return copy.AliasTypeDef( - tree, sym, - transform(tparams, currentOwner), - transform(rhs, currentOwner)); - - case Ident(_): - if (isLocal(sym, currentOwner)) { - if (sym.isMethod()) { - Symbol f = enclFun(currentOwner); - if (f.name.length() > 0) // it is not a template function { - putCall(f, sym); - } else if (sym.kind == VAL || sym.kind == TYPE) { - markFree(sym, currentOwner); - } - } - return tree; - - default: - return super.transform(tree); - } - } - - /** Propagate free fariables from all called functions. - * - * @param fvs - */ - void propagateFvs(HashMap fvs) { - Object[] fs = called.keySet().toArray(); - for (int i = 0; i < fs.length; i++) { - Symbol f = (Symbol) fs[i]; - Symbol[] calledFromF = get(called, f).toArray(); - for (int j = 0; j < calledFromF.length; j++) { - //System.out.println(f + " calls " + calledFromF[j]);//DEBUG - Symbol[] newFvs = get(fvs, calledFromF[j]).toArray(); - for (int k = 0; k < newFvs.length; k++) { - markFree(newFvs[k], f); - } - } - } - } - - /** This method re-enters all free variables into their free variable - * sets. This is necessary because the names of these variables (and - * therefore their `isLess' order have changed. - * - * @param fvs - */ - private void restoreFvs(HashMap fvs) { - Object[] fs = fvs.keySet().toArray(); - for (int i = 0; i < fs.length; i++) { - Symbol f = (Symbol) fs[i]; - Symbol[] elems = get(fvs, f).toArray(); - SymSet elems1 = SymSet.EMPTY; - for (int j = 0; j < elems.length; j++) - elems1 = elems1.incl(elems[j]); - fvs.put(f, elems1); - } - } - - /** Compute a mapping from symbols to their free variables - * in hashtable `fvs'. Also rename all variables that need it. - * - * @param unit - */ - public void initialize(CompilationUnit unit) { - this.unit = unit; - fvs = new HashMap(); - ftvs = new HashMap(); - called = new HashMap(); - renamable = SymSet.EMPTY; - excluded = SymSet.EMPTY; - apply(unit); - - propagatePhase = true; - do { - changedFreeVars = false; - propagateFvs(fvs); - propagateFvs(ftvs); - } while (changedFreeVars); - - Symbol[] ss = renamable.toArray(); - for (int i = 0; i < ss.length; i++) { - makeUnique(ss[i]); - } - - restoreFvs(fvs); - restoreFvs(ftvs); - } - } - - private TreeList liftedDefs; - - /** Transform template and add lifted definitions to it. - * - * @param stats - * @param tsym - * @return - */ - public Tree[] transformTemplateStats(Tree[] stats, Symbol tsym) { - TreeList prevLiftedDefs = liftedDefs; - liftedDefs = new TreeList(); - TreeList stats1 = new TreeList(super.transformTemplateStats(stats, tsym)); - stats1.append(liftedDefs); - liftedDefs = prevLiftedDefs; - return stats1.toArray(); - } - - /** ... - * - * @param tree - */ - public Tree transform(Tree tree) { - //global.debugPrinter.print("lifting ").print(tree).println().end();//DEBUG - //System.out.print(tree.type + " --> ");//DEBUG - tree.type = descr.transform(tree.type, currentOwner); - //System.out.println(tree.type);//DEBUG - switch (tree) { - case Block(Tree[] stats, Tree value): - for (int i = 0; i < stats.length; i++) - liftSymbol(stats[i]); - return copy.Block(tree, transform(stats), transform(value)); - - case ClassDef(int mods, _, AbsTypeDef[] tparams, ValDef[][] vparams, Tree tpe, Template impl): - Symbol sym = tree.symbol(); - if ((mods & LIFTED) != 0) { - ((ClassDef) tree).mods &= ~LIFTED; - Tree tree1 = copy.ClassDef( - tree, sym, - addTypeParams(transform(tparams, sym), newtparams(sym.primaryConstructor())), - new ValDef[][]{ - addParams(transform(vparams, sym)[0], newparams(sym.primaryConstructor()))}, - transform(tpe, sym), - transform(impl, sym)); - liftedDefs.append(tree1); - return Tree.Empty; - } else { - assert !sym.isLocal() : sym; - return copy.ClassDef( - tree, sym, - transform(tparams, sym), - transform(vparams, sym), - transform(tpe, sym), - transform(impl, sym)); - } - - case DefDef(int mods, _, AbsTypeDef[] tparams, ValDef[][] vparams, Tree tpe, Tree rhs): - Symbol sym = tree.symbol(); - if ((mods & LIFTED) != 0) { - ((DefDef) tree).mods &= ~LIFTED; - Tree tree1 = copy.DefDef( - tree, sym, - addTypeParams(transform(tparams, sym), newtparams(sym)), - new ValDef[][]{ - addParams(transform(vparams, sym)[0], newparams(sym))}, - transform(tpe, sym), - transform(rhs, sym)); - liftedDefs.append(tree1); - return Tree.Empty; - } else { - assert !sym.isLocal() : sym; - return copy.DefDef( - tree, sym, - transform(tparams, sym), transform(vparams, sym), transform(tpe, sym), - transform(rhs, sym)); - } - - case AbsTypeDef(int mods, Name name, Tree rhs, Tree lobound): - // ignore type definition as owner. - // reason: it might be in a refinement - // todo: handle type parameters? - return copy.AbsTypeDef( - tree, tree.symbol(), - transform(rhs, currentOwner), - transform(lobound, currentOwner)); - - case AliasTypeDef(int mods, Name name, AbsTypeDef[] tparams, Tree rhs): - // ignore type definition as owner. - // reason: it might be in a refinement - // todo: handle type parameters? - return copy.AliasTypeDef( - tree, tree.symbol(), - transform(tparams, currentOwner), - transform(rhs, currentOwner)); - - case ValDef(_, _, _, Tree rhs): - Symbol sym = tree.symbol(); - rhs = transform(rhs, sym); - if (sym.isCaptured()) { - assert sym.isLocal(); - switch (sym.nextType()) { - case TypeRef(_, Symbol clasz, Type[] args): - Tree constr = gen.mkPrimaryConstructorGlobalRef(rhs.pos, clasz); - rhs = gen.New(gen.mkApplyTV(constr, args, new Tree[]{rhs})); - break; - default: - throw Debug.abort("illegal case", sym.nextType()); - } - } - return gen.ValDef(sym, rhs); - - case Sequence(Tree[] args): - throw new ApplicationError("this should not happen"); - /* // moved this to Uncurry - Tree tree1 = gen.mkNewList(tree.pos, tree.type.typeArgs()[0], transform(args)); - //System.out.println("TUPLE: " + tree + "\n ==> \n" + tree1);//DEBUG - return tree1; - */ - - case Return(Block(Tree[] stats, Tree value)): - return transform( - gen.Block(stats, gen.Return(tree.pos, tree.symbol(), value))); - - case Return(Tree expr): - if (tree.symbol() != currentOwner.enclMethod()) { - unit.error(tree.pos, "non-local return not yet implemented"); - } - return super.transform(tree); - - case Apply(Tree fn, Tree[] args): - Symbol fsym = TreeInfo.methSymbol(fn); - Tree fn1 = transform(fn); - switch (fn1) { - case TypeApply(Tree fn2, Tree[] targs): - //if (args.length == 1 && fn2.symbol() == definitions.PREDEF_ARRAY()) { - // throw new ApplicationError("this should not happen"); - /* // this moved to UnCurry - switch (args[0]) { - case Sequence(Tree[] items): - assert targs.length == 1: tree; - Tree array = gen.mkNewArray( - args[0].pos, - targs[0].type(), - transform(items), - currentOwner); - // fn2 may be like "{ println("hello"); Predef}.Array" - switch (fn2) { - case Select(Tree qualifier, _): - return gen.mkBlock(args[0].pos, qualifier, array); - default: - throw Debug.abort("illegal case", fn2); - } - } - */ - //} - fn1 = copy.TypeApply( - fn1, fn2, addFreeArgs(tree.pos, get(free.ftvs, fsym), targs, true)); - break; - default: - Tree[] targs = addFreeArgs( - tree.pos, get(free.ftvs, fsym), Tree.EMPTY_ARRAY, true); - if (targs.length > 0) - fn1 = gen.TypeApply(fn1, targs); - } - Tree[] args1 = transform(args); - return copy.Apply( - tree, fn1, addFreeArgs(tree.pos, get(free.fvs, fsym), args1, false)); - - case Ident(_): - Symbol sym = tree.symbol(); - if (isLocal(sym, currentOwner) && - (sym.kind == TYPE || (sym.kind == VAL && !sym.isMethod()))) { - sym = descr.proxy(sym, currentOwner); - } - Tree tree1 = gen.mkLocalRef(tree.pos, sym); - if (sym.isCaptured()) - return gen.Select(tree1, definitions.REF_ELEM()); - else - return tree1; - - default: - return super.transform(tree); - } - } - - private Symbol[] ftvsParams(Symbol owner) { - Symbol[] freevars = get(free.ftvs, owner).toArray(); - Symbol[] params = new Symbol[freevars.length]; - for (int i = 0; i < params.length; i++) { - params[i] = freevars[i].cloneSymbol(owner); - params[i].pos = owner.pos; - params[i].flags = PARAM | SYNTHETIC; - } - for (int i = 0; i < params.length; i++) - params[i].setInfo(freevars[i].info().subst(freevars, params)); - return params; - } - - private Symbol[] fvsParams(Symbol owner) { - Symbol[] freevars = get(free.fvs, owner).toArray(); - Symbol[] params = new Symbol[freevars.length]; - for (int i = 0; i < params.length; i++) { - params[i] = freevars[i].cloneSymbol(owner); - params[i].pos = owner.pos; - params[i].flags &= CAPTURED; - params[i].flags |= PARAM | SYNTHETIC; - params[i].setInfo(freevars[i].type()); - } - return params; - } - - private Symbol[] newtparams(Symbol owner) { - Symbol[] tparams = owner.nextType().typeParams(); - int nfree = get(free.ftvs, owner).size(); - assert nfree == tparams.length - owner.type().typeParams().length - : owner + " " + nfree + " " + tparams.length + " " + owner.type().firstParams().length; - Symbol[] newtparams = new Symbol[nfree]; - System.arraycopy(tparams, tparams.length - nfree, newtparams, 0, nfree); - return newtparams; - } - - private Symbol[] newparams(Symbol owner) { - Symbol[] params = owner.nextType().firstParams(); - int nfree = get(free.fvs, owner).size(); - assert nfree == params.length - owner.type().firstParams().length; - Symbol[] newparams = new Symbol[nfree]; - System.arraycopy(params, params.length - nfree, newparams, 0, nfree); - return newparams; - } - - /** For members: - * change symbol of tree so that - * owner = currentClass - * newparams are added - * enter symbol in scope of currentClass - * For non-members: - * change symbol of tree so that - * owner = currentMember - */ - private void liftSymbol(Tree tree) { - switch (tree) { - case ClassDef(_, _, _, _, _, _): - ((ClassDef) tree).mods |= LIFTED; - Symbol sym = tree.symbol(); - sym.flags |= LIFTED; - assert sym.isLocal() : sym; - Symbol constr = sym.primaryConstructor(); - liftSymbol( - sym, get(free.ftvs, constr).toArray(), - ftvsParams(constr), fvsParams(constr)); - break; - - case DefDef(_, _, _, _, _, _): - ((DefDef) tree).mods |= LIFTED; - Symbol sym = tree.symbol(); - sym.flags |= LIFTED | PRIVATE; - assert sym.isLocal() : sym; - liftSymbol( - sym, get(free.ftvs, sym).toArray(), - ftvsParams(sym), fvsParams(sym)); - break; - - case ValDef(_, _, _, _): - case LabelDef(_, _, _): - Symbol sym = tree.symbol(); - assert sym.isLocal() : sym; - // This is to fix the owner of y from x to f in this example: - // class C { def f = { val x = { val y = ...; y } } } - if (!isClassMember(sym.owner())) { - assert isClassMember(sym.owner().owner()): Debug.show(tree, sym); - sym.setOwner(sym.owner().owner()); - } - break; - - } - } - // where - private boolean isClassMember(Symbol sym) { - return sym.isConstructor() || sym.owner().isClass(); - } - - private void liftSymbol(Symbol sym, Symbol[] oldtparams, - Symbol[] newtparams, Symbol[] newparams) { - Symbol enclClass = sym.owner(); - while (!enclClass.isClassType()) { - enclClass = enclClass.isConstructor() && !enclClass.isPrimaryConstructor() - ? enclClass.constructorClass() - : enclClass.owner(); - } - if (!sym.isConstructor()) sym.setOwner(enclClass); - if (!sym.isConstructor()) enclClass.members().enter(sym); - if (sym.isMethod()) { - if (newtparams.length != 0 || newparams.length != 0) { - sym.updateInfo( - addParams( - addTypeParams( - sym.nextInfo(), oldtparams, newtparams), - newparams)); - if (global.debug) - global.log(sym + " has now type " + sym.nextType()); - } - } else if (sym.kind == CLASS) { - Symbol constr = sym.primaryConstructor(); - liftSymbol(constr, oldtparams, newtparams, newparams); - // fix result type of constructor - constr.updateInfo(descr.transform(constr.nextInfo(), constr)); - } else { - throw new ApplicationError(); - } - } - - private Type addTypeParams(Type tp, Symbol[] oldtparams, Symbol[] newtparams) { - if (newtparams.length == 0) return tp; - switch (tp) { - case MethodType(_, _): - return Type.PolyType( - newtparams, - Type.getSubst(oldtparams, newtparams, true).apply(tp)); - case PolyType(Symbol[] tparams, Type restpe): - Symbol[] tparams1 = new Symbol[tparams.length + newtparams.length]; - System.arraycopy(tparams, 0, tparams1, 0, tparams.length); - System.arraycopy(newtparams, 0, tparams1, tparams.length, newtparams.length); - return Type.PolyType( - tparams1, - Type.getSubst(oldtparams, newtparams, true).apply(restpe)); - default: - throw new ApplicationError("illegal type: " + tp); - } - } - - private Type addParams(Type tp, Symbol[] newparams) { - if (newparams.length == 0) return tp; - switch (tp) { - case MethodType(Symbol[] params, Type restpe): - Symbol[] params1 = new Symbol[params.length + newparams.length]; - System.arraycopy(params, 0, params1, 0, params.length); - System.arraycopy(newparams, 0, params1, params.length, newparams.length); - return Type.MethodType(params1, restpe); - case PolyType(Symbol[] tparams, Type restpe): - return Type.PolyType(tparams, addParams(restpe, newparams)); - default: - throw new ApplicationError("illegal type: " + tp); - } - } - - private AbsTypeDef[] addTypeParams(AbsTypeDef[] tparams, Symbol[] newtparams) { - if (newtparams.length == 0) return tparams; - AbsTypeDef[] tparams1 = new AbsTypeDef[tparams.length + newtparams.length]; - System.arraycopy(tparams, 0, tparams1, 0, tparams.length); - for (int i = 0; i < newtparams.length; i++) { - tparams1[tparams.length + i] = gen.mkTypeParam(newtparams[i]); - } - return tparams1; - } - - private ValDef[] addParams(ValDef[] params, Symbol[] newparams) { - if (newparams.length == 0) return params; - ValDef[] params1 = new ValDef[params.length + newparams.length]; - System.arraycopy(params, 0, params1, 0, params.length); - for (int i = 0; i < newparams.length; i++) { - params1[params.length + i] = gen.mkParam(newparams[i]); - } - return params1; - } - - /** For all variables or type variables in `fvs', - * append proxies to argument array `args'. - * - * @param pos - * @param fvs - * @param args - * @param types - * @return - */ - private Tree[] addFreeArgs(int pos, SymSet fvs, Tree[] args, boolean types) { - if (fvs != SymSet.EMPTY) { - Symbol[] fparams = fvs.toArray(); - Tree[] args1 = new Tree[args.length + fparams.length]; - System.arraycopy(args, 0, args1, 0, args.length); - for (int i = 0; i < fparams.length; i++) { - Symbol farg = descr.proxy(fparams[i], currentOwner); - args1[args.length + i] = - types ? gen.mkTypeRef(pos, farg) : gen.Ident(pos, farg); - } - return args1; - } else { - return args; - } - } - -} diff --git a/sources/scalac/transformer/LambdaLiftPhase.java b/sources/scalac/transformer/LambdaLiftPhase.java deleted file mode 100644 index 06c1984249..0000000000 --- a/sources/scalac/transformer/LambdaLiftPhase.java +++ /dev/null @@ -1,175 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.transformer; - -//import java.util.ArrayList; - -import scalac.*; -import scalac.parser.*; -import scalac.symtab.*; -import scalac.util.ArrayApply; - - -public class LambdaLiftPhase extends Phase implements Kinds, Modifiers { - - /** Initializes this instance. */ - public LambdaLiftPhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - } - - /** Applies this phase to the given compilation unit. - * - * @param unit - */ - public void apply(CompilationUnit unit) { - new LambdaLift(global, this).apply(unit); - } - - /** ... - * - * @param sym - * @param tp - * @return - */ - public Type transformInfo(Symbol sym, Type tp) { - /* - if (global.debug) - global.log("transform info for " + sym + ":" + tp + sym.locationString()); - */ - Type tp1 = tp; - if (sym != Symbol.NONE) { - switch (tp) { - case MethodType(_, _): - case PolyType(_, _): - tp1 = transform(tp, sym); - break; - default: - if (sym.kind == CLASS) - tp1 = transform(tp, sym); - else - tp1 = transform(tp, sym.owner()); - } - } - if (sym.isCaptured()) - return global.definitions.REF_TYPE(tp1); - else return tp1; - } - - /** Add proxies as type arguments for propagated type parameters. - * - * @param tp - * @param owner - * @return - */ - Type transform(Type tp, Symbol owner) { - return transformTypeMap.setOwner(owner).apply(tp); - } - - /** MapOnlyTypes => All symbols are mapped to themselves. - */ - private class TransformTypeMap extends Type.MapOnlyTypes { - Symbol owner; -// ArrayList/*<Symbol>*/ excluded = new ArrayList(); - Type.Map setOwner(Symbol owner) { this.owner = owner; return this; } - - public Type apply(Type tp) { - switch (tp) { - case TypeRef(Type pre, Symbol sym, Type[] targs): - if (sym.kind == CLASS) { - switch (pre) { - case NoPrefix: - pre = sym.owner().enclClass().thisType(); - tp = Type.typeRef(pre, sym, targs); - } - } - switch (pre) { - case NoPrefix: - if (LambdaLift.isLocal(sym, owner)) { - assert targs.length == 0; - return proxy(sym, owner).type(); - } - break; - case ThisType(_): - if (sym.kind == CLASS && - sym.primaryConstructor().isUpdatedAt(LambdaLiftPhase.this)) { - Symbol[] tparams = sym.primaryConstructor().nextInfo().typeParams(); - int i = tparams.length; - while (i > 0 && tparams[i-1].isSynthetic()) - i--; - if (i < tparams.length) { - if (global.debug) - global.log("adding proxies for " + sym + - ": " + ArrayApply.toString(tparams)); - - Type[] targs1 = new Type[tparams.length]; - System.arraycopy(map(targs), 0, targs1, 0, targs.length); - while (i < tparams.length) { - targs1[i] = proxy(tparams[i], owner).type(); - i++; - } - return Type.typeRef(pre, sym, targs1); - } - } - } - break; -/* - case PolyType(Symbol[] tparams, _): - if (tparams.length != 0) { - int len = excluded.size(); - for (int i = 0; i < tparams.length; i++) - excluded.add(tparams[i]); - Type tp1 = map(tp); - for (int i = 0; i < tparams.length; i++) - excluded.remove(excluded.size() - 1); - return tp1; - } -*/ - } - return map(tp); - } - } - - private TransformTypeMap transformTypeMap = new TransformTypeMap(); - - /** Return closest enclosing (type)parameter that has same name as `fv', - * or `fv' itself if this is the closest definition. - * - * @param fv - * @param owner - * @return - */ - Symbol proxy(Symbol fv, Symbol owner) { - if (global.debug) - global.log("proxy " + fv + " of " + fv.owner() + - " in " + LambdaLift.enclFun(owner)); - Symbol o = owner; - while (o.kind != NONE) { - if (global.debug) - global.log("looking in " + LambdaLift.enclFun(o) + " " + - ArrayApply.toString(o.typeParams())); - Symbol fowner = LambdaLift.enclFun(o); - if (fowner.isMethod()) { - if (LambdaLift.enclFun(fv.owner()) == fowner) return fv; - Type ft = (fowner.isUpdatedAt(this)) ? fowner.nextType() - : fowner.type(); - Symbol[] ownerparams = fv.isType() ? ft.typeParams() - : ft.firstParams(); - for (int i = 0; i < ownerparams.length; i++) { - if (ownerparams[i].name == fv.name) - return ownerparams[i]; - } - } - assert o.owner() != o; - o = o.owner(); - } - return fv; - //throw new ApplicationError("proxy " + fv + " in " + owner); - } - -} diff --git a/sources/scalac/transformer/MakeBoxingExplicitPhase.java b/sources/scalac/transformer/MakeBoxingExplicitPhase.java deleted file mode 100644 index 435886b1dc..0000000000 --- a/sources/scalac/transformer/MakeBoxingExplicitPhase.java +++ /dev/null @@ -1,50 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.transformer; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; -import scalac.CompilationUnit; -import scalac.checkers.TreeChecker; -import scalac.symtab.Definitions; - -/** - * This phase makes boxing and unboxing of primitive values and arrays - * explicit. - */ -public class MakeBoxingExplicitPhase extends Phase { - - //######################################################################## - // Private Fields - - private final Definitions definitions; - private final TreeChecker checker; - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public MakeBoxingExplicitPhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - this.definitions = global.definitions; - this.checker = new TreeChecker(definitions); - } - - //######################################################################## - // Public Methods - - /** Applies this phase to the given compilation unit. */ - public void apply(CompilationUnit unit) { - assert checker.check(unit); - new scalac.atree.ATreeFromSTree(definitions).translate(unit); // !!! - } - - //######################################################################## -} diff --git a/sources/scalac/transformer/OwnerTransformer.java b/sources/scalac/transformer/OwnerTransformer.java deleted file mode 100644 index 55ee93dadd..0000000000 --- a/sources/scalac/transformer/OwnerTransformer.java +++ /dev/null @@ -1,189 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002-2005, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.transformer; - -import scalac.*; -import scalac.ast.*; -import scalac.symtab.Kinds; -import scalac.symtab.Symbol; -import scalac.util.Name; -import Tree.*; - - -/** A default transformer class which also maintains owner information - * - * @author Martin Odersky - * @version 1.0 - */ -public class OwnerTransformer extends Transformer { - - protected Symbol currentOwner; - - public OwnerTransformer(Global global) { - super(global); - } - - public void apply(CompilationUnit unit) { - currentOwner = global.definitions.ROOT_CLASS; - unit.body = transform(unit.body); - } - - /** .. - * - * @param tree - * @param owner - * @return - */ - public Tree transform(Tree tree, Symbol owner) { - Symbol prevOwner = currentOwner; - currentOwner = owner; - Tree tree1 = transform(tree); - currentOwner = prevOwner; - return tree1; - } - - /** .. - * - * @param params - * @param owner - * @return - */ - public AbsTypeDef[] transform(AbsTypeDef[] params, Symbol owner) { - Symbol prevOwner = currentOwner; - currentOwner = owner; - AbsTypeDef[] res = transform(params); - currentOwner = prevOwner; - return res; - } - - /** .. - * - * @param params - * @param owner - * @return - */ - public ValDef[][] transform(ValDef[][] params, Symbol owner) { - Symbol prevOwner = currentOwner; - currentOwner = owner; - ValDef[][] res = transform(params); - currentOwner = prevOwner; - return res; - } - - /** .. - * - * @param templ - * @param owner - * @return - */ - public Template transform(Template templ, Symbol owner) { - Symbol prevOwner = currentOwner; - if (owner.kind == Kinds.CLASS) - currentOwner = owner.primaryConstructor(); - Tree[] parents1 = transform(templ.parents); - currentOwner = owner; - Tree[] body1 = transformTemplateStats(templ.body, templ.symbol()); - currentOwner = prevOwner; - return copy.Template(templ, parents1, body1); - } - - /** .. - * - * @param ts - * @param tsym - * @return - */ - public Tree[] transformTemplateStats(Tree[] ts, Symbol tsym) { - Tree[] ts1 = ts; - for (int i = 0; i < ts.length; i++) { - Tree t = transformTemplateStat(ts[i], tsym); - if (t != ts[i] && ts1 == ts) { - ts1 = new Tree[ts.length]; - System.arraycopy(ts, 0, ts1, 0, i); - } - ts1[i] = t; - } - return ts1; - } - - /** .. - * - * @param stat - * @param tsym - * @return - */ - public Tree transformTemplateStat(Tree stat, Symbol tsym) { - return transform(stat, tsym); - } - - /** .. - * - * @param tree - * @return - */ - public Tree transform(Tree tree) { - switch(tree) { - case PackageDef(Tree packaged, Template impl): - return copy.PackageDef( - tree, - transform(packaged), - transform(impl, packaged.symbol())); - - case ClassDef(_, _, AbsTypeDef[] tparams, ValDef[][] vparams, Tree tpe, Template impl): - Symbol symbol = tree.symbol(); - return copy.ClassDef( - tree, symbol, - transform(tparams, symbol.primaryConstructor()), - transform(vparams, symbol.primaryConstructor()), - transform(tpe, symbol), - transform(impl, symbol)); - - case ModuleDef(_, _, Tree tpe, Template impl): - Symbol symbol = tree.symbol(); - return copy.ModuleDef( - tree, symbol, - transform(tpe, symbol), - transform(impl, symbol.moduleClass())); - - case DefDef(_, _, AbsTypeDef[] tparams, ValDef[][] vparams, Tree tpe, Tree rhs): - Symbol symbol = tree.symbol(); - return copy.DefDef( - tree, symbol, - transform(tparams, symbol), - transform(vparams, symbol), - transform(tpe, symbol), - transform(rhs, symbol)); - - case ValDef(_, _, Tree tpe, Tree rhs): - Symbol symbol = tree.symbol(); - return copy.ValDef( - tree, symbol, - transform(tpe), - transform(rhs, symbol)); - - case AbsTypeDef(int mods, Name name, Tree rhs, Tree lobound): - Symbol symbol = tree.symbol(); - return copy.AbsTypeDef( - tree, symbol, - transform(rhs, symbol), - transform(lobound, symbol)); - - case AliasTypeDef(int mods, Name name, AbsTypeDef[] tparams, Tree rhs): - Symbol symbol = tree.symbol(); - return copy.AliasTypeDef( - tree, symbol, - transform(tparams, symbol), - transform(rhs, symbol)); - - default: - return super.transform(tree); - } - } - -} diff --git a/sources/scalac/transformer/TailCallPhase.java b/sources/scalac/transformer/TailCallPhase.java deleted file mode 100644 index 4798e22c1a..0000000000 --- a/sources/scalac/transformer/TailCallPhase.java +++ /dev/null @@ -1,296 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.transformer; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; -import scalac.CompilationUnit; -import scalac.ast.Tree; -import scalac.ast.GenTransformer; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.util.Debug; - -/** - * A Tail Call Transformer - * - * @author Erik Stenman - * @version 1.0 - * - * What it does: - * - * Finds method calls in tail-position and replaces them with jumps. - * A call is in a tail-position if it is the last instruction to be - * executed in the body of a method. This is done by recursing over - * the trees that may contain calls in tail-position (trees that can't - * contain such calls are not transformed). However, they are not that - * many. - * - * Self-recursive calls in tail-position are replaced by jumps to a - * label at the beginning of the method. As the JVM provides no way to - * jump from a method to another one, non-recursive calls in - * tail-position are not optimized. - * - * A method call is self-recursive if it calls the current method on - * the current instance and the method is final (otherwise, it could - * be a call to an overridden method in a subclass). Furthermore, If - * the method has type parameters, the call must contain these - * parameters as type arguments. - * - * Nested functions can be tail recursive (if this phase runs before - * lambda lift) and they are transformed as well. - * - * If a method contains self-recursive calls, a label is added to at - * the beginning of its body and the calls are replaced by jumps to - * that label. - */ -public class TailCallPhase extends Phase { - - private static class Context { - /** The current method */ - public Symbol method = Symbol.NONE; - - /** The current tail-call label */ - public Symbol label = Symbol.NONE; - - /** The expected type arguments of self-recursive calls */ - public Type[] types; - - /** Tells whether we are in a tail position. */ - public boolean tailPosition; - - public Context() { - this.tailPosition = false; - } - - /** - * The Context of this transformation. It contains the current enclosing method, - * the label and the type parameters of the enclosing method, together with a - * flag which says whether our position in the tree allows tail calls. This is - * modified only in <code>Block</code>, where stats cannot possibly contain tail - * calls, but the value can. - */ - public Context(Symbol method, Symbol label, Type[] types, boolean tailPosition) { - this.method = method; - this.label = label; - this.types = types; - this.tailPosition = tailPosition; - } - } - - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public TailCallPhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - } - - //######################################################################## - // Public Methods - - /** Applies this phase to the given compilation unit. */ - public void apply(CompilationUnit unit) { - treeTransformer.apply(unit); - } - - //######################################################################## - // Private Classes - - /** The tree transformer */ - private final GenTransformer treeTransformer = new GenTransformer(global) { - - - /** The context of this call */ - private Context ctx = new Context(); - - /** Transform the given tree, which is (or not) in tail position */ - public Tree transform(Tree tree, boolean tailPos) { - boolean oldTP = ctx.tailPosition; - ctx.tailPosition = tailPos; - tree = transform(tree); - ctx.tailPosition = oldTP; - return tree; - } - - public Tree[] transform(Tree[] trees, boolean tailPos) { - boolean oldTP = ctx.tailPosition; - ctx.tailPosition = tailPos; - trees = transform(trees); - ctx.tailPosition = oldTP; - return trees; - } - - /** Transforms the given tree. */ - public Tree transform(Tree tree) { - switch (tree) { - - case DefDef(_, _, _, _, _, Tree rhs): - Context oldCtx = ctx; - - ctx = new Context(); - - //assert method == null: Debug.show(method) + " -- " + tree; - ctx.method = tree.symbol(); - ctx.tailPosition = true; - - if (ctx.method.isMethodFinal() || ctx.method.owner().isMethod()) { - ctx.label = ctx.method.newLabel(ctx.method.pos, ctx.method.name); - ctx.types = Type.EMPTY_ARRAY; - Type type = ctx.method.type(); - switch (type) { - case PolyType(Symbol[] tparams, Type result): - ctx.types = Symbol.type(tparams); - type = result; - } - ctx.label.setInfo(type.cloneType(ctx.method, ctx.label)); - rhs = transform(rhs); - if (ctx.label.isAccessed()) { - global.log("Rewriting def " + ctx.method.simpleName()); - rhs = gen.LabelDef(ctx.label, ctx.method.valueParams(), rhs); - } - tree = gen.DefDef(ctx.method, rhs); - } else { - assert !ctx.method.isMethodFinal() - : "Final method: " + ctx.method.simpleName(); - // non-final method - ctx.tailPosition = false; - tree = gen.DefDef(tree.symbol(), transform(rhs)); - } - ctx = oldCtx; - return tree; - - case Block(Tree[] stats, Tree value): - boolean oldPosition = ctx.tailPosition; - ctx.tailPosition = false; stats = transform(stats); - ctx.tailPosition = oldPosition; - return gen.Block(tree.pos, stats, transform(value)); - - - case If(Tree cond, Tree thenp, Tree elsep): - Type type = tree.type(); - thenp = transform(thenp); - elsep = transform(elsep); - return gen.If(tree.pos, cond, thenp, elsep); - - case Switch(Tree test, int[] tags, Tree[] bodies, Tree otherwise): - Type type = tree.type(); - bodies = transform(bodies); - otherwise = transform(otherwise); - return gen.Switch(tree.pos, test, tags, bodies,otherwise,type); - - // handle pattern matches explicitly - case Apply(Select(_, scalac.util.Names._match), Tree[] args): - Tree newTree = global.make.Apply(tree.pos, ((Tree.Apply)tree).fun, transform(args)); - newTree.setType(tree.getType()); - return newTree; - - case Apply(TypeApply(Tree fun, Tree[] targs), Tree[] vargs): - if (ctx.method != Symbol.NONE && ctx.tailPosition) { - assert targs != null : "Null type arguments " + tree; - assert ctx.types != null : "Null types " + tree; - - if (!Type.isSameAs(Tree.typeOf(targs), ctx.types) | - !ctx.tailPosition) - return tree; - return transform(tree, fun, transform(vargs, false)); - } else - return tree; - - case Apply(Tree fun, Tree[] vargs): - if (ctx.tailPosition) - return transform(tree, fun, transform(vargs, false)); - else - return gen.mkApply_V(fun, transform(vargs, false)); - - case Visitor(Tree.CaseDef[] cases): - Tree newTree = global.make.Visitor(tree.pos, super.transform(cases)); - newTree.setType(tree.getType()); - return newTree; - - case CaseDef(Tree pattern, Tree guard, Tree body): - return gen.CaseDef(pattern, guard, transform(body)); - - case Typed(Tree expr, Tree type): - return gen.Typed(transform(expr), type); - - case ClassDef(_, _, _, _, _, Tree.Template impl): - Symbol impl_symbol = getSymbolFor(impl); - Tree[] body = transform(impl.body); - return gen.ClassDef(getSymbolFor(tree), impl.parents, impl_symbol, body); - - case PackageDef(_, _): - case LabelDef(_, _, _): - case Return(_): - return super.transform(tree); - - - case Empty: - case ValDef(_, _, _, _): - case Assign(_, _): - case New(_): - case Super(_, _): - case This(_): - case Select(_, _): - case Ident(_): - case Literal(_): - case TypeTerm(): - case AbsTypeDef(_, _, _, _): - case AliasTypeDef(_, _, _, _): - case Import(_, _): - case Function(_, _): - return tree; - - default: - throw Debug.abort("illegal case", tree); - } - } - - /** Transforms the given function call. */ - private Tree transform(Tree tree, Tree fun, Tree[] vargs) { - if (fun.symbol() != ctx.method) - return tree; - switch (fun) { - case Select(Tree qual, _): - if (!isReferenceToThis(qual, ctx.method.owner())) - return tree; - global.log("Applying tail call recursion elimination for " + - ctx.method.enclClass().simpleName() + "." + ctx.method.simpleName()); - return gen.Apply(tree.pos, gen.Ident(qual.pos, ctx.label), vargs); - - case Ident(_): - global.log("Applying tail call recursion elimination for function " + - ctx.method.enclClass().simpleName() + "." + ctx.method.simpleName()); - return gen.Apply(tree.pos, gen.Ident(fun.pos, ctx.label), vargs); - - default: - throw Debug.abort("illegal case", fun); - } - } - - /** - * Returns true if the tree represents the current instance of - * given class. - */ - private boolean isReferenceToThis(Tree tree, Symbol clasz) { - switch (tree) { - case This(_): - assert tree.symbol() == clasz: tree +" -- "+ Debug.show(clasz); - return true; - default: - return false; - } - } - - }; - - //######################################################################## -} diff --git a/sources/scalac/transformer/TypesAsValuesPhase.java b/sources/scalac/transformer/TypesAsValuesPhase.java deleted file mode 100644 index 394373bd94..0000000000 --- a/sources/scalac/transformer/TypesAsValuesPhase.java +++ /dev/null @@ -1,1415 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.transformer; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; -import scalac.CompilationUnit; -import scalac.symtab.Definitions; -import scalac.symtab.Scope; -import scalac.symtab.Symbol; -import scalac.symtab.Type; -import scalac.symtab.Modifiers; -import scalac.atree.AConstant; -import scalac.ast.Transformer; -import scalac.ast.GenTransformer; -import scalac.ast.Tree; -import scalac.ast.TreeGen; -import scalac.ast.TreeList; -import scalac.backend.Primitives; - -import scalac.util.Name; -import scalac.util.Names; -import scalac.util.Debug; - -import java.util.Map; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.Arrays; -import java.util.Collections; - -/** - * Turn types into values by applying the following transformations: - * - * - For all type member T of all classes, add an accessor method - * T$type returnining the type as a value (the accessor is abstract - * if the type member is abstract). - * - * - For all polymorphic methods/constructors, add a value parameter - * for each type parameter. - * - * - Add a method getScalaType to every class, to obtain its type as a - * value. - * - * - Transform all type expressions into value expressions: type - * application is turned into value application, type selection into - * value selection, and so on. - * - * @author Michel Schinz - * @version 1.0 - */ - -// TODO use a constant instead of generating empty arrays all the -// time. - -public class TypesAsValuesPhase extends Phase { - private final GenTransformer transformer; - - /** - * The list of members to add to a given class (either type - * accessors or instantiation methods). - */ - private final HashMap/*<Symbol,Symbol[]>*/ membersToAdd = - new HashMap(); - - /** The list of parameters to add to a given method. */ - private final HashMap/*<Symbol,List<Symbol>>*/ paramsToAdd = - new HashMap(); - - /** The accessor method corresponding to a given type (or class) member. */ - private final HashMap/*<Symbol, Symbol>*/ typeAccessor = - new HashMap(); - - /** The instanciation method corresponding to a given class. */ - private final HashMap/*<Symbol,Symbol>*/ instantiator = - new HashMap(); - - /** The lazy parent class corresponding to a given class. */ - private final HashMap/*<Symbol,Symbol>*/ lazyParentsClass = - new HashMap(); - - /** The class constructor corresponding to a given class. */ - private final HashMap/*<Symbol,Symbol>*/ classInitialiser = - new HashMap(); - - private final HashMap/*<Symbol,Symbol>*/ tConstructor = - new HashMap(); - - private final HashMap/*<Symbol, HashSet<Symbol>>*/ constructorNeed = - new HashMap(); - - private final Definitions defs = global.definitions; - private final Primitives prims = global.primitives; - - private final Type.MethodType typeAccessorType, lazyForceType; - - private final Symbol ARRAY_CONSTRUCTOR = - defs.ARRAY_CLASS.primaryConstructor(); - - private final TEnv EENV = new TEnv(); - - private final Map/*<Symbol, Symbol>*/ predefTypes; - private final Map/*<Type, String>*/ basicTypes; - - private HashMap/*<Symbol, Ancestor[][]>*/ ancestorCache = new HashMap(); - - public TypesAsValuesPhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - // If RTT are disabled, use a minimal transformer which simply - // replaces [ia]sInstanceOf with their erased counterpart. - if (global.runTimeTypes && global.target != Global.TARGET_MSIL) { - transformer = new TV_Transformer(global); - typeAccessorType = - new Type.MethodType(new Symbol[]{}, defs.TYPE_TYPE()); - lazyForceType = - new Type.MethodType(Symbol.EMPTY_ARRAY, - defs.ARRAY_TYPE(defs.SCALACLASSTYPE_TYPE())); - predefTypes = new HashMap(); - predefTypes.put(defs.DOUBLE_CLASS, defs.RTT_DOUBLE()); - predefTypes.put(defs.FLOAT_CLASS, defs.RTT_FLOAT()); - predefTypes.put(defs.LONG_CLASS, defs.RTT_LONG()); - predefTypes.put(defs.INT_CLASS, defs.RTT_INT()); - predefTypes.put(defs.SHORT_CLASS, defs.RTT_SHORT()); - predefTypes.put(defs.CHAR_CLASS, defs.RTT_CHAR()); - predefTypes.put(defs.BYTE_CLASS, defs.RTT_BYTE()); - predefTypes.put(defs.BOOLEAN_CLASS, defs.RTT_BOOLEAN()); - predefTypes.put(defs.UNIT_CLASS, defs.RTT_UNIT()); - - predefTypes.put(defs.ANY_CLASS, defs.RTT_ANY()); - predefTypes.put(defs.ANYVAL_CLASS, defs.RTT_ANYVAL()); - predefTypes.put(defs.ALLREF_CLASS, defs.RTT_ALLREF()); - predefTypes.put(defs.ALL_CLASS, defs.RTT_ALL()); - - basicTypes = new HashMap(); - basicTypes.put(defs.BOOLEAN_TYPE(), "Z"); - basicTypes.put(defs.BYTE_TYPE(), "B"); - basicTypes.put(defs.CHAR_TYPE(), "C"); - basicTypes.put(defs.DOUBLE_TYPE(), "D"); - basicTypes.put(defs.FLOAT_TYPE(), "F"); - basicTypes.put(defs.INT_TYPE(), "I"); - basicTypes.put(defs.LONG_TYPE(), "J"); - basicTypes.put(defs.SHORT_TYPE(), "S"); - - membersToAdd.put(defs.ARRAY_CLASS, new Symbol[0]); - paramsToAdd.put(ARRAY_CONSTRUCTOR, new Symbol[0]); - - ancestorCache.put(defs.OBJECT_CLASS, new Ancestor[0][]); - } else { - transformer = new TV_MiniTransformer(global); - typeAccessorType = lazyForceType = null; - predefTypes = basicTypes = null; - } - } - - /** - * Return the symbol of the accessor for the given type symbol. - */ - private Symbol getAccessorSym(Symbol typeSym) { - assert typeSym.isType(); - Symbol accessorSym = (Symbol)typeAccessor.get(typeSym); - if (accessorSym == null) { - accessorSym = typeSym.owner().newVariable(typeSym.pos, - typeSym.flags, - Names.TYPE(typeSym)); - accessorSym.setInfo(defs.TYPE_TYPE()); - typeAccessor.put(typeSym, accessorSym); - } - return accessorSym; - } - - private Symbol getInstMethSym(Symbol classSym) { - Symbol imSym = (Symbol)instantiator.get(classSym); - if (imSym == null) { - int pos = classSym.pos; - boolean isStatic = !isNestedClass(classSym); - Name imName = Names.INSTANTIATE(classSym, isStatic); - - int flags = classSym.isAbstractType() ? Modifiers.DEFERRED : 0; - - imSym = isStatic - ? classSym.newStaticMethod(pos, 0, imName) - : classSym.owner().newMethodOrFunction(pos, flags, imName); - - Symbol[] argTypes; - Symbol typesP = imSym.newVParam(pos, 0, Name.fromString("types")); - typesP.setInfo(defs.ARRAY_TYPE(defs.TYPE_TYPE())); - argTypes = new Symbol[]{ typesP }; - - imSym.setInfo(new Type.MethodType(argTypes, - isStatic - ? defs.SCALACLASSTYPE_TYPE() - : defs.TYPE_TYPE())); - - instantiator.put(classSym, imSym); - } - return imSym; - } - - private Symbol getLazyParentClassSym(Symbol classSym) { - Symbol lpcSym = (Symbol)lazyParentsClass.get(classSym); - if (lpcSym == null) { - int pos = classSym.pos; - Name lpcName = Names.LAZYPARENTS(classSym); - lpcSym = classSym.owner().newClass(pos, 0, lpcName); - - Type lpcInfo = - Type.compoundType(new Type[] { defs.LAZYPARENTS_TYPE() }, - new Scope(), - lpcSym); - lpcSym.setInfo(lpcInfo); - - Symbol lpcConstrSym = lpcSym.primaryConstructor(); - Symbol typesP = - lpcConstrSym.newVParam(pos, 0, Name.fromString("types")); - typesP.setInfo(defs.ARRAY_TYPE(defs.TYPE_TYPE())); - - lpcConstrSym.setInfo(new Type.MethodType(new Symbol[]{ typesP }, - defs.UNIT_TYPE())); - - lazyParentsClass.put(classSym, lpcSym); - } - return lpcSym; - } - - private Symbol getTConstructorSym(Symbol classSym) { - Symbol tcSym = (Symbol)tConstructor.get(classSym); - if (tcSym == null) { - int pos = classSym.pos; - boolean isStatic = !isNestedClass(classSym); - Name tcName = Names.TYPECONSTRUCTOR(classSym, isStatic); - - tcSym = isStatic - ? classSym.newStaticField(pos, 0, tcName) - : classSym.owner().newFieldOrVariable(pos, 0, tcName); - tcSym.setInfo(defs.TYPECONSTRUCTOR_TYPE()); - - tConstructor.put(classSym, tcSym); - } - return tcSym; - } - - private Symbol getClassInitSym(Symbol classSym) { - Symbol ciSym = (Symbol)classInitialiser.get(classSym); - if (ciSym == null) { - int pos = classSym.pos; - - ciSym = classSym.newStaticMethod(pos, 0, Names.CLASS_CONSTRUCTOR); - ciSym.setInfo(new Type.MethodType(Symbol.EMPTY_ARRAY, - defs.UNIT_TYPE())); - - classInitialiser.put(classSym, ciSym); - } - return ciSym; - } - - private Symbol[] membersToAdd(Symbol classSym) { - Symbol[] toAdd = (Symbol[])membersToAdd.get(classSym); - if (toAdd == null) { - HashSet seenMembers = new HashSet(); // [HACK] - ArrayList toAddL = new ArrayList(); - Scope.SymbolIterator membersIt = classSym.members().iterator(); - while (membersIt.hasNext()) { - Symbol member = membersIt.next(); - // [HACK] work around a bug in the analyzer, which - // doesn't add the module class to its owner's members - if (member.isModule()) - member = member.moduleClass(); - if (!seenMembers.add(member)) - continue; - if (member.isClass()) { - toAddL.add(getTConstructorSym(member)); - toAddL.add(getInstMethSym(member)); - } else if (member.isType()) - toAddL.add(getInstMethSym(member)); - } - - if (needsInstantiationMethod(classSym)) { - toAddL.add(getTConstructorSym(classSym)); - toAddL.add(getClassInitSym(classSym)); - toAddL.add(getInstMethSym(classSym)); - } - - toAdd = (Symbol[])toAddL.toArray(new Symbol[toAddL.size()]); - membersToAdd.put(classSym, toAdd); - } - return toAdd; - } - - private Symbol[] paramsToAdd(Symbol methSym) { - Symbol[] toAdd = (Symbol[])paramsToAdd.get(methSym); - if (toAdd == null) { - Symbol[] tparams = methSym.typeParams(); - - ArrayList toAddL = new ArrayList(); - for (int i = 0; i < tparams.length; ++i) - toAddL.add(getAccessorSym(tparams[i])); - - toAdd = (Symbol[])toAddL.toArray(new Symbol[toAddL.size()]); - paramsToAdd.put(methSym, toAdd); - } - - return toAdd; - } - - /** - * Return true iff the given symbol is not a polymorphic - * primitive, which shouldn't get type parameters as value - * parameters. - */ - private boolean monoPrimitive(Symbol sym) { - return sym.isJava() - || sym == ARRAY_CONSTRUCTOR - || sym == defs.OBJECT_SYNCHRONIZED - || sym == defs.ANY_IS - || sym == defs.ANY_IS_ERASED - || sym == defs.ANY_AS - || sym == defs.ANY_AS_ERASED; - } - - public Type transformInfo(Symbol symbol, Type type) { - if (!global.runTimeTypes) return type; - - if (symbol.isClass()) { - Symbol[] toAdd = membersToAdd(symbol); - - if (toAdd.length == 0) - return type; - else { - Scope newMembers = new Scope(symbol.members()); - - for (int i = 0; i < toAdd.length; ++i) - newMembers.enterOrOverload(toAdd[i]); - - return Type.compoundType(type.parents(), newMembers, symbol); - } - } else if (type.typeParams().length > 0 && !monoPrimitive(symbol)) { - // Polymorphic method/constructor: - // - add a value parameter for every type parameter. - switch (type) { - case PolyType(Symbol[] tparams, // : - Type.MethodType(Symbol[] vparams, Type result)): - List newVParams = - new LinkedList(Arrays.asList(paramsToAdd(symbol))); - newVParams.addAll(Arrays.asList(vparams)); - Symbol[] newVParamsA = (Symbol[]) - newVParams.toArray(new Symbol[newVParams.size()]); - - return new Type.PolyType(tparams, - new Type.MethodType(newVParamsA, - result)); - - default: - throw Debug.abort("unexpected type: ", type); - } - } else - return type; - } - - /** - * Return true iff the given type is trivial, that is if it - * has neither a prefix, nor type parameters. - */ - private boolean isTrivial(Type tp) { - switch (tp) { - case TypeRef(_, Symbol sym, Type[] args): - if (sym == defs.ARRAY_CLASS) - return isTrivial(args[0]); - else - return sym.isStatic() && args.length == 0; - case SingleType(_, _): - case ThisType(_): - case CompoundType(_, _): - return false; - default: - throw Debug.abort("unexpected type", tp); - } - } - - /** - * Return true iff the given type is strongly trivial, that is - * if it and all its ancestors are trivial. - */ - private boolean isStronglyTrivial(Type tp) { - if (isTrivial(tp)) { - Type[] parents = tp.parents(); - for (int i = 0; i < parents.length; ++i) { - if (!isStronglyTrivial(parents[i])) - return false; - } - return true; - } else - return false; - } - - private boolean isNestedClass(Symbol classSym) { - return !classSym.owner().isPackageClass(); - } - - private boolean needsInstantiationMethod(Symbol classSym) { - return !(isNestedClass(classSym) || isStronglyTrivial(classSym.type())); - } - - public void apply(CompilationUnit unit) { - transformer.apply(unit); - } - - private class TV_Transformer extends TV_MiniTransformer { - private Symbol currentOwner; - private TreeList additionalTopLevelClasses; - - public TV_Transformer(Global global) { - super(global); - } - - public void apply(CompilationUnit unit) { - unit.global.log("transforming " + unit); - additionalTopLevelClasses = new TreeList(); - TreeList newUnitBody = new TreeList(transform(unit.body)); - newUnitBody.append(additionalTopLevelClasses); - additionalTopLevelClasses = null; - unit.body = newUnitBody.toArray(); - } - - public Tree transform(Tree tree) { - switch (tree) { - case ClassDef(_, _, _, _, _, Tree.Template impl): - Symbol clsSym = tree.symbol(); - - TreeList newBody = new TreeList(); - if (needsInstantiationMethod(clsSym)) { - boolean lazy = isCyclic(clsSym); - - Symbol tcSym = getTConstructorSym(clsSym); - newBody.append(tConstructorVal(clsSym, tcSym)); - Symbol ciSym = getClassInitSym(clsSym); - newBody.append(classInitialiser(clsSym, ciSym, tcSym)); - Symbol imSym = getInstMethSym(clsSym); - newBody.append(instantiatorBody(clsSym, imSym, lazy)); - - if (lazy) { - Symbol lpcSym = getLazyParentClassSym(clsSym); - Tree lpc = lazyParentsClass(clsSym, lpcSym); - additionalTopLevelClasses.append(lpc); - } - } - newBody.append(transformStatements(impl.body, impl.symbol())); - - return gen.ClassDef(clsSym, - transform(impl.parents, - clsSym.primaryConstructor()), - impl.symbol(), - newBody.toArray()); - - case DefDef(_, _, _, _, _, Tree rhs): - Symbol symbol = getSymbolFor(tree); - - if (symbol.name == Names.getScalaType && symbol.isSynthetic()) { - // Correct the body of the getScalaType method - // which, until now, was a placeholder (introduced - // by RefCheck). - return gen.DefDef(symbol, - scalaClassType(symbol.pos, - symbol.owner().type(), - symbol, - EENV)); - } else - return gen.DefDef(symbol, transform(rhs, symbol)); - - case Block(Tree[] stats, Tree value): - return gen.Block(tree.pos, - transformStatements(stats), - transform(value)); - - case ValDef(_, _, Tree tpe, Literal(AConstant.ZERO)): - // transform default values: - // val x: T = _ - // becomes - // val x: T = asValue(T).defaultValue() - Symbol symbol = getSymbolFor(tree); - Tree defaultValue = - gen.mkRef(tree.pos, - typeAsValue(tree.pos, - tpe.type, - currentOwner, - EENV), - defs.TYPE_DEFAULTVALUE()); - Tree rhs = gen.mkApply__(tree.pos, defaultValue); - return gen.ValDef(symbol, rhs); - - case ValDef(_, _, _, Tree rhs): - Symbol symbol = getSymbolFor(tree); - return gen.ValDef(symbol, transform(rhs, symbol)); - - case New(Apply(TypeApply(Tree fun, Tree[] targs), Tree[] vargs)): - if (fun.symbol() == ARRAY_CONSTRUCTOR - && targs[0].type().symbol().isParameter()) { - // Transform array creations: - // new Array[T](size) - // becomes - // asValue(T).newArray[T](size) - assert targs.length == 1; - assert vargs.length == 1; - Tree newArrayfun = gen.mkRef(tree.pos, - typeAsValue(targs[0].pos, - targs[0].type(), - currentOwner, - EENV), - defs.TYPE_NEWARRAY()); - return gen.mkApplyTV(newArrayfun, targs, vargs); - } else - return super.transform(tree); - - case Apply(TypeApply(Tree fun, Tree[] targs), Tree[] vargs): - Symbol funSym = fun.symbol(); - - if (funSym == defs.ANY_IS) { - assert targs.length == 1 && vargs.length == 0; - Type type = targs[0].type; - Tree expr = transform(qualifierOf(fun)); - return (isTrivial(type) && !isSpecial(type)) - ? super.transform(tree) - : genInstanceTest(tree.pos, expr, type); - } else if (funSym == defs.ANY_AS) { - // Transform instance tests: - // e.asInstanceOf[T] - // becomes: - // asValue(T).cast(e).asInstanceOf[T] - // unless T is a trivial type for which a Java - // instance test is sufficient, in which case the - // erased version of asInstanceOf is used. - assert targs.length == 1 && vargs.length == 0; - Type type = targs[0].type; - Tree expr = transform(qualifierOf(fun)); - return (isTrivial(type) && !isSpecial(type)) - ? super.transform(tree) - : genTypeCast(tree.pos, expr, type); - } else if (!monoPrimitive(funSym)) { - // Transform applications to pass types as values: - // f[T1, ...](v1, ...) - // becomes - // f[T1, ...](asValue(T1), ..., v1, ...) - Tree[] newVArgs = transform(vargs); - Tree[] finalVArgs = - new Tree[newVArgs.length + targs.length]; - for (int i = 0; i < targs.length; ++i) - finalVArgs[i] = typeAsValue(targs[i].pos, - targs[i].type, - currentOwner, - EENV); - System.arraycopy(newVArgs, 0, - finalVArgs, targs.length, - newVArgs.length); - return gen.mkApplyTV(tree.pos, - transform(fun), - targs, - finalVArgs); - } else - return super.transform(tree); - - default: - return super.transform(tree); - } - } - - private Tree[] transformStatements(Tree[] stats) { - ArrayList newStats = new ArrayList(); - int beginIdx = 0; - for (int i = 0; i < stats.length; ++i) { - Tree stat = stats[i]; - switch (stat) { - case ClassDef(_, _, _, _, _, Tree.Template impl): - Symbol clsSym = stat.symbol(); - boolean lazy = isCyclic(clsSym); - Symbol tcSym = getTConstructorSym(clsSym); - newStats.add(beginIdx++, tConstructorVal(clsSym, tcSym)); - Symbol insSym = getInstMethSym(clsSym); - newStats.add(instantiatorBody(clsSym, insSym, lazy)); - if (lazy) { - Symbol lpcSym = getLazyParentClassSym(clsSym); - newStats.add(lazyParentsClass(clsSym, lpcSym)); - } - break; - - case AbsTypeDef(_, _, _, _): - case AliasTypeDef(_, _, _, _): - Symbol tpSym = stat.symbol(); - Symbol insSym = getInstMethSym(tpSym); - newStats.add(typeAccessorBody(tpSym, insSym)); - break; - } - newStats.add(transform(stat)); - } - return (Tree[])newStats.toArray(new Tree[newStats.size()]); - } - - private Tree[] transformStatements(Tree[] stats, Symbol currentOwner) { - Symbol bkpOwner = this.currentOwner; - this.currentOwner = currentOwner; - Tree[] newStats = transformStatements(stats); - this.currentOwner = bkpOwner; - return newStats; - } - - private Tree transform(Tree tree, Symbol currentOwner) { - Symbol bkpOwner = this.currentOwner; - this.currentOwner = currentOwner; - Tree newTree = transform(tree); - this.currentOwner = bkpOwner; - return newTree; - } - - private Tree[] transform(Tree[] trees, Symbol currentOwner) { - Symbol bkpOwner = this.currentOwner; - this.currentOwner = currentOwner; - Tree[] newTrees = transform(trees); - this.currentOwner = bkpOwner; - return newTrees; - } - - private int level(Symbol sym) { - Symbol superClass = sym.parents()[0].symbol(); - assert superClass != Symbol.NONE : sym; - if (superClass == defs.ANY_CLASS) - return 0; - else - return 1 + level(superClass); - } - - /** - * Return a method giving access to the given type, as a - * value. - */ - private Tree.DefDef typeAccessorBody(Symbol typSym, Symbol accSym) { - Tree rhs; - if (typSym.isAbstractType()) - rhs = Tree.Empty; - else if (typSym.isClass()) - rhs = scalaClassType(typSym.pos, typSym.type(), accSym, EENV); - else { - final Symbol[] vparams = accSym.valueParams(); - final int pos = accSym.pos; - - final HashMap varMap = new HashMap(); - Symbol[] tparams = typSym.typeParams(); - for (int i = 0; i < tparams.length; ++i) - varMap.put(tparams[i], new Integer(i)); - - TEnv tEnv = new TEnv() { - public boolean definesVar(Symbol sym) { - return varMap.containsKey(sym); - } - - public Tree treeForVar(Symbol sym) { - int idx = ((Integer)varMap.get(sym)).intValue(); - Tree array = gen.mkLocalRef(pos, vparams[0]); - return gen.mkArrayGet(pos, array, idx); - } - }; - - rhs = typeAsValue(typSym.pos, typSym.type(), accSym, tEnv); - } - return gen.DefDef(accSym, rhs); - } - - private Tree tConstructorVal(Symbol clsSym, Symbol tcSym) { - return gen.ValDef(tcSym, - tcSym.isStatic() - ? Tree.Empty - : tConstructorRHS(tcSym.pos, clsSym, tcSym)); - } - - private Tree classInitialiser(Symbol clsSym, - Symbol ciSym, - Symbol tcSym) { - if (tcSym.isStatic()) { - int pos = tcSym.pos; - Tree rhs = tConstructorRHS(pos, clsSym, ciSym); - Tree assign = gen.Assign(pos, gen.Ident(pos, tcSym), rhs); - - return gen.DefDef(ciSym, assign); - } else - return Tree.Empty; - } - - private Tree tConstructorRHS(int pos, Symbol clsSym, Symbol owner) { - int zCount = 0, mCount = 0, pCount = 0; - Symbol[] tparams = clsSym.typeParams(); - - for (int i = 0; i < tparams.length; ++i) { - if ((tparams[i].flags & Modifiers.COVARIANT) != 0) - ++pCount; - else if ((tparams[i].flags & Modifiers.CONTRAVARIANT) != 0) - ++mCount; - else - ++zCount; - } - - Ancestor[][] ancestors = computeAncestors(clsSym); - int[] ancestorCode = getAncestorCode(ancestors); - - Tree outer = isNestedClass(clsSym) - ? (clsSym.owner().isClass() - ? gen.This(pos, clsSym.owner()) - : gen.mkGlobalRef(pos, defs.TYPECONSTRUCTOR_FUNCTIONOUTER())) - : gen.mkNullLit(pos); - - Tree[] tcArgs = new Tree[] { - gen.mkIntLit(pos, level(clsSym)), - gen.mkSymbolNameLit(pos, clsSym), - outer, - gen.mkIntLit(pos, zCount), - gen.mkIntLit(pos, mCount), - gen.mkIntLit(pos, pCount), - gen.mkIntLit(pos, ancestors.length), - ancestorCode.length == 0 - ? gen.mkNullLit(pos) - : mkNewIntLitArray(pos, getAncestorCode(ancestors), owner) - }; - - Symbol tcConst = defs.TYPECONSTRUCTOR_CLASS.primaryConstructor(); - Tree tcCall = - gen.mkApply_V(pos, gen.mkGlobalRef(pos, tcConst), tcArgs); - return gen.New(pos, tcCall); - } - - private Tree mkNewIntLitArray(int pos, int[] values, Symbol owner) { - Tree[] intLits = new Tree[values.length]; - for (int i = 0; i < values.length; ++i) - intLits[i] = gen.mkIntLit(pos, values[i]); - return gen.mkNewArray(pos, defs.INT_TYPE(), intLits, owner); - } - - private Tree lazyParentsClass(Symbol clsSym, Symbol lazyClsSym) { - int pos = clsSym.pos; - - Symbol typesSym = lazyClsSym.primaryConstructor().valueParams()[0]; - - Symbol forceSym = lazyClsSym.newMethod(pos, 0, Names.force); - forceSym.setInfo(lazyForceType); - lazyClsSym.members().enter(forceSym); - Tree.DefDef forceDef = - gen.DefDef(forceSym, - parentsArray(pos, clsSym, typesSym, forceSym)); - - return gen.ClassDef(lazyClsSym, new Tree[] { forceDef }); - } - - /** - * Return a method to instantiate the given type. - */ - private Tree.DefDef instantiatorBody(Symbol clsSym, - Symbol insSym, - boolean lazy) { - // TODO fix flags for all symbols below - final int pos = clsSym.pos; - final Symbol typesArr = insSym.valueParams()[0]; - - Tree[] body = new Tree[2]; - - // Generate call to "getInstantiation" method of - // constructor. - Tree getInstFun = - gen.Select(pos, - gen.mkLocalRef(pos, getTConstructorSym(clsSym)), - defs.TYPECONSTRUCTOR_GETINSTANTIATION()); - - Tree[] getInstArgs = new Tree[]{ gen.mkLocalRef(pos, typesArr) }; - - Symbol instVal = - insSym.newVariable(pos, 0, Name.fromString("inst")); - instVal.setInfo(defs.SCALACLASSTYPE_TYPE()); - - Tree instValDef = - gen.ValDef(instVal, - gen.mkApply_V(pos, getInstFun, getInstArgs)); - - // Generate test to see if a call to "instantiate" is - // necessary. - Tree cond = - gen.mkApply_V(pos, - gen.Select(pos, - gen.mkLocalRef(pos, instVal), - defs.ANY_BANGEQ), - new Tree[] { gen.mkNullLit(pos) }); - Tree thenP = gen.mkLocalRef(pos, instVal); - Tree elseP = lazy - ? lazyInstantiateCall(pos, clsSym, typesArr) - : strictInstantiateCall(pos, clsSym, typesArr, insSym); - Tree ifExpr = - gen.If(pos, cond, thenP, elseP, defs.SCALACLASSTYPE_TYPE()); - - return gen.DefDef(insSym, gen.mkBlock(pos, instValDef, ifExpr)); - } - - private Tree strictInstantiateCall(int pos, - Symbol clsSym, - Symbol tpArraySym, - Symbol owner) { - Tree instFun = - gen.Select(pos, - gen.mkLocalRef(pos, getTConstructorSym(clsSym)), - defs.TYPECONSTRUCTOR_INSTANTIATE()); - Tree[] instArgs = new Tree[] { - gen.mkLocalRef(pos, tpArraySym), - parentsArray(pos, clsSym, tpArraySym, owner) - }; - return gen.mkApply_V(pos, instFun, instArgs); - } - - private Tree lazyInstantiateCall(int pos, - Symbol clsSym, - Symbol tpArraySym) { - Tree instFun = - gen.Select(pos, - gen.mkLocalRef(pos, getTConstructorSym(clsSym)), - defs.TYPECONSTRUCTOR_INSTANTIATE()); - Symbol lpcSym = getLazyParentClassSym(clsSym); - Tree lazyConstr = - gen.mkPrimaryConstructorLocalRef(pos, lpcSym); - Tree[] lazyConstrArgs = new Tree[] { - gen.mkLocalRef(pos, tpArraySym) - }; - Tree[] instArgs = new Tree[] { - gen.mkLocalRef(pos, tpArraySym), - gen.New(pos, gen.mkApply_V(lazyConstr, lazyConstrArgs)) - }; - return gen.mkApply_V(pos, instFun, instArgs); - } - - private Tree parentsArray(final int pos, - final Symbol clsSym, - final Symbol tpArraySym, - final Symbol owner) { - final HashMap varMap = new HashMap(); - final Symbol[] tparams = clsSym.typeParams(); - for (int i = 0; i < tparams.length; ++i) - varMap.put(tparams[i], new Integer(i)); - - // Type environment mapping the type parameters of the - // class to their corresponding element in the "types" - // array passed to this instantiator. - TEnv tEnv = new TEnv() { - public boolean definesVar(Symbol sym) { - return varMap.containsKey(sym); - } - public Tree treeForVar(Symbol sym) { - int idx = ((Integer)varMap.get(sym)).intValue(); - Tree array = gen.mkLocalRef(pos, tpArraySym); - return gen.mkArrayGet(pos, array, idx); - } - public boolean definesVarArray(Symbol[] syms) { - if (syms.length == tparams.length) { - for (int i = 0; i < syms.length; ++i) { - if (syms[i] != tparams[i]) - return false; - } - return true; - } else - return false; - } - public Tree treeForVarArray(Symbol[] syms) { - assert definesVarArray(syms); - return gen.mkLocalRef(pos, tpArraySym); - } - }; - - Type[] parents = clsSym.parents(); - TreeList parentTypes = new TreeList(); - for (int i = 0; i < parents.length; ++i) { - Type parent = parents[i]; - if (!isStronglyTrivial(parent)) - parentTypes.append(typeAsValue(pos, parent, owner, tEnv)); - } - boolean emptyParents = (parentTypes.length() == 0); - return emptyParents - ? gen.mkGlobalRef(pos, defs.SCALACLASSTYPE_EMPTYARRAY()) - : gen.mkNewArray(pos, - defs.SCALACLASSTYPE_TYPE(), - parentTypes.toArray(), - owner); - } - - /** - * Generate code to test if the given expression is an - * instance of the given type. - */ - private Tree genInstanceTest(int pos, Tree expr, Type tp) { - Tree tpVal = typeAsValue(pos, tp, currentOwner, EENV); - - if (isKnowClassType(tp)) { - Symbol val = - currentOwner.newVariable(pos, - Modifiers.SYNTHETIC, - Names.LOCAL(currentOwner)); - val.setType(expr.type); - - Tree valDef = gen.ValDef(val, expr); - - Tree cheapTest = - gen.mkIsInstanceOf(pos, gen.mkLocalRef(pos, val), tp, true); - Symbol isNonTrivialInst = defs.CLASSTYPE_ISNONTRIVIALINSTANCE(); - Tree scalaTpVal = gen.mkAsInstanceOf(pos, - tpVal, - defs.CLASSTYPE_TYPE(), - true); - Tree expensiveTest = - gen.mkApply_V(pos, - gen.Select(pos, scalaTpVal, isNonTrivialInst), - new Tree[] { gen.mkLocalRef(pos, val) }); - - Tree bothTests = - gen.mkApply_V(pos, - gen.Select(pos, - cheapTest, - defs.BOOLEAN_AND()), - new Tree[] { expensiveTest }); - - return gen.mkBlock(pos, valDef, bothTests); - } else { - Tree fun = gen.Select(pos, tpVal, defs.TYPE_ISINSTANCE()); - return gen.mkApply_V(pos, fun, new Tree[] { expr }); - } - } - - /** - * Generate code to cast the given value to the given type. - */ - private Tree genTypeCast(int pos, Tree expr, Type tp) { - Tree tpVal = typeAsValue(pos, tp, currentOwner, EENV); - Tree fun = gen.Select(pos, tpVal, defs.TYPE_CAST()); - Tree castCall = gen.mkApply_V(pos, fun, new Tree[] { expr }); - return gen.mkAsInstanceOf(pos, castCall, tp); - } - - private boolean isSpecial(Type tp) { - switch (tp) { - case TypeRef(_, Symbol sym, _): - return (sym == defs.ANY_CLASS) - || (sym == defs.ANYVAL_CLASS) - || (sym == defs.ALLREF_CLASS) - || (sym == defs.ALL_CLASS); - default: - return false; - } - } - - private boolean isKnowClassType(Type tp) { - switch (tp) { - case TypeRef(_, Symbol sym, _): - return (sym != defs.ARRAY_CLASS) && !sym.isParameter(); - default: - return false; - } - } - - private void addConstructorsNeededBy(HashSet roots, - Type tp, - HashSet set){ - switch (tp) { - case TypeRef(_, Symbol pSym, Type[] args): - if (!pSym.isParameter()) { - set.add(pSym); - set.addAll(constructorsNeededBy(roots, pSym)); - for (int i = 0; i < args.length; ++i) - addConstructorsNeededBy(roots, args[i], set); - } - break; - case CompoundType(Type[] parts, _): - for (int i = 0; i < parts.length; ++i) - addConstructorsNeededBy(roots, parts[i], set); - default: - ; // nothing to do - } - } - - private HashSet constructorsNeededBy(HashSet roots, Symbol sym) { - HashSet constr = new HashSet(); - if (roots.add(sym)) { - Type[] parents = sym.parents(); - for (int i = 0; i < parents.length; ++i) - addConstructorsNeededBy(roots, parents[i], constr); - } - return constr; - } - - private HashSet constructorsNeededBy(Symbol sym) { - HashSet constr = (HashSet)constructorNeed.get(sym); - if (constr == null) { - constr = constructorsNeededBy(new HashSet(), sym); - constructorNeed.put(sym, constr); - } - return constr; - } - - private boolean isCyclic(Symbol sym) { - HashSet constrs = constructorsNeededBy(sym); - if (constrs.contains(sym)) - return true; - Iterator constrsIt = constrs.iterator(); - while (constrsIt.hasNext()) { - Symbol constr = (Symbol)constrsIt.next(); - if (constr.isAbstractType()) - return true; - } - return false; - } - - /** - * Transform a type into a tree representing it. - */ - private Tree typeAsValue(int pos, Type tp, Symbol owner, TEnv env) { - switch (tp) { - case ConstantType(Type base, _): - return typeAsValue(pos, base, owner, env); - - case TypeRef(Type pre, Symbol sym, Type[] args): - if (env.definesVar(sym)) { - assert args.length == 0; - return env.treeForVar(sym); - } else if (sym == defs.ARRAY_CLASS) { - assert args.length == 1; - return arrayType(pos, args[0], owner, env); - } else if (predefTypes.containsKey(sym)) { - return gen.mkGlobalRef(pos, (Symbol)predefTypes.get(sym)); - } else if (sym.isJava()) { - assert args.length <= 1 - : Debug.show(sym) + " " + args.length; - return javaClassType(pos, sym); - } else if (!sym.isParameter()) { - // Reference to a "global" type. - return scalaClassType(pos, tp, owner, env); - } else { - assert !isValuePrefix(pre) : tp; - return gen.mkLocalRef(pos, getAccessorSym(sym)); - } - - case SingleType(Type pre, Symbol sym): - return singleType(pos, (Type.SingleType)tp); - - case ThisType(Symbol sym): - return thisType(pos, sym); - - case CompoundType(Type[] parts, Scope members): - return compoundType(pos, parts, members, owner, env); - - default: - throw Debug.abortIllegalCase(tp); - } - } - - private Tree arrayType(int pos, - Type elemType, - Symbol owner, - TEnv env) { - Type realElemType = elemType; - int dimensions = 1; - while (realElemType.symbol() == defs.ARRAY_CLASS) { - realElemType = realElemType.typeArgs()[0]; - ++dimensions; - } - - if (isTrivial(elemType)) { - Tree nameLit; - if (basicTypes.containsKey(elemType)) - nameLit = - gen.mkStringLit(pos, (String)basicTypes.get(elemType)); - else - nameLit = gen.mkSymbolNameLit(pos, realElemType.symbol()); - - Tree constr = - gen.mkGlobalRef(pos, defs.JAVACLASSTYPE_JAVAARRAYTYPE()); - Tree[] args = new Tree[]{ - nameLit, - gen.mkIntLit(pos, dimensions) - }; - return gen.mkApply_V(constr, args); - } else { - Tree constr = - gen.mkGlobalRef(pos, - defs.JAVAREFARRAYTYPE_JAVAREFARRAYTYPE()); - Tree[] args = new Tree[]{ - typeAsValue(pos, elemType, owner, env), - gen.mkIntLit(pos, dimensions) - }; - return gen.mkApply_V(constr, args); - } - } - - private Tree javaClassType(int pos, Symbol sym) { - Tree constr = - gen.mkGlobalRef(pos, defs.JAVACLASSTYPE_JAVACLASSTYPE()); - Tree nameLit = gen.mkSymbolNameLit(pos, sym); - Tree[] args = new Tree[] { nameLit }; - return gen.mkApply_V(constr, args); - } - - private Tree thisType(int pos, Symbol sym) { - Tree constr = - gen.mkPrimaryConstructorGlobalRef(pos, defs.SINGLETYPE_CLASS); - Tree[] args = new Tree[] { gen.This(pos, sym) }; - return gen.New(pos, gen.mkApply_V(constr, args)); - } - - private Tree singleType(int pos, Type.SingleType tp) { - Tree constr = - gen.mkPrimaryConstructorGlobalRef(pos, defs.SINGLETYPE_CLASS); - Tree[] args = new Tree[] { gen.mkQualifier(pos, tp) }; - return gen.New(pos, gen.mkApply_V(constr, args)); - } - - private Tree compoundType(int pos, - Type[] parts, - Scope members, - Symbol owner, - TEnv env) { - Tree[] partsT = new Tree[parts.length]; - for (int i = 0; i < parts.length; ++i) - partsT[i] = typeAsValue(pos, parts[i], owner, env); - - Tree[] constrArgs = new Tree[] { - gen.mkNewArray(pos, defs.CLASSTYPE_TYPE(), partsT, owner), - gen.mkBooleanLit(pos, members.isEmpty()) - }; - Tree constr = - gen.mkPrimaryConstructorGlobalRef(pos, - defs.COMPOUNDTYPE_CLASS); - return gen.New(pos, gen.mkApply_V(constr, constrArgs)); - } - - private Tree scalaClassType(int pos, Type tp, Symbol owner, TEnv env) { - if (isStronglyTrivial(tp)) - return javaClassType(pos, tp.symbol()); - - switch (tp) { - case TypeRef(Type pre, Symbol sym, Type[] args): - Symbol insSym = getInstMethSym(sym); - Tree preFun = (isNestedClass(sym) && sym.owner().isClass()) - ? gen.Select(pos, gen.mkQualifier(pos, pre), insSym) - : gen.Ident(pos, insSym); - - Tree insArg; - int[] perm = typeParamsPermutation(sym.typeParams()); - Symbol[] permArgs = new Symbol[args.length]; - for (int i = 0; i < args.length; ++i) - permArgs[i] = args[perm[i]].symbol(); - - if (env.definesVarArray(permArgs)) - insArg = env.treeForVarArray(permArgs); - else { - Tree[] tps = new Tree[args.length]; - for (int i = 0; i < args.length; ++i) - tps[i] = typeAsValue(pos, args[perm[i]], owner, env); - insArg = gen.mkNewArray(pos, defs.TYPE_TYPE(), tps, owner); - } - - return gen.mkApply_V(pos, preFun, new Tree[] { insArg }); - - default: - throw Debug.abort("unexpected type: ", tp); - } - } - - private final int VARIANT = - Modifiers.COVARIANT | Modifiers.CONTRAVARIANT; - - /** - * Compute the (unique) permutation which puts all invariant - * type parameters first, followed by the contravariant ones, - * then the covariants, preserving the relative ordering of - * arguments with same variance. - */ - private int[] typeParamsPermutation(Symbol[] params) { - int[] tparamsPerm = new int[params.length]; - int permIdx = 0; - - for (int i = 0; i < params.length; ++i) - if ((params[i].flags & VARIANT) == 0) - tparamsPerm[permIdx++] = i; - for (int i = 0; i < params.length; ++i) - if ((params[i].flags & Modifiers.CONTRAVARIANT) != 0) - tparamsPerm[permIdx++] = i; - for (int i = 0; i < params.length; ++i) - if ((params[i].flags & Modifiers.COVARIANT) != 0) - tparamsPerm[permIdx++] = i; - assert permIdx == tparamsPerm.length; - - return tparamsPerm; - } - - private boolean isValuePrefix(Type pre) { - switch (pre) { - case ThisType(Symbol clazz): - return !(clazz.isPackage() || clazz.isNone()); - case NoPrefix: - return false; - default: - return true; - } - } - - private Ancestor[][] computeAncestors0(Symbol classSym) { - Symbol[] nstParents = notStronglyTrivialParents(classSym); - int level = level(classSym); - ArrayList/*<Ancestor>*/[] ancestor = new ArrayList[level + 1]; - - for (int l = 0; l < ancestor.length; ++l) - ancestor[l] = new ArrayList(); - - if (!isTrivial(classSym.type())) - ancestor[level].add(new Ancestor(classSym, -1, -1)); - - // Go over parents from left to right and add missing - // ancestors to the set, remembering where they come from. - for (int p = 0; p < nstParents.length; ++p) { - Symbol parentSymbol = nstParents[p]; - Ancestor[][] parentAncestors = computeAncestors(parentSymbol); - assert parentAncestors.length <= ancestor.length; - - for (int l = 0; l < parentAncestors.length; ++l) { - ArrayList/*<Ancestor>*/ myRow = ancestor[l]; - Ancestor[] parentRow = parentAncestors[l]; - parentRowLoop: - for (int i = 0; i < parentRow.length; ++i) { - Symbol sym = parentRow[i].symbol; - assert !isTrivial(sym.type()) : sym; - - Iterator myRowIt = myRow.iterator(); - while (myRowIt.hasNext()) { - Ancestor myAncestor = (Ancestor)myRowIt.next(); - if (myAncestor.symbol == sym) - continue parentRowLoop; - } - myRow.add(new Ancestor(sym, p, i)); - } - } - } - - int ancestorsLen = ancestor.length; - while (ancestorsLen > 0 && ancestor[ancestorsLen - 1].isEmpty()) - --ancestorsLen; - - Ancestor[][] finalAncestor = new Ancestor[ancestorsLen][]; - for (int i = 0; i < finalAncestor.length; ++i) { - finalAncestor[i] = (Ancestor[]) - ancestor[i].toArray(new Ancestor[ancestor[i].size()]); - } - - return finalAncestor; - } - - /** Return the non-trivial ancestors of the class */ - private Ancestor[][] computeAncestors(Symbol classSym) { - Ancestor[][] ancestor = (Ancestor[][])ancestorCache.get(classSym); - if (ancestor == null) { - ancestor = computeAncestors0(classSym); - ancestorCache.put(classSym, ancestor); -// debugPrintAncestor(classSym, ancestor); - } - return ancestor; - } - - /** Return the parents which are not strongly trivial. */ - private Symbol[] notStronglyTrivialParents(Symbol classSym) { - Type[] parentTypes = classSym.parents(); - ArrayList nstParents = new ArrayList(parentTypes.length); - for (int i = 0; i < parentTypes.length; ++i) { - if (!isStronglyTrivial(parentTypes[i])) - nstParents.add(parentTypes[i].symbol()); - } - return (Symbol[]) - nstParents.toArray(new Symbol[nstParents.size()]); - } - - private int[] getAncestorCode(Ancestor[][] ancestor) { - ArrayList/*<Ancestor>*/[] prunedRows = - new ArrayList[ancestor.length]; - - int totalSize = 0; - for (int l = 0; l < ancestor.length; ++l) { - Ancestor[] row = ancestor[l]; - ArrayList/*<Ancestor>*/ prunedRow = new ArrayList(row.length); - for (int i = 0; i < row.length; ++i) { - if (row[i].parentIndex > 0) - prunedRow.add(row[i]); - } - prunedRows[l] = prunedRow; - if (!prunedRow.isEmpty()) - totalSize += 2 + 2 * prunedRow.size(); - } - - int[] res = new int[totalSize]; - int i = 0; - for (int l = 0; l < prunedRows.length; ++l) { - ArrayList row = prunedRows[l]; - if (!row.isEmpty()) { - res[i++] = l; - res[i++] = row.size(); - Iterator ancIt = row.iterator(); - while (ancIt.hasNext()) { - Ancestor anc = (Ancestor)ancIt.next(); - res[i++] = anc.parentIndex; - res[i++] = anc.position; - } - } - } - assert i == totalSize; - return res; - } - } - - /** - * Minimalistic transformer, which simply transforms calls to - * isInstanceOf/asInstanceOf by calls to their erased - * counterparts. Used when full run time types are disabled. - */ - private class TV_MiniTransformer extends GenTransformer { - private final Definitions defs; - - public TV_MiniTransformer(Global global) { - super(global); - defs = global.definitions; - } - - public Tree transform(Tree tree) { - switch (tree) { - case Apply(TypeApply(Tree fun, Tree[] targs), Tree[] vargs): - Symbol funSym = fun.symbol(); - if (funSym == defs.ANY_IS || funSym == defs.ANY_AS) { - assert vargs.length == 0; - Symbol erasedSym = (funSym == defs.ANY_AS) - ? defs.ANY_AS_ERASED - : defs.ANY_IS_ERASED; - return gen.mkApplyTV(tree.pos, - gen.Select(fun.pos, - transform(qualifierOf(fun)), - erasedSym), - targs, - vargs); - } else - return super.transform(tree); - - default: - return super.transform(tree); - } - } - } - - /** - * Extract qualifier from a tree, which must be a Select node. - */ - private Tree qualifierOf(Tree tree) { - switch (tree) { - case Select(Tree qualifier, _): return qualifier; - default: throw Debug.abort("cannot extract qualifier from ", tree); - } - } - - // Debugging function - private void debugPrintAncestor(Symbol sym, Ancestor[][] ancestor) { - System.out.println("ancestor for " + Debug.show(sym)); - for (int l = 0; l < ancestor.length; ++l) { - System.out.print(" [" + l + "] "); - for (int i = 0; i < ancestor[l].length; ++i) { - if (i > 0) - System.out.print(" "); - System.out.println(" " + Debug.show(ancestor[l][i].symbol) - + "/par" + ancestor[l][i].parentIndex - + "/pos" + ancestor[l][i].position); - } - if (ancestor[l].length == 0) - System.out.println("<empty>"); - } - } - - ////////////////////////////////////////////////////////////////////// - - private static class TEnv { - public boolean definesVar(Symbol sym) { - return false; - } - public Tree treeForVar(Symbol sym) { - throw Debug.abort("no tree for variable " + sym); - } - public boolean definesVarArray(Symbol[] syms) { - return false; - } - public Tree treeForVarArray(Symbol[] syms) { - throw Debug.abort("no tree for variable array " + syms); - } - } - - private static class Ancestor { - public static final Ancestor[] EMPTY_ARRAY = new Ancestor[0]; - - public final Symbol symbol; - public final int parentIndex; - public final int position; - - public Ancestor(Symbol symbol, int parentIndex, int position) { - this.symbol = symbol; - this.parentIndex = parentIndex; - this.position = position; - } - } -} diff --git a/sources/scalac/transformer/WholeProgPhase.java b/sources/scalac/transformer/WholeProgPhase.java deleted file mode 100644 index 7591352c21..0000000000 --- a/sources/scalac/transformer/WholeProgPhase.java +++ /dev/null @@ -1,32 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $Id$ - -package scalac.transformer; - -import scalac.Global; -import scalac.Phase; -import scalac.PhaseDescriptor; - -/** - * This class represents the wholeprog phase for the java version of - * the compiler. It doesn't do anything but permit to make a bridge - * between the java implementation of Socos and the scala one. See - * scala.tools.scalac.wholeprog.WholeProgPhase for implementation. - */ -public abstract class WholeProgPhase extends Phase { - - //######################################################################## - // Public Constructors - - /** Initializes this instance. */ - public WholeProgPhase(Global global, PhaseDescriptor descriptor) { - super(global, descriptor); - } - - //######################################################################## -} |