summaryrefslogtreecommitdiff
path: root/sources/scalac/transformer
diff options
context:
space:
mode:
Diffstat (limited to 'sources/scalac/transformer')
-rw-r--r--sources/scalac/transformer/AddAccessorsPhase.java146
-rw-r--r--sources/scalac/transformer/AddConstructors.java295
-rw-r--r--sources/scalac/transformer/AddConstructorsPhase.java63
-rw-r--r--sources/scalac/transformer/AddInterfaces.java304
-rw-r--r--sources/scalac/transformer/AddInterfacesPhase.java313
-rw-r--r--sources/scalac/transformer/Erasure.java759
-rw-r--r--sources/scalac/transformer/ErasurePhase.java135
-rw-r--r--sources/scalac/transformer/ExpandMixinsPhase.java473
-rw-r--r--sources/scalac/transformer/ExplicitOuterClassesPhase.java558
-rw-r--r--sources/scalac/transformer/ICodePhase.java42
-rw-r--r--sources/scalac/transformer/LambdaLift.java763
-rw-r--r--sources/scalac/transformer/LambdaLiftPhase.java175
-rw-r--r--sources/scalac/transformer/MakeBoxingExplicitPhase.java50
-rw-r--r--sources/scalac/transformer/OwnerTransformer.java189
-rw-r--r--sources/scalac/transformer/TailCallPhase.java296
-rw-r--r--sources/scalac/transformer/TypesAsValuesPhase.java1415
-rw-r--r--sources/scalac/transformer/WholeProgPhase.java32
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);
- }
-
- //########################################################################
-}