/* ____ ____ ____ ____ ______ *\ ** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** ** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** ** /_____/\____/\___/\____/____/ ** \* */ // $Id$ package scalac.ast; import scalac.Global; import scalac.Unit; 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(Unit[] units) { for (int i = 0; i < units.length; i++) apply(units[i]); } public void apply(Unit 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(Unit[] units) { for (int i = 0; i < units.length; i++) apply(units[i]); } /** Transforms the given unit. */ public void apply(Unit 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): return gen.Block(tree.pos, transform(stats)); // 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); 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); 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(Template(Tree[] base, Tree[] body)): assert base.length == 1 && body.length == 0: tree; return gen.New(tree.pos, transform(base[0])); 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#} //######################################################################## }