package edu.neu.ccs.demeterf.demfgen; import edu.neu.ccs.demeterf.Fields; import edu.neu.ccs.demeterf.demfgen.ClassGen.ArityPair; import edu.neu.ccs.demeterf.demfgen.ClassGen.ToList; import edu.neu.ccs.demeterf.demfgen.ClassGen.ToTDList; import edu.neu.ccs.demeterf.demfgen.classes.*; import edu.neu.ccs.demeterf.demfgen.traversals.Travs; import edu.neu.ccs.demeterf.lib.List; import edu.neu.ccs.demeterf.lib.ident; import edu.neu.ccs.demeterf.util.Util; /** Does a quick type check over the TypeDefs to be sure type parameters are used with * the correct arity, and uses/definitions exist */ public class TypeCheck extends StaticTP{ public static class Env{ String curr; List env; Env(List e){ this("ROOT",e); } Env(String c, List e){ curr = c; env = e; } Env push(List l){ return new Env(curr,env.push(l)); } Env enter(TypeDef d){ return new Env(d.name()+d.typeParams(), env); } boolean containsAny(List ps){ return env.containsAny(ps); } boolean contains(ArityPair p){ return env.contains(p); } } static ToList TOLIST = new ToList(); static List paramsToList(TypeDefParams p){ return Travs.TheFactory.makeParamArityTrav(TOLIST).traverse(p); } static ToTDList TOTDLIST = new ToTDList(); static List defsToList(TypeDefList tl){ return Travs.TheFactory.makeTypeArityTrav(TOTDLIST).traverse(tl); } public Env update(TypeDef t, Fields.any f, Env env){ List pars = paramsToList(t.typeParams()); if(env.containsAny(pars) && Util.warningOn) //throw new TE("Type param shadows another type in def. "+t.name()); ClassGen.p(" ** WARNING: Type param shadows another type in def: "+t.name()+"\n"); return env.push(pars).enter(t); } public TypeUse combine(TypeUse tus, ident n, TypeUseParams p, Env env){ ArityPair search = new ArityPair(""+n,0); if(!env.contains(search)) throw new TE("Unbound Type: "+n+"\n * In definition of: "+env.curr); ArityPair found = env.env.find(search); if(found.arity != p.length()) throw new TE("Wrong Number of Type Params for: "+n+"\n "+ " * Expected "+found.arity+" found "+p.length()+"\n"); return tus; } public TypeDef combine(TypeDef t){ return t; } }