1
2
3
4
5
6
7 package joeq.Compiler.Quad;
8
9 import java.util.Collection;
10 import java.util.Iterator;
11 import java.util.LinkedList;
12 import joeq.Class.jq_Method;
13 import joeq.Compiler.Analysis.IPA.ProgramLocation;
14 import jwutil.util.Assert;
15
16 /***
17 *
18 * @author Chris Unkel <cunkel@stanford.edu>
19 * @version $Id: FilteredCallGraph.java 2482 2007-10-30 05:17:36Z cunkel $
20 *
21 * Filtered call graph. Useful for excluding joeq, jwutil, etc. from a call graph
22 * when performing analysis in hosted VM mode.
23 */
24 public class FilteredCallGraph extends CallGraph {
25 private final CallGraph base;
26 private final Filter filter;
27
28 public FilteredCallGraph(CallGraph base, Filter filter) {
29 this.base = base;
30 this.filter = filter;
31 }
32
33 public Collection getRoots() {
34 return base.getRoots();
35 }
36
37 public void setRoots(Collection roots) {
38 base.setRoots(roots);
39 }
40
41 public Collection getTargetMethods(Object context, ProgramLocation callSite) {
42 Collection targetMethods = base.getTargetMethods(context, callSite);
43 LinkedList filteredTargetMethods = new LinkedList();
44 for (Iterator i = targetMethods.iterator(); i.hasNext();) {
45 Object target = i.next();
46 if (filter.acceptTargetMethod(context, callSite, target)) {
47 filteredTargetMethods.add(target);
48 }
49 }
50 return filteredTargetMethods;
51 }
52
53 public static interface Filter {
54 public abstract boolean acceptTargetMethod(Object context, ProgramLocation callSite, Object targetMethod);
55 }
56
57 public static class PackageFilter implements Filter {
58 Collection excludedPackages = new LinkedList();
59
60 public PackageFilter() {
61 }
62
63 public void excludePackage(String packageName) {
64 if (!packageName.endsWith(".")) {
65 packageName = packageName + ".";
66 }
67 excludedPackages.add(packageName);
68 }
69
70 public boolean acceptTargetMethod(Object context, ProgramLocation callSite, Object targetMethod) {
71 jq_Method callee = (jq_Method) targetMethod;
72 jq_Method caller = callSite.getMethod();
73
74 String calleeName = callee.getDeclaringClass().getName().toString();
75 String callerName = caller.getDeclaringClass().getName().toString();
76
77 for (Iterator i = excludedPackages.iterator(); i.hasNext(); ) {
78 String packageName = (String) i.next();
79 if (calleeName.startsWith(packageName)) {
80 return false;
81 }
82 if (callerName.startsWith(packageName)) {
83 return false;
84 }
85 }
86
87 return true;
88 }
89 }
90 }