/** * */ package soottocfg.soot.util; import java.util.HashSet; import java.util.Set; import soot.Body; import soot.Scene; import soot.SootClass; import soot.SootField; import soot.SootMethod; import soot.Unit; import soot.Value; import soot.jimple.Constant; import soot.jimple.DefinitionStmt; import soot.jimple.InstanceFieldRef; import soot.jimple.ParameterRef; /** * @author schaef * */ public class WriteOnceFieldCollector { static Set<SootField> getWriteOnceInstanceFields() { Set<SootField> writtenFields = new HashSet<SootField>(); Set<SootField> writtenTwiceFields = new HashSet<SootField>(); for (SootClass sc : Scene.v().getClasses()) { if (sc.resolvingLevel()<SootClass.BODIES) { continue; } for (SootMethod sm : sc.getMethods()) { try { Body body = sm.retrieveActiveBody(); for (Unit u : body.getUnits()) { if (u instanceof DefinitionStmt ) { Value lOp = ((DefinitionStmt)u).getLeftOp(); Value rOp = ((DefinitionStmt)u).getRightOp(); if (lOp instanceof InstanceFieldRef) { SootField f = ((InstanceFieldRef)lOp).getField(); boolean nonVariableAssign = f.isFinal() || (sm.isConstructor() && (rOp instanceof ParameterRef)) || (rOp instanceof Constant); if (writtenFields.contains(f) || !nonVariableAssign ) { writtenTwiceFields.add(f); } writtenFields.add(f); } } } } catch (Exception e) { //ignore continue; } } } writtenFields.removeAll(writtenTwiceFields); return writtenFields; } }