package deadlock.analyser.generation; import java.util.List; import java.util.LinkedList; import java.util.Map; import java.util.HashMap; import java.util.Set; import java.util.HashSet; import abs.frontend.ast.ASTNode; import deadlock.analyser.factory.DataTypeInterface; import deadlock.analyser.factory.Contract; import deadlock.analyser.factory.ContractElementParallel; import deadlock.analyser.factory.FunctionInterface; import deadlock.analyser.factory.IRecord; import deadlock.analyser.factory.ITypingEnvironmentFutureType; import deadlock.analyser.factory.ITypingEnvironmentVariableType; import deadlock.analyser.factory.RecordPresent; import deadlock.analyser.factory.MethodInterface; import deadlock.analyser.factory.TypingEnvironmentFutureTypeUntick; import deadlock.analyser.factory.TypingEnvironmentVariableTypeFuture; public class TypingEnvironment { private static final String _connector = "."; // 1. Fields for declarations private Map<String, MethodInterface> methods; // Methods private Map<String, FunctionInterface> functions; //Functions private Map<String, DataTypeInterface> types; //DataTypes // 2. fields for inference of methods private Set<String>searchPath; private List<Map<String, ITypingEnvironmentVariableType>> variables; // stack frame of mapping variable => record or future private Map<TypingEnvironmentVariableTypeFuture, ITypingEnvironmentFutureType> futures; // mapping future => checked or unchecked /* Constructor */ public TypingEnvironment() { methods = new HashMap<>(); functions = new HashMap<>(); types = new HashMap<>(); searchPath = new HashSet<>(); variables = new LinkedList<>(); futures = new HashMap<>(); } public TypingEnvironment copy() { TypingEnvironment res = new TypingEnvironment(); res.methods = this.methods; res.functions = this.functions; res.types = this.types; res.searchPath = this.searchPath; res.variables = new LinkedList<>(this.variables); res.futures = new HashMap<>(this.futures); return res; } /* Basic Gets */ // declarations public MethodInterface getMethod(String className, String methodName) { MethodInterface res = null; for(String moduleName: this.searchPath) { System.out.println("checking with \"" + moduleName + _connector + className + _connector + methodName + "\""); res = methods.get(moduleName + _connector + className + _connector + methodName); if(res != null) return res; } return null; } public FunctionInterface getFunction(String function) { FunctionInterface res = null; for(String moduleName: this.searchPath) { res = functions.get(moduleName + _connector + function); if(res != null) return res; } return null; } public DataTypeInterface getDataType(String dataType) { DataTypeInterface res = null; for(String moduleName: this.searchPath) { res = types.get(moduleName + _connector + dataType); if(res != null) return res; } return null; } // Variables public ITypingEnvironmentVariableType getVariable(String name) { ITypingEnvironmentVariableType res = null; for(Map<String, ITypingEnvironmentVariableType> map: variables) { res = map.get(name); if(res != null) return res; } if((res == null) && (name != "this")) { RecordPresent t = (RecordPresent)(getVariable("this")); assert t != null : name; res = t.getField(name); // possible nullPointerException } return res; } public IRecord getVariableRecord(String name) { ITypingEnvironmentVariableType var = this.getVariable(name); return (var instanceof IRecord)?(IRecord)var : this.getFuture((TypingEnvironmentVariableTypeFuture)var).getRecord(); } public boolean isField(String name) { boolean res = true; for(Map<String, ITypingEnvironmentVariableType> map: variables) { res = (map.get(name) == null); if(!res) return false; } return true; } // Other gets public ITypingEnvironmentFutureType getFuture(TypingEnvironmentVariableTypeFuture fut){ return futures.get(fut); } public ContractElementParallel unsync(ASTNode<?> pos) { LinkedList<Contract> contracts = new LinkedList<Contract>(); Contract c; for(ITypingEnvironmentFutureType t: this.futures.values()) { if(t instanceof TypingEnvironmentFutureTypeUntick) { c = new Contract(); c.getSubTerms().add(((TypingEnvironmentFutureTypeUntick)t).getContract()); contracts.add(c); } } return new ContractElementParallel(pos, contracts); } public IRecord getRecord(ITypingEnvironmentVariableType x) { if (x instanceof IRecord) return (IRecord)x; else { final ITypingEnvironmentFutureType f = getFuture(((TypingEnvironmentVariableTypeFuture)x)); assert f != null : "I want the future now: "+x; return f.getRecord(); } } /* Basic Extension */ public void putMethod(String moduleName, String className, String methodName, MethodInterface mi) { methods.put(moduleName + _connector + className + _connector + methodName, mi); } public void putFunction(String moduleName, String name, FunctionInterface func) { functions.put(moduleName + _connector + name, func); } public void putDataType(String moduleName, String name, DataTypeInterface type) { types.put(moduleName + _connector + name, type); } public void newScope() { variables.add(0, new HashMap<String, ITypingEnvironmentVariableType>()); } public void popScope() { variables.remove(0); } public void putVariable(String name, ITypingEnvironmentVariableType record) { variables.get(0).put(name, record); } public void putFuture(TypingEnvironmentVariableTypeFuture f, ITypingEnvironmentFutureType z) { futures.put(f, z); } public void clearFutures() { futures = new HashMap<>(); } public void clearVariables() { variables = new LinkedList<>(); } public void addSearchPath(String name) { searchPath.add(name); } public void resetSearchPath() { searchPath = new HashSet<>(); } public void setSearchPath(Set<String> path) { searchPath = path; } /* public void add(TypingEnvironment e) { this.variables.putAll(e.variables); this.methods.putAll(e.methods); this.functions.putAll(e.functions); this.futures.putAll(e.futures); this.types.putAll(e.types); } public void updateValues(TypingEnvironment e) { for(Map.Entry<String, ITypingEnvironmentVariableType> entry : e.variables.entrySet()) { if(this.variables.containsKey(entry.getKey())) { this.variables.put(entry.getKey(), entry.getValue()); } } for(Map.Entry<String, MethodInterface> entry : e.methods.entrySet()) { if(this.methods.containsKey(entry.getKey())) { this.methods.put(entry.getKey(), entry.getValue()); } } }*/ /* toString */ public String toStringSearchPath() { String res = "{ "; for(String s: searchPath) { res = res + s + " "; } res = res + "}"; return res; } public String toStringVariables() { String res = ""; Set<String> checkedVariables = new HashSet<>(); for(Map<String, ITypingEnvironmentVariableType> el: variables) { for(Map.Entry<String, ITypingEnvironmentVariableType> e : el.entrySet()){ if(!checkedVariables.contains(e.getKey())) { res = res + "\t" + e.getKey() + " := " + e.getValue().toString() + "\n"; checkedVariables.add(e.getKey()); } } } return res; } public String toString() { String res = "{ "; for(String s: searchPath) { res = res + s + " "; } res = res + "}\n"; Set<String> checkedVariables = new HashSet<>(); for(Map<String, ITypingEnvironmentVariableType> el: variables) { for(Map.Entry<String, ITypingEnvironmentVariableType> e : el.entrySet()){ if(!checkedVariables.contains(e.getKey())) { res = res + "\t" + e.getKey() + " := " + e.getValue().toString() + "\n"; checkedVariables.add(e.getKey()); } } } for(Map.Entry<String, MethodInterface> e : methods.entrySet()){ res = res + "\t" + e.getKey() + " := " + e.getValue().toString() + "\n"; } return res; } /* public DataTypeType getBoolType() { return types.get("Bool"); } public DataTypeType getIntType() { return types.get("Int"); } public DataTypeType getUnitType() { return types.get("Unit"); } public DataTypeType getStringType() { return types.get("String"); } */ } // end class Environment