package edu.neu.ccs.demeterf.demfgen.pcdgp;

import edu.neu.ccs.demeterf.*;
import edu.neu.ccs.demeterf.demfgen.Diff;
import edu.neu.ccs.demeterf.demfgen.classes.*;
import edu.neu.ccs.demeterf.demfgen.StrLTrip.StrPair;
import edu.neu.ccs.demeterf.lib.List;
import edu.neu.ccs.demeterf.lib.ident;
import edu.neu.ccs.demeterf.util.Util;

/**  */
public class HashCode extends Typical{
    
    public HashCode(List<String> sFs){ super(sFs); }
    public FC functionObj(List<String> superFs){ return new HashCode(superFs); }
    
    public String combine(ClassDef td, DoGen g, final ident n, TypeDefParams ps, List<String> sts, List<StrPair> fs){
        if(!sts.isEmpty())return "";
        return ("    /** Compute a HashCode for this "+n+" */\n"+
                "    public"+Diff.d.override+" "+Diff.d.hashRet+" "+Diff.d.hashMethod+"(){\n"+
                "        return ("+(fs.isEmpty()?n.hashCode():fs.pop().foldl(new List.Fold<StrPair, String>(){
                    int mult = 1;
                    public String fold(StrPair f, String r){
                        mult += 2;
                        return r+"+("+mult+" * ("+wrapPrim(f.n)+f.b+")."+Diff.d.hashMethod+"())";
                    }
                }, "("+wrapPrim(fs.top().n)+fs.top().b+")."+Diff.d.hashMethod+"()"))+");\n    }\n");
    }
    String wrapPrim(String t){
        if(Diff.isCS() || !Diff.d.primitives.contains(t))return "";
        return "("+Diff.d.box(t)+")";
    }
}