/* ____ ____ ____ ____ ______ *\
** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
** /_____/\____/\___/\____/____/ **
\* */
// $Id$
package scalac.ast;
import scalac.Global;
import scalac.CompilationUnit;
import scalac.symtab.Type;
{#Imports#}
/**
* A default transformer class. This class traverses the abstract
* syntax tree but does not do any transformations.
*/
public class Transformer {
//########################################################################
// Public Fields
/** The global environment */
public final Global global;
/** The tree factory */
public final TreeFactory make;
/** The tree copier */
public final TreeCopier copy;
/** A tree generator */
public final TreeGen gen;
//########################################################################
// Public Constructors
public Transformer(Global global) {
this(global, global.make);
}
public Transformer(Global global, TreeFactory make) {
this(global, make, new LazyTreeCopier(make));
}
public Transformer(Global global, TreeFactory make, TreeCopier copy) {
this.global = global;
this.make = make;
this.copy = copy;
this.gen = global.treeGen;
}
//########################################################################
// Public Methods
public void apply(CompilationUnit[] units) {
for (int i = 0; i < units.length; i++) apply(units[i]);
}
public void apply(CompilationUnit unit) {
unit.global.log("transforming " + unit);
unit.body = transform(unit.body);
}
public Tree transform(Tree tree) {
{#TreeSwitch#}
}
public Template transform(Template tree) {
return (Template)transform((Tree)tree);
}
{#TransformArrays#}
//########################################################################
}
public class GenTransformer {
//########################################################################
// Public Fields
/** The global environment */
public final Global global;
/** The type map */
public final Type.Map map;
/** A tree generator */
public final TreeGen gen;
//########################################################################
// Public Constructors
/** Initializes this instance with an identity type map. */
public GenTransformer(Global global) {
this(global, Type.IdMap);
}
/** Initializes this instance with given type map. */
public GenTransformer(Global global, Type.Map map) {
this.global = global;
this.gen = global.treeGen;
this.map = map;
}
//########################################################################
// Public Methods
/** Transforms the given units. */
public void apply(CompilationUnit[] units) {
for (int i = 0; i < units.length; i++) apply(units[i]);
}
/** Transforms the given unit. */
public void apply(CompilationUnit unit) {
unit.global.log("transforming " + unit);
unit.body = transform(unit.body);
}
/** Transforms the given symbol. */
public Symbol getSymbolFor(Tree tree) {
return tree.symbol();
}
/** Transforms the given types. */
public Type[] transform(Type[] types) {
for (int i = 0; i < types.length; i++) {
Type type = transform(types[i]);
if (type == types[i]) continue;
Type[] clones = new Type[types.length];
for (int j = 0; j < i; j++) clones[j] = types[j];
clones[i] = type;
for (; i < types.length; i++) clones[i] = transform(types[i]);
return clones;
}
return types;
}
/** Transforms the given type. */
public Type transform(Type type) {
return map.apply(type);
}
/** Transforms the given tree. */
public Tree transform(Tree tree) {
switch (tree) {
// case Bad():
case Empty:
return tree;
case ClassDef(_, _, _, _, _, Template impl):
Symbol symbol = getSymbolFor(tree);
if (global.currentPhase.id < global.PHASE.ADDCONSTRUCTORS.id()) {
Symbol impl_symbol = getSymbolFor(impl);
Tree[] parents = transform(impl.parents);
Tree[] body = transform(impl.body);
return gen.ClassDef(symbol, parents, impl_symbol, body);
} else {
Tree[] body = transform(impl.body);
return gen.ClassDef(symbol, body);
}
case PackageDef(Tree packaged, Template(Tree[] parents, Tree[] body)):
Symbol symbol = getSymbolFor(packaged);
assert parents.length == 0: tree;
return gen.PackageDef(symbol, transform(body));
// case ModuleDef(_, _, _, Template impl):
case ValDef(_, _, _, Tree rhs):
Symbol symbol = getSymbolFor(tree);
return gen.ValDef(symbol, transform(rhs));
// case PatDef(int mods, Tree pat, Tree rhs):
case DefDef(_, _, _, _, _, Tree rhs):
Symbol symbol = getSymbolFor(tree);
return gen.DefDef(symbol, transform(rhs));
case AbsTypeDef(_, _, _, _):
Symbol symbol = getSymbolFor(tree);
return gen.AbsTypeDef(symbol);
case AliasTypeDef(_, _, _, _):
Symbol symbol = getSymbolFor(tree);
return gen.AliasTypeDef(symbol);
case Import(Tree expr, Name[] selectors):
return gen.Import(tree.pos, transform(expr), selectors);
case CaseDef(Tree pat, Tree guard, Tree body):
pat = transform(pat);
guard = transform(guard);
body = transform(body);
return gen.CaseDef(pat, guard, body);
// case Template(Tree[] parents, Tree[] body):
case LabelDef(_, Ident[] params, Tree rhs):
Symbol symbol = getSymbolFor(tree);
return gen.LabelDef(symbol, transform(params), transform(rhs));
case Block(Tree[] stats, Tree value):
return gen.Block(tree.pos, transform(stats), transform(value));
// case Sequence(Tree[] trees):
// case Alternative(Tree[] trees):
// case Bind(Name name, Tree rhs):
// case Visitor(CaseDef[] cases):
// case Function(ValDef[] vparams, Tree body):
case Assign(Tree lhs, Tree rhs):
return gen.Assign(tree.pos, transform(lhs), transform(rhs));
case If(Tree cond, Tree thenp, Tree elsep):
cond = transform(cond);
thenp = transform(thenp);
elsep = transform(elsep);
if (tree.type().isSameAs(global.definitions.ANY_TYPE())) {
global.nextPhase();
Type type = global.definitions.ANY_TYPE();
global.prevPhase();
return gen.If(tree.pos, cond, thenp, elsep, type);
} else {
return gen.If(tree.pos, cond, thenp, elsep);
}
case Switch(Tree test, int[] tags, Tree[] bodies, Tree otherwise):
test = transform(test);
bodies = transform(bodies);
otherwise = transform(otherwise);
if (tree.type().isSameAs(global.definitions.ANY_TYPE())) {
global.nextPhase();
Type type = global.definitions.ANY_TYPE();
global.prevPhase();
return gen.Switch(tree.pos, test, tags, bodies,otherwise,type);
} else {
return gen.Switch(tree.pos, test, tags, bodies, otherwise);
}
case Return(Tree expr):
Symbol symbol = getSymbolFor(tree);
return gen.Return(tree.pos, symbol, transform(expr));
// case Throw(Tree expr):
case New(Tree init):
return gen.New(tree.pos, transform(init));
case Create(Tree qualifier, Tree[] args):
Symbol symbol = getSymbolFor(tree);
qualifier = transform(qualifier);
args = transform(args);
return gen.Create(tree.pos, qualifier, symbol, args);
case Typed(Tree expr, Tree tpe):
return gen.Typed(tree.pos, transform(expr), transform(tpe));
case TypeApply(Tree fun, Tree[] args):
return gen.TypeApply(transform(fun), transform(args));
case Apply(Tree fun, Tree[] args):
return gen.Apply(transform(fun), transform(args));
case Super(_, _):
Symbol symbol = getSymbolFor(tree);
return gen.Super(tree.pos, symbol);
case This(_):
Symbol symbol = getSymbolFor(tree);
return gen.This(tree.pos, symbol);
case Select(Tree qualifier, _):
Symbol symbol = getSymbolFor(tree);
return gen.Select(tree.pos, transform(qualifier), symbol);
case Ident(_):
Symbol symbol = getSymbolFor(tree);
return gen.Ident(tree.pos, symbol);
case Literal(AConstant value):
return gen.Literal(tree.pos, value);
case TypeTerm():
return gen.mkType(tree.pos, transform(tree.type()));
// case SingletonType(Tree ref):
// case SelectFromType(Tree qualifier, Name selector):
// case FunType(Tree[] argtpes, Tree restpe):
// case CompoundType(Tree[] parents, Tree[] refinements):
// case AppliedType(Tree tpe, Tree[] args):
// case Try(Tree block, Tree catcher, Tree finalizer):
default:
throw Debug.abort("illegal case", tree);
}
}
{#TransformArrays#}
//########################################################################
}