KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > umd > cs > findbugs > ba > DataflowTestDriver


1 /*
2  * Bytecode Analysis Framework
3  * Copyright (C) 2003,2004 University of Maryland
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */

19
20 package edu.umd.cs.findbugs.ba;
21
22 import java.io.IOException JavaDoc;
23
24 import org.apache.bcel.classfile.JavaClass;
25 import org.apache.bcel.classfile.Method;
26 import org.apache.bcel.generic.MethodGen;
27
28 import edu.umd.cs.findbugs.FindBugsAnalysisFeatures;
29 import edu.umd.cs.findbugs.SystemProperties;
30
31 /**
32  * A test driver for dataflow analysis classes.
33  * It runs the dataflow analysis on the methods of a single class,
34  * and has options (properties) to restrict the analysis to a single
35  * method, and to print out a CFG annotated with dataflow values.
36  *
37  * @author David Hovemeyer
38  * @see Dataflow
39  * @see DataflowAnalysis
40  */

41 public abstract class DataflowTestDriver <Fact, AnalysisType extends BasicAbstractDataflowAnalysis<Fact>> {
42     private boolean overrideIsForwards;
43     
44     public void overrideIsForwards() {
45         this.overrideIsForwards = true;
46     }
47
48     /**
49      * Execute the analysis on a single class.
50      *
51      * @param filename the name of the class file
52      */

53     public void execute(String JavaDoc filename) throws DataflowAnalysisException, CFGBuilderException, IOException JavaDoc {
54         JavaClass jclass = new RepositoryClassParser(filename).parse();
55
56         final RepositoryLookupFailureCallback lookupFailureCallback = new DebugRepositoryLookupFailureCallback();
57
58         AnalysisContext analysisContext = AnalysisContext.create(lookupFailureCallback);
59         analysisContext.setBoolProperty(AnalysisFeatures.ACCURATE_EXCEPTIONS, true);
60         
61         configureAnalysisContext(analysisContext);
62
63         ClassContext classContext = analysisContext.getClassContext(jclass);
64         String JavaDoc methodName = SystemProperties.getProperty("dataflow.method");
65
66         Method[] methods = jclass.getMethods();
67         for (Method method : methods) {
68             if (methodName != null && !method.getName().equals(methodName))
69                 continue;
70
71             MethodGen methodGen = classContext.getMethodGen(method);
72             if (methodGen == null)
73                 continue;
74
75             System.out.println("-----------------------------------------------------------------");
76             System.out.println("Method: " + SignatureConverter.convertMethodSignature(methodGen));
77             System.out.println("-----------------------------------------------------------------");
78
79             execute(classContext, method);
80         }
81     }
82     
83     static class Knob {
84         String JavaDoc systemPropertyName;
85         int analysisProperty;
86         
87         Knob(String JavaDoc systemPropertyName, int analysisProperty) {
88             this.systemPropertyName = systemPropertyName;
89             this.analysisProperty = analysisProperty;
90         }
91     }
92     
93     private static final Knob[] KNOB_LIST = {
94         new Knob("ta.instanceof", AnalysisFeatures.MODEL_INSTANCEOF),
95         new Knob("inva.trackvalues", AnalysisFeatures.TRACK_VALUE_NUMBERS_IN_NULL_POINTER_ANALYSIS),
96         new Knob("fnd.derefs", AnalysisFeatures.TRACK_GUARANTEED_VALUE_DEREFS_IN_NULL_POINTER_ANALYSIS),
97     };
98
99     /**
100      * Configure the analysis context.
101      *
102      * @param analysisContext
103      */

104     private void configureAnalysisContext(AnalysisContext analysisContext) {
105         boolean max = SystemProperties.getBoolean("dataflow.max");
106
107         for (Knob knob : KNOB_LIST) {
108             boolean enable = max || SystemProperties.getBoolean(knob.systemPropertyName);
109             System.out.println("Setting " + knob.systemPropertyName + "=" + enable);
110             analysisContext.setBoolProperty(knob.analysisProperty, enable);
111         }
112     }
113
114     /**
115      * Execute the analysis on a single method of a class.
116      */

117     public void execute(ClassContext classContext, Method method) throws DataflowAnalysisException, CFGBuilderException {
118
119         Dataflow<Fact, AnalysisType> dataflow = createDataflow(classContext, method);
120         System.out.println("Finished in " + dataflow.getNumIterations() + " iterations");
121
122         CFG cfg = classContext.getCFG(method);
123         examineResults(cfg, dataflow);
124
125         if (SystemProperties.getBoolean("dataflow.printcfg")) {
126             CFGPrinter p = new DataflowCFGPrinter<Fact, AnalysisType>(dataflow);
127             if (overrideIsForwards) {
128                 p.setIsForwards(!p.isForwards());
129             }
130             p.print(System.out);
131         }
132     }
133
134     /**
135      * Downcall method to create the dataflow driver object
136      * and execute the analysis.
137      *
138      * @param classContext ClassContext for the class
139      * @param method the Method
140      * @return the Dataflow driver
141      */

142     public abstract Dataflow<Fact, AnalysisType> createDataflow(ClassContext classContext, Method method)
143             throws CFGBuilderException, DataflowAnalysisException;
144
145     /**
146      * Downcall method to inspect the analysis results.
147      * Need not be implemented by subclasses.
148      *
149      * @param cfg the control flow graph
150      * @param dataflow the analysis results
151      */

152     public void examineResults(CFG cfg, Dataflow<Fact, AnalysisType> dataflow) {
153     }
154 }
155
156 // vim:ts=4
157
Popular Tags