this.catchers.clear();
this.currentHotspots = new LinkedList<HotspotInfo>();
findSourceFile();
Method method = jt.getMethod(sootMethod);
Body body = sootMethod.retrieveActiveBody();
// use an exceptional unit graph for the nullness analysis
ExceptionalUnitGraph exceptionalFlow = new ExceptionalUnitGraph(body);
nullAnalysis = new NullnessAnalysis(exceptionalFlow);
// prepare the reaching definitions analysis for the assertion creator
LiveLocals liveness = new SimpleLiveLocals(exceptionalFlow);
LocalDefs definitions = new SmartLocalDefs(exceptionalFlow, liveness);
// translate each statement in isolation
for (Unit unit : body.getUnits()) {
Stmt stmt = (Stmt) unit;
translateStmt(stmt);
}
// create intermediate Catch statements for every catch block
for (Trap trap : body.getTraps()) {
Catch ct = new Catch();
method.addStatement(ct);
// remember the Catch statement associated with the trap
catchers.put(trap, ct);
// add the catch block as successor
ct.addSucc(translations.get(trap.getHandlerUnit()).getFirst());
}
// connect according to normal flow
AssertionContext assertionContext = new AssertionContext(jt, definitions, translations, sootMethod);
BriefUnitGraph normalFlow = new BriefUnitGraph(body);
for (Unit stmt : body.getUnits()) {
Statement tail = translations.get(stmt).getLast();
if (stmt instanceof IfStmt) {
// branching statement: link assertion in-between its successors
IfStmt ifstmt = (IfStmt)stmt;
Stmt trueSuccessor = ifstmt.getTarget();
Stmt falseSuccessor = (Stmt)body.getUnits().getSuccOf(ifstmt);
AssertionBranches assertions = assertionCreator.createAssertions(ifstmt, assertionContext);
tail.addSucc(assertions.getWhenFalse().getFirst());
tail.addSucc(assertions.getWhenTrue().getFirst());
assertions.getWhenFalse().getLast().addSucc(translations.get(falseSuccessor).getFirst());
assertions.getWhenTrue().getLast().addSucc(translations.get(trueSuccessor).getFirst());
}
else if (stmt instanceof LookupSwitchStmt) {
LookupSwitchStmt sw = (LookupSwitchStmt)stmt;
// add cases
List<Integer> values = new ArrayList<Integer>();
for (int i=0; i<sw.getTargetCount(); i++) {
Stmt succ = (Stmt)sw.getTarget(i);
AssertionBranch assertion = assertionCreator.createSwitchAssertions(sw.getKeyBox(), sw.getLookupValue(i), sw, assertionContext);
tail.addSucc(assertion.getFirst());
assertion.getLast().addSucc(translations.get(succ).getFirst());
values.add(sw.getLookupValue(i));
}
// add default case
AssertionBranch assertion = assertionCreator.createSwitchDefaultAssertions(sw.getKeyBox(), values, sw, assertionContext);
tail.addSucc(assertion.getFirst());
assertion.getLast().addSucc(translations.get(sw.getDefaultTarget()).getFirst());
}
else {
// normal statement
for (Unit succ : normalFlow.getSuccsOf(stmt)) {
tail.addSucc(translations.get(succ).getFirst());
}
}
}
// connect first statements to the head
for (Unit stmt : normalFlow.getHeads()) {
method.getEntry().addSucc(translations.get(stmt).getFirst());
}
// connect according to exceptional flow
List<Catch> activeCatchers = new LinkedList<Catch>();
for (Unit stmt : body.getUnits()) {
// open and close catchers
for (Trap trap : body.getTraps()) {
if (trap.getBeginUnit() == stmt) {
activeCatchers.add(catchers.get(trap));
}
if (trap.getEndUnit() == stmt) {
activeCatchers.remove(catchers.get(trap));