package edu.neu.ccs.demeterf.demfgen;

import edu.neu.ccs.demeterf.*;
import edu.neu.ccs.demeterf.control.MutableControl;
import edu.neu.ccs.demeterf.demfgen.classes.*;
import edu.neu.ccs.demeterf.demfgen.ClassHier.*;
import edu.neu.ccs.demeterf.lib.List;
import edu.neu.ccs.demeterf.lib.ident;


/** Collect the Inheritance relationships from the CD */
public class CollectInherit extends ID{
    public static List<InhrtPair> inheritPairs(TypeDefList tdl){
        MutableControl c = Control.builtins(TypeUse.class, DefParams.class,
                                            UseParams.class, SumToken.class,
                                            DoGen.class,FieldList.class);
        c.addBypassing(IntfImpl.class);
        return Factory.newTraversalCtx(new CollectInherit(),c)
            .traverseTypeDefList(tdl,new InhrtStr("",List.<String>create(),List.<FieldOrSyntax>create()));
    }
    
    InhrtStr update(ClassDef t, Fields.any f, InhrtStr s)
    { return new InhrtStr(""+t.name(),t.getTparams().toList(),t.getFields().toList()); }
    InhrtStr update(IntfcDef t, Fields.any f, InhrtStr s)
    { return new IntfcStr(""+t.name(),t.getTparams().toList()); }
    
    InhrtPair combine(TypeUse tu, InhrtStr p){ return new InhrtPair(p,""+tu.getName(),
            tu.getTparams().toTUList()); }

    List<InhrtPair> combine(EmptyList c){ return List.<InhrtPair>create(); }
    List<InhrtPair> combine(ConsList c, InhrtPair sp, List<InhrtPair> r){
        return r.push(sp);
    }
    List<InhrtPair> combine(NoImpl i){ return List.<InhrtPair>create(); }
    List<InhrtPair> combine(IntfImpl i, NETypeUseList ifcs, final InhrtStr p){
        return ifcs.toTUList().map(new List.Map<TypeUse,InhrtPair>(){
            public InhrtPair map(TypeUse t){
                return new InhrtPair(new IntfcStr(""+t.getName(),
                        List.<String>create()),p.parent(),t.getTparams().toTUList());
            }
        });    
    }
    FieldList combine(FieldEmpty e){ return e; }
    List<InhrtPair> combine(IntfcDef t, DoGen g, ident n, Object parm, List<InhrtPair> pairs){ return pairs; }
    List<InhrtPair> combine(ClassDef t, DoGen g, ident n, Object parm,
                            List<InhrtPair> ext, FieldList fs, List<InhrtPair> infcs)
    { return ext.append(infcs); }
    List<InhrtPair> combine(ConsList c, List<InhrtPair> f, List<InhrtPair> r){
        return f.append(r);
    }
}