package jqian.sootex.util;
import jqian.sootex.util.graph.GraphHelper;
import jqian.sootex.util.graph.GraphHelper.LabelProvider;
import jqian.util.graph.Graph;
import jqian.util.graph.GraphEdge;
import jqian.util.graph.GraphNode;
import java.util.*;
import soot.*;
import soot.toolkits.graph.*;
import soot.util.*;
public class CFGViewer {
protected DirectedGraph<Unit> _graph;
protected SootMethod _method;
public CFGViewer(SootMethod m,DirectedGraph<Unit> graph){
this._graph = graph;
this._method = m;
}
public Graph makeJimpleCFG(){
LabelProvider labelProvider = new LabelProvider(){
int index = 0;
public String getLabel(Object o){
Unit n = (Unit) o;
index ++;
return "n"+index+": "+SootUtils.getStmtString(n);
}
};
Graph cfg = GraphHelper.toDisplayGraph(_graph, "Jimple CFG", labelProvider);
return cfg;
}
public Graph makeJavaCFG(){
Graph cfg = new Graph("Java CFG");
Body body = _method.getActiveBody();
Chain<Unit> ch = body.getUnits();
Set<Integer> lineNumbers= new HashSet<Integer>();
for(Unit n: ch){
int line = SootUtils.getLine(n);
lineNumbers.add(new Integer(line));
}
Map<Integer,GraphNode> line2Node = new HashMap<Integer,GraphNode>(lineNumbers.size()*2+1,0.7f);
for(Integer line: lineNumbers){
GraphNode node = new GraphNode(line.toString());
line2Node.put(line,node);
}
for(Iterator<Unit> it = _graph.iterator();it.hasNext();) {
Unit from = (Unit) it.next();
List<Unit> lst = _graph.getSuccsOf(from);
for(Unit to: lst){
int fromLine=SootUtils.getLine(from);
int toLine=SootUtils.getLine(to);
if(fromLine==toLine){
//drop reflexive edges
}
else{
GraphNode fromNode=(GraphNode)line2Node.get(fromLine);
GraphNode toNode=(GraphNode)line2Node.get(toLine);
cfg.addEdge(new GraphEdge(fromNode,toNode));
}
}
}
return cfg;
}
}