import java.io.*;
public class CallGraph {
- private State state;
+ protected State state;
// MethodDescriptor maps to HashSet<MethodDescriptor>
- private Hashtable mapVirtual2ImplementationSet;
+ protected Hashtable mapVirtual2ImplementationSet;
// MethodDescriptor or TaskDescriptor maps to HashSet<MethodDescriptor>
- private Hashtable mapCaller2CalleeSet;
+ protected Hashtable mapCaller2CalleeSet;
// MethodDescriptor maps to HashSet<MethodDescriptor or TaskDescriptor>
- private Hashtable mapCallee2CallerSet;
+ protected Hashtable mapCallee2CallerSet;
+
+ protected CallGraph() {}
public CallGraph(State state) {
this.state=state;
// (MethodDescriptors and/or TaskDescriptors)
// that call the given method
public Set getCallerSet(MethodDescriptor md) {
- return (Set) mapCallee2CallerSet.get(md);
+ Set s = (Set) mapCallee2CallerSet.get(md);
+
+ if( s == null ) {
+ return new HashSet();
+ }
+ return s;
}
// this method returns the set of MethodDescriptors that
assert(d instanceof MethodDescriptor) ||
(d instanceof TaskDescriptor);
- return (Set) mapCaller2CalleeSet.get(d);
+ Set s = (Set) mapCaller2CalleeSet.get(d);
+
+ if( s == null ) {
+ return new HashSet();
+ }
+ return s;
}
// build a mapping of virtual methods to all
// possible implementations of that method
- private void buildVirtualMap() {
+ protected void buildVirtualMap() {
//Iterator through classes
Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
while(it.hasNext()) {
HashSet ns=new HashSet();
ns.add(d);
+ return getMoreMethodCalls(ns, d);
+ }
+
+ private Set getMoreMethodCalls(HashSet found, Descriptor d) {
+ HashSet ns=new HashSet();
+ ns.add(d);
+ found.add(d);
Set s=(Set)mapCaller2CalleeSet.get(d);
if (s!=null)
for(Iterator it=s.iterator(); it.hasNext();) {
MethodDescriptor md=(MethodDescriptor)it.next();
- ns.addAll(getMethodCalls(md));
+ if( !found.contains(md) ) {
+ ns.addAll(getMoreMethodCalls(found, md));
+ }
}
return ns;
}
+ /** Returns all methods transitively callable from d */
+
+ public Set getAllMethods(Descriptor d) {
+ HashSet tovisit=new HashSet();
+ tovisit.add(d);
+ HashSet callable=new HashSet();
+ while(!tovisit.isEmpty()) {
+ Descriptor md=(Descriptor)tovisit.iterator().next();
+ tovisit.remove(md);
+ Set s=(Set)mapCaller2CalleeSet.get(md);
+ if (s!=null) {
+ for(Iterator it=s.iterator(); it.hasNext();) {
+ MethodDescriptor md2=(MethodDescriptor)it.next();
+ if( !callable.contains(md2) ) {
+ callable.add(md2);
+ tovisit.add(md2);
+ }
+ }
+ }
+ }
+ return callable;
+ }
+
private void buildGraph() {
Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
while(it.hasNext()) {
}
}
- private void analyzeMethod(Object caller, FlatMethod fm) {
+ protected void analyzeMethod(Object caller, FlatMethod fm) {
HashSet toexplore=new HashSet();
toexplore.add(fm);
HashSet explored=new HashSet();