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());
}
}
}