package dk.brics.xact.analysis.soot;
import java.util.HashMap;
import java.util.Map;
import soot.Local;
import soot.Unit;
import soot.jimple.DefinitionStmt;
import soot.jimple.StringConstant;
import soot.toolkits.graph.DirectedGraph;
import soot.toolkits.scalar.ForwardFlowAnalysis;
/**
* Determines for each program point the locals with a constant string value and their
* corresponding string constants.
*/
public class StringConstantAnalysis extends ForwardFlowAnalysis<Unit,Map<Local,StringConstant>> {
public StringConstantAnalysis(DirectedGraph<Unit> graph) {
super(graph);
doAnalysis();
}
@Override
protected void flowThrough(Map<Local, StringConstant> in, Unit d, Map<Local, StringConstant> out) {
out.putAll(in);
if (d instanceof DefinitionStmt) {
DefinitionStmt def = (DefinitionStmt)d;
if (def.getLeftOp() instanceof Local) {
if (def.getRightOp() instanceof StringConstant) {
out.put((Local)def.getLeftOp(), (StringConstant)def.getRightOp());
} else {
out.remove(def.getLeftOp());
}
}
}
}
@Override
protected void copy(Map<Local, StringConstant> source, Map<Local, StringConstant> dest) {
dest.clear();
dest.putAll(source);
}
@Override
protected Map<Local, StringConstant> entryInitialFlow() {
return new HashMap<Local,StringConstant>();
}
@Override
protected void merge(Map<Local, StringConstant> in1, Map<Local, StringConstant> in2, Map<Local, StringConstant> out) {
out.putAll(in1);
for (Map.Entry<Local,StringConstant> entry : in2.entrySet()) {
StringConstant s1 = out.get(entry.getKey());
StringConstant s2 = in2.get(entry.getKey());
if (s1 != s2)
out.remove(entry.getKey());
}
}
@Override
protected Map<Local, StringConstant> newInitialFlow() {
return new HashMap<Local,StringConstant>();
}
}