package jqian.sootex.util.callgraph; import java.util.*; import soot.jimple.toolkits.callgraph.*; import soot.*; /** * Collect caller methods. support filters * */ public class Callers{ protected Set<MethodOrMethodContext> _all; public static interface Filter{ public boolean want(SootMethod m); } private static class NoFilter implements Filter{ public boolean want(SootMethod m){ return true; } } private static class SetFilter implements Filter{ public Set<MethodOrMethodContext> _set; public SetFilter(Set<MethodOrMethodContext> mask){ this._set = mask; } public boolean want(SootMethod m){ return _set.contains(m); } } private static class ReachableFilter implements Filter{ public ReachableMethods _rm; public ReachableFilter(ReachableMethods rm){ this._rm = rm; } public boolean want(SootMethod m){ return _rm.contains(m); } } private static NoFilter NOFILTER = new NoFilter(); public Callers(CallGraph cg,MethodOrMethodContext callee,Filter filter){ build(cg,callee,filter); } public Callers(CallGraph cg,MethodOrMethodContext callee){ build(cg,callee,NOFILTER); } //@param maskSet Only collect callers in this set public Callers(CallGraph cg,MethodOrMethodContext callee,Set<MethodOrMethodContext> maskSet){ Filter filter = new SetFilter(maskSet); build(cg,callee,filter); } public Callers(CallGraph cg,MethodOrMethodContext callee,ReachableMethods rm){ Filter filter = new ReachableFilter(rm); build(cg,callee,filter); } void build(CallGraph cg,MethodOrMethodContext callee,Filter filter){ _all = new HashSet<MethodOrMethodContext>(); Iterator<Edge> it = cg.edgesInto(callee); while(it.hasNext()){ Edge edge = it.next(); SootMethod src = edge.src(); if(filter.want(src)) _all.add(src); } } public Set<MethodOrMethodContext> all(){ return _all; } }