summaryrefslogblamecommitdiff
path: root/sources/scalac/ast/Transformer.java.tmpl
blob: bf97e2cbb14043ad0c8707fcf9ef7ccb2a7cbc3a (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12











                                                                          
                          











































                                                                              




















                                                                              









                                                                              


                              





                                                                              
                                                               
                                          




                                                         

                                  
                       















                                                                              























                                                                          









                                                    

                                                    

                                                     
                                                                    

                                                                              
                                                   
                                             
                                                           



                                                  

                                                      



                                                     

                                                      
 
                                    

                                               

                                      










                                                                    
 


                                                      

                                                                           

























                                                                          

                                                                 






                                                              

                                                                        







                                                                  

                                               

                     

                                               

                                       

                                                                      

                      

                                               




                                              
                                                                
















                                                                              
/*     ____ ____  ____ ____  ______                                     *\
**    / __// __ \/ __// __ \/ ____/    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);
            Symbol impl_symbol = getSymbolFor(impl);
            Tree[] parents = transform(impl.parents);
            Tree[] body = transform(impl.body);
            return gen.ClassDef(symbol, parents, impl_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(Object value):
            return gen.mkLit(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#}

    //########################################################################
}