package costabs.structures; import java.util.ArrayList; import java.util.HashMap; import org.eclipse.core.resources.IFile; import costabs.markers.UBMarker; /** * This class is a wrapper to store the results that Costabs has calculated * in the session. * It adds results from XML, update line numbers and put markers. */ public class ResultTracker { /** * Storage for results. */ private HashMap<String, TrackerValue> results; /** * Create an empty result tracker. */ public ResultTracker() { results = new HashMap<String, TrackerValue>(); } /** * Get the number of results in the tracker. * @return The number of results in the tracker. */ public int size() { return results.size(); } /** * Add a result to the tracker. * @param callName The name of the method / function. * @param header The head of the method / function in the form: set(A) * @param ub The upperbound calculated for this method / function. * @param termin The termination calculated for this method / function. * @param line The line number in the source code corresponding to this method / function. */ public void addResult(String callName, String header, String ub, String termin, int line) { // If it's the first result with this call, create the container if (!results.containsKey(callName)) results.put(callName, new TrackerValue(callName, header, ub, termin, line)); else { TrackerValue r = results.get(callName); r.setCallName(callName); r.setUb(ub); r.setTermin(termin); r.setLine(line); } } /** * Remove a result from the tracker. * @param callName The name of the method / function to remove from the tracker. */ public void removeResult(String callName) { if (results.containsKey(callName)) results.remove(callName); } /** * Fill the tracker with the results stored in the xml generated by costabs. */ public void addXMLResults() { XMLParser parser = new XMLParser("//tmp//costabs//abs.xml"); ResultTracker r = parser.read(); for (TrackerValue p : r.results.values()) { if (!results.containsKey(p.getCallName())) results.put(p.getCallName(), p); else { TrackerValue ourR = results.get(p.getCallName()); if (!p.getHeader().equals("")) ourR.setHeader(p.getHeader()); if (p.hasUB()) ourR.setUb(p.getUb()); if (p.hasTermin()) ourR.setTermin(p.getTermin()); } } } /** * Insert the lines from source file corresponding to methods or functions * given in the array list names. * Note: The i element of array list lines is the line number of method / function * in array list names. * @param names The names of methods / functions wich number must be update. * @param lines The line numbers of the methods / functions. */ public void addLineNumbers(ArrayList<String> names, ArrayList<Integer> lines) { for (int i = 0; i < names.size(); i++) { if (!results.containsKey(names.get(i))) { TrackerValue p = new TrackerValue(names.get(i), "", "", "", lines.get(i)); results.put(names.get(i), p); } else { TrackerValue ourR = results.get(names.get(i)); ourR.setLine(lines.get(i)); } } } /** * Put the results stored in the tracker to markers in the IFile file. * @param file The source file in which to put the markers. */ public void fillMarkers(IFile file) { for (TrackerValue p : results.values()) { UBMarker ub = new UBMarker(); String message = ""; if (p.hasUB()) message = p.getHeader() + " = " + p.getUb(); if (p.hasTermin()) { if (p.hasUB()) message += "\n"; if (p.getTermin().equals("yes")) message += p.getCallName() + " is terminating."; else message += p.getCallName() + " might be non-terminating."; } ub.markLine(file, message , p.getLine()); } } }