KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > de > uka > ipd > coverage > natures > all_uses > AllUsesCoverageNature


1 /*
2  * Created on Sep 14, 2004
3  * @author Matthias Kempka
4  */

5 package de.uka.ipd.coverage.natures.all_uses;
6
7 import java.util.*;
8
9 import org.apache.bcel.classfile.Code;
10 import org.apache.bcel.classfile.JavaClass;
11 import org.apache.bcel.generic.InstructionHandle;
12 import org.apache.bcel.generic.StoreInstruction;
13 import org.eclipse.jface.resource.ImageDescriptor;
14
15 import de.uka.ipd.coverage.natures.CompleteCoverage;
16 import de.uka.ipd.coverage.natures.CoverageNature;
17 import de.uka.ipd.coverage.natures.TestedClass;
18 import de.uka.ipd.coverage.plugin.CoveragePlugin;
19 import de.uka.ipd.coverage.plugin.ui.CoverageNatureDescriptor;
20 import de.uka.ipd.coverage.recording.CoverageState;
21 import de.uka.ipd.coverage.recording.Path;
22 import de.uka.ipd.coverage.recording.RegisteredMethod;
23
24 /**
25  * @author Matthias Kempka
26  *
27  */

28 public class AllUsesCoverageNature implements CoverageNature {
29
30     // contains SsaBasicBlockWrapper objects
31
private List ssaBlockList = new ArrayList();
32     
33     public static final CoverageNatureDescriptor DESCRIPTOR = new CoverageNatureDescriptor() {
34
35         public String JavaDoc getName() {
36             return Messages.getString("AllUsesCoverageNature.0"); //$NON-NLS-1$
37
}
38
39         public String JavaDoc getDescription() {
40             return Messages.getString("AllUsesCoverageNature.1"); //$NON-NLS-1$
41
}
42
43         public String JavaDoc getID() {
44             return "de.uka.ipd.coverage.natures.all_uses.AllUsesCoverageNature"; //$NON-NLS-1$
45
}
46
47         public ImageDescriptor getImageDescriptor() {
48             String JavaDoc iconPath = "icons/coverageNatures/"; //$NON-NLS-1$
49
String JavaDoc[] icons = new String JavaDoc[] {"all_uses_coverage_nature"}; //$NON-NLS-1$
50
return CoveragePlugin.getDefault().getImageDescriptors(
51                 icons, iconPath)[0];
52         }
53     };
54     
55     public TestedClass[] getMeasuredClasses() {
56 // System.out.print("getMeasuredClasses " );
57
List testedClasses = new ArrayList(); // contains TestedClass objects
58
for (Iterator iter = ssaBlockList.iterator(); iter.hasNext();) {
59             SsaBasicBlockWrapper ssaBlock = (SsaBasicBlockWrapper) iter.next();
60             JavaClass javaClass = ssaBlock.getRegisteredMethod().getJavaClass();
61             TestedClass tc = new TestedClass(javaClass,
62                     computeCoverageState(javaClass));
63             if (! testedClasses.contains(tc)) {
64                 testedClasses.add(tc);
65             }
66         }
67 // System.out.println(" ..there are " + testedClasses.size() + " classes!");
68
return (TestedClass[]) testedClasses.toArray(
69                 new TestedClass[testedClasses.size()]);
70     }
71
72     /**
73      * computes the coverage state of a given tested class in terms of
74      * the All Uses criteria.
75      * @param javaClass
76      */

77     private CoverageState computeCoverageState(JavaClass javaClass) {
78         DefinitionFreePath[] dfps = createDefinitionFreePaths(javaClass);
79         int covered = 0;
80         int unCovered = 0;
81         for (int i = 0; i < dfps.length; i++) {
82             UsesCoverage uses = dfps[i].getCoveredUsesSourcePositions();
83             covered += uses.getCoveredUsesSourceLineNumbers().length;
84             unCovered += uses.getUncoveredUsesSourceLineNumbers().length;
85             if (covered > 0 && unCovered > 0) {
86                 return CoverageState.PARTIAL_COVERAGE;
87             }
88         }
89         if (unCovered > 0) {
90             return CoverageState.NO_COVERAGE;
91         }
92         return CoverageState.FULL_COVERAGE;
93     }
94
95     /**
96      * @param javaClass
97      */

98     protected DefinitionFreePath[] createDefinitionFreePaths(JavaClass javaClass) {
99 // System.out.println("creating DefinitionFreePaths for " + javaClass.getClassName());
100
List dfps = new ArrayList(20);
101         SsaBasicBlockWrapper[] ssaBlocks = getBlocks(javaClass);
102         for (int i = 0; i < ssaBlocks.length; i++) {
103             createDefinitionFreePath(javaClass, dfps, ssaBlocks[i]);
104         }
105         removeDuplicates(dfps);
106         Collections.sort(dfps);
107         for (Iterator iter = dfps.iterator(); iter.hasNext();) {
108             DefinitionFreePath dfp = (DefinitionFreePath) iter.next();
109             dfp.triggerFinished();
110         }
111 // System.out.println(" Done creating DefinitionFreePaths for " + javaClass.getClassName() + ". " + dfps.size() + " Pfade.");
112
return (DefinitionFreePath[]) dfps.toArray(new DefinitionFreePath[dfps.size()]);
113 // System.out.println(definitionFreePaths);
114
}
115
116 // /*
117
// * method used for debug only
118
// */
119
// private int countDifferentClasses() {
120
// List differentClassesList = new ArrayList();
121
// for (Iterator iter = definitionFreePaths.iterator(); iter.hasNext();) {
122
// DefinitionFreePath dfp = (DefinitionFreePath) iter.next();
123
// JavaClass cjc = dfp.getCorrespondingMethod().getJavaClass();
124
// if (!differentClassesList.contains(cjc)) {
125
// differentClassesList.add(cjc);
126
// }
127
// }
128
// return differentClassesList.size();
129
// }
130

131     /**
132      * @param javaClass
133      * @param dfps
134      * @param ssaBlock
135      * @param i
136      */

137     private void createDefinitionFreePath(JavaClass javaClass, List dfps, SsaBasicBlockWrapper ssaBlock) {
138         List indices = getDefinedVariableSSAIndices(ssaBlock);
139         for (Iterator iter = indices.iterator(); iter.hasNext();) {
140             Integer JavaDoc key = (Integer JavaDoc) iter.next();
141             DefinitionFreePath path;
142             SsaBasicBlockWrapper[] succs;
143             createDefinitionFreePathForIndex(javaClass, dfps, ssaBlock, key);
144         }
145     }
146
147     /**
148      * @param javaClass
149      * @param dfps
150      * @param ssaBlock
151      * @param index
152      */

153     private void createDefinitionFreePathForIndex(JavaClass javaClass, List dfps, SsaBasicBlockWrapper ssaBlock, Integer JavaDoc index) {
154         DefinitionFreePath path = new DefinitionFreePath(index);
155         path.addBlock(ssaBlock);
156 // System.out.println("Now working with dfp: " + path);
157
// if (path.toString().equals("{DFP: <init>:recreationableString}[ (0,54) ]")) {
158
// try {
159
// PrintStream out = new PrintStream(new FileOutputStream("/tmp/CompoundUnit.bytecode"));
160
// new ByteCodePrinter(javaClass).printBytecode(out);
161
// } catch (FileNotFoundException e) {
162
// // TODO Auto-generated catch block
163
// e.printStackTrace();
164
// }
165
// ByteCodePrinter.printByteCode(System.out, "problem", ssaBlock.getWrappedBasicBlock().getRegisteredMethod().getMethod().getCode(), false, false);
166
// System.out.println("STOP");
167
// }
168
SsaBasicBlockWrapper[] succs = ssaBlock.getSuccessorWrappers();
169         if (succs.length == 0) {
170             path.removeUnnecessaryBlocks(index);
171             dfps.add(path);
172         } else {
173             for (int j = 0; j < succs.length; j++) {
174                 dfps.addAll(
175                         computeDefinitionFreePaths((DefinitionFreePath) path.clone(), succs[j], index));
176             }
177         }
178     }
179
180     /**
181      * removes duplicates from the definitionFreePaths list
182      */

183     private void removeDuplicates(List definitionFreePaths) {
184         // put all elements in a hashmap.
185
// then use the keyset as definitionFreePath list.
186
Map map = new HashMap();
187         for (Iterator iter = definitionFreePaths.iterator(); iter.hasNext();) {
188             Object JavaDoc element = iter.next();
189             map.put(element, element);
190         }
191         definitionFreePaths.clear();
192         for (Iterator iter = map.keySet().iterator(); iter.hasNext();) {
193             DefinitionFreePath element = (DefinitionFreePath) iter.next();
194             definitionFreePaths.add(element);
195         }
196     }
197
198     /**
199      * @param currentPath the path that is currently computed. collecting parameter.
200      * @param block, index
201      * @return returns a list containing Path objects.
202      * The Path objects are the definition free paths of the given index
203      */

204     private List computeDefinitionFreePaths(
205             DefinitionFreePath currentPath,
206             SsaBasicBlockWrapper block,
207             Integer JavaDoc index) {
208         assert currentPath != null : "currentPath must not be null"; //$NON-NLS-1$
209
List resultList = new ArrayList();
210         if (startsLoop(currentPath, block)) {
211             // ... and abort if there is one.
212
currentPath.removeUnnecessaryBlocks(index);
213             resultList.add(currentPath);
214             return resultList;
215         }
216         
217         currentPath.addBlock(block);
218         if (getDefinedVariableSSAIndices(block).contains(index)) {
219             // this block contains a store
220
currentPath.removeUnnecessaryBlocks(index);
221             resultList.add(currentPath);
222             return resultList;
223         }
224         
225         // add successors to the path where necessary.
226
SsaBasicBlockWrapper[] succs = block.getSuccessorWrappers();
227         for (int i = 0; i < succs.length; i++) {
228             resultList.addAll(computeDefinitionFreePaths(
229                     (DefinitionFreePath) currentPath.clone(),
230                     succs[i],
231                     index));
232         }
233         // if there are no successors, add the current Path
234
if (succs.length == 0) {
235             currentPath.removeUnnecessaryBlocks(index);
236             resultList.add(currentPath);
237         }
238         return resultList;
239     }
240
241
242
243     /**
244      * a block is said to start a loop if it takes the same branch twice
245      * from a block that has more than one predecessors (thus being a potential
246      * start for a loop).
247      * @return returns true if the block would start a loop.
248      */

249     private boolean startsLoop(DefinitionFreePath currentPath, SsaBasicBlockWrapper block) {
250         SsaBasicBlockWrapper[] pres = block.getPredecessorWrappers();
251         for (int i = 0; i < pres.length; i++) {
252             if (pres[i].getPredecessorWrappers().length > 1) {
253                 Path loopCheck = new Path();
254                 loopCheck.addEnteredBlock(pres[i]);
255                 loopCheck.addExitedBlock(pres[i]);
256                 loopCheck.addEnteredBlock(block);
257                 loopCheck.addExitedBlock(block);
258                 if (CoverageState.FULL_COVERAGE == currentPath.includes(loopCheck)) {
259                     return true;
260                 }
261             }
262         }
263         return false;
264     }
265
266     /**
267      * returns an array of variable indices that are defined in a given
268      * basic block. Those are the variables that are stored via a
269      * store instruction.
270      * @param wrapper
271      * @return returns a list containing Integer objects representing the
272      * SSA index of the instructions.
273      */

274     private List getDefinedVariableSSAIndices(SsaBasicBlockWrapper wrapper) {
275         InstructionHandle[] handles = wrapper.getInstructionHandles();
276         List indices = new ArrayList();
277         for (int i = 0; i < handles.length; i++) {
278             if (handles[i].getInstruction() instanceof StoreInstruction) {
279                 StoreInstruction store =
280                     (StoreInstruction) handles[i].getInstruction();
281                 List keys = wrapper.getKeys(new Integer JavaDoc(store.getIndex()));
282                 assert keys.size() < 2 : " Es gibt tatsaechlich mehr als 2 Eintraege fuer einen value"; //$NON-NLS-1$
283
indices.addAll(keys);
284             }
285         }
286         return indices;
287     }
288
289 // /**
290
// * returns an array of variable indices that are defined in a given
291
// * basic block. Those are the variables that are stored via a
292
// * store instruction.
293
// * @param wrapper
294
// * @return returns a list containing Integer objects representing the
295
// * original indices of the instructions.
296
// */
297
// private List getDefinedVariableOriginalIndices(SsaBasicBlockWrapper wrapper) {
298
// InstructionHandle[] handles = wrapper.getInstructionHandles();
299
// List indices = new ArrayList();
300
// for (int i = 0; i < handles.length; i++) {
301
// if (handles[i].getInstruction() instanceof StoreInstruction) {
302
// StoreInstruction store =
303
// (StoreInstruction) handles[i].getInstruction();
304
// indices.add(new Integer(store.getIndex()));
305
// }
306
// }
307
// return indices;
308
// }
309

310     
311     private SsaBasicBlockWrapper[] getBlocks(JavaClass javaClass) {
312         List result = new ArrayList();
313         for (Iterator iter = ssaBlockList.iterator(); iter.hasNext();) {
314             SsaBasicBlockWrapper block = (SsaBasicBlockWrapper) iter.next();
315             if (javaClass == block.getRegisteredMethod().getJavaClass()) {
316                 result.add(block);
317             }
318         }
319         return (SsaBasicBlockWrapper[]) result.toArray(
320                 new SsaBasicBlockWrapper[result.size()]);
321     }
322
323     public CompleteCoverage getCompleteCoverage(JavaClass className) {
324         AllUsesCompleteCoverage result = new AllUsesCompleteCoverage(className);
325         DefinitionFreePath[] paths = createDefinitionFreePaths(className);
326         DefinitionUsesMap dum = new DefinitionUsesMap();
327         for (int i = 0; i < paths.length; i++) {
328             dum.addUses(paths[i].getDefinition(),
329                 paths[i].getCoveredUsesSourcePositions());
330         }
331         for (int i = 0; i < paths.length; i++) {
332             RegisteredMethod rm = paths[i].getRegisteredMethod();
333             if (rm != null) {
334                 CoverageState state;
335                 Definition def = paths[i].getDefinition();
336                 UsesCoverage usesCoverage = dum.getUses(def);
337                 if (usesCoverage.getUncoveredUsesSourceLineNumbers().length == 0) {
338                     state = CoverageState.FULL_COVERAGE;
339                 } else if (usesCoverage.getCoveredUsesSourceLineNumbers().length == 0 ) {
340                     state = CoverageState.NO_COVERAGE;
341                 } else {
342                     state = CoverageState.PARTIAL_COVERAGE;
343                 }
344                 result.addLine(def, state, Messages.getString("AllUsesCoverageNature.8") + def.getVariableName(), usesCoverage); //$NON-NLS-1$
345
}
346         }
347         return result;
348     }
349
350 // private DefinitionFreePath[] getDefinitionFreePaths(JavaClass className) {
351
// List result = new ArrayList();
352
// for (Iterator iter = definitionFreePaths.iterator(); iter.hasNext();) {
353
// DefinitionFreePath dfp = (DefinitionFreePath) iter.next();
354
// if (dfp.getRegisteredMethod().getJavaClass().equals(className)) {
355
// result.add(dfp);
356
// }
357
// }
358
// return (DefinitionFreePath[]) result.toArray(new DefinitionFreePath[result.size()]);
359
// }
360

361     public void visitCode(RegisteredMethod callback, Code code) {
362 // new ByteCodePrinter(callback.getJavaClass()).printBytecode(System.out, callback.getMethod(), true);
363
SSABasicBlockBuilder.buildSSABasicBlockWrappers(callback);
364         SSABasicBlockBuilder.generateSSAForm();
365         SsaBasicBlockWrapper[] blocks =
366             SSABasicBlockBuilder.getSSABasicBlockWrappers();
367         ssaBlockList.addAll(Arrays.asList(blocks));
368     }
369
370     public CoverageNatureDescriptor getCoverageNatureDescriptor() {
371         return DESCRIPTOR;
372     }
373
374     public void clear() {
375 // if (definitionFreePaths != null) {
376
// definitionFreePaths.clear();
377
// }
378
if (ssaBlockList != null) {
379             ssaBlockList.clear();
380         }
381     }
382
383 }
384
Popular Tags