1 19 20 package edu.umd.cs.findbugs; 21 22 import java.util.Iterator ; 23 24 import org.apache.bcel.classfile.JavaClass; 25 import org.apache.bcel.classfile.Method; 26 import org.apache.bcel.generic.ConstantPoolGen; 27 import org.apache.bcel.generic.MethodGen; 28 29 import edu.umd.cs.findbugs.ba.CFG; 30 import edu.umd.cs.findbugs.ba.CFGBuilderException; 31 import edu.umd.cs.findbugs.ba.ClassContext; 32 import edu.umd.cs.findbugs.ba.Dataflow; 33 import edu.umd.cs.findbugs.ba.DataflowAnalysisException; 34 import edu.umd.cs.findbugs.ba.DepthFirstSearch; 35 import edu.umd.cs.findbugs.ba.Location; 36 import edu.umd.cs.findbugs.ba.ResourceTracker; 37 import edu.umd.cs.findbugs.ba.ResourceValueAnalysis; 38 import edu.umd.cs.findbugs.ba.ResourceValueFrame; 39 import edu.umd.cs.findbugs.ba.SignatureConverter; 40 41 50 public abstract class ResourceTrackingDetector <Resource, ResourceTrackerType extends ResourceTracker<Resource>> 51 implements Detector { 52 53 private static final boolean DEBUG = SystemProperties.getBoolean("rtd.debug"); 54 55 private static final String DEBUG_METHOD_NAME = SystemProperties.getProperty("rtd.method"); 56 57 protected BugReporter bugReporter; 58 59 public ResourceTrackingDetector(BugReporter bugReporter) { 60 this.bugReporter = bugReporter; 61 } 62 63 public abstract boolean prescreen(ClassContext classContext, Method method); 64 65 public abstract ResourceTrackerType getResourceTracker(ClassContext classContext, Method method) 66 throws DataflowAnalysisException, CFGBuilderException; 67 68 public abstract void inspectResult(ClassContext classContext, MethodGen methodGen, CFG cfg, 69 Dataflow<ResourceValueFrame, ResourceValueAnalysis<Resource>> dataflow, Resource resource); 70 71 public void visitClassContext(ClassContext classContext) { 72 73 final JavaClass jclass = classContext.getJavaClass(); 74 Method[] methodList = jclass.getMethods(); 75 for (Method method : methodList) { 76 if (method.isAbstract() || method.isNative()) 77 continue; 78 79 MethodGen methodGen = classContext.getMethodGen(method); 80 if (methodGen == null) 81 continue; 82 83 if (DEBUG_METHOD_NAME != null && !DEBUG_METHOD_NAME.equals(method.getName())) 84 continue; 85 86 if (!prescreen(classContext, method)) 87 continue; 88 89 if (DEBUG) { 90 System.out.println("----------------------------------------------------------------------"); 91 System.out.println("Analyzing " + SignatureConverter.convertMethodSignature(methodGen)); 92 System.out.println("----------------------------------------------------------------------"); 93 } 94 95 try { 96 ResourceTrackerType resourceTracker = getResourceTracker(classContext, method); 97 98 ResourceCollection<Resource> resourceCollection = 99 buildResourceCollection(classContext, method, resourceTracker); 100 if (resourceCollection.isEmpty()) 101 continue; 102 103 analyzeMethod(classContext, method, resourceTracker, resourceCollection); 104 } catch (CFGBuilderException e) { 105 bugReporter.logError("Error analyzing method " + method.toString(), e); 106 } catch (DataflowAnalysisException e) { 107 bugReporter.logError("Error analyzing method " + method.toString(), e); 108 } 109 } 110 111 } 112 113 private ResourceCollection<Resource> buildResourceCollection(ClassContext classContext, 114 Method method, ResourceTrackerType resourceTracker) 115 throws CFGBuilderException, DataflowAnalysisException { 116 117 ResourceCollection<Resource> resourceCollection = new ResourceCollection<Resource>(); 118 119 CFG cfg = classContext.getCFG(method); 120 ConstantPoolGen cpg = classContext.getConstantPoolGen(); 121 122 for (Iterator <Location> i = cfg.locationIterator(); i.hasNext();) { 123 Location location = i.next(); 124 Resource resource = resourceTracker.isResourceCreation(location.getBasicBlock(), 125 location.getHandle(), cpg); 126 if (resource != null) 127 resourceCollection.addCreatedResource(location, resource); 128 } 129 130 return resourceCollection; 131 } 132 133 public void analyzeMethod(ClassContext classContext, Method method, 134 ResourceTrackerType resourceTracker, ResourceCollection<Resource> resourceCollection) 135 throws CFGBuilderException, DataflowAnalysisException { 136 137 MethodGen methodGen = classContext.getMethodGen(method); 138 if (methodGen == null) return; 139 CFG cfg = classContext.getCFG(method); 140 DepthFirstSearch dfs = classContext.getDepthFirstSearch(method); 141 142 if (DEBUG) System.out.println(SignatureConverter.convertMethodSignature(methodGen)); 143 144 for (Iterator <Resource> i = resourceCollection.resourceIterator(); i.hasNext();) { 145 Resource resource = i.next(); 146 147 ResourceValueAnalysis<Resource> analysis = 148 new ResourceValueAnalysis<Resource>(methodGen, cfg, dfs, resourceTracker, resource); 149 Dataflow<ResourceValueFrame, ResourceValueAnalysis<Resource>> dataflow = 150 new Dataflow<ResourceValueFrame, ResourceValueAnalysis<Resource>>(cfg, analysis); 151 152 dataflow.execute(); 153 inspectResult(classContext, methodGen, cfg, dataflow, resource); 154 } 155 } 156 157 public void report() { 158 } 159 160 } 161 162 | Popular Tags |