1 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 28 public class AllUsesCoverageNature implements CoverageNature { 29 30 private List ssaBlockList = new ArrayList(); 32 33 public static final CoverageNatureDescriptor DESCRIPTOR = new CoverageNatureDescriptor() { 34 35 public String getName() { 36 return Messages.getString("AllUsesCoverageNature.0"); } 38 39 public String getDescription() { 40 return Messages.getString("AllUsesCoverageNature.1"); } 42 43 public String getID() { 44 return "de.uka.ipd.coverage.natures.all_uses.AllUsesCoverageNature"; } 46 47 public ImageDescriptor getImageDescriptor() { 48 String iconPath = "icons/coverageNatures/"; String [] icons = new String [] {"all_uses_coverage_nature"}; return CoveragePlugin.getDefault().getImageDescriptors( 51 icons, iconPath)[0]; 52 } 53 }; 54 55 public TestedClass[] getMeasuredClasses() { 56 List testedClasses = new ArrayList(); 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 return (TestedClass[]) testedClasses.toArray( 69 new TestedClass[testedClasses.size()]); 70 } 71 72 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 98 protected DefinitionFreePath[] createDefinitionFreePaths(JavaClass javaClass) { 99 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 return (DefinitionFreePath[]) dfps.toArray(new DefinitionFreePath[dfps.size()]); 113 } 115 116 131 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 key = (Integer ) iter.next(); 141 DefinitionFreePath path; 142 SsaBasicBlockWrapper[] succs; 143 createDefinitionFreePathForIndex(javaClass, dfps, ssaBlock, key); 144 } 145 } 146 147 153 private void createDefinitionFreePathForIndex(JavaClass javaClass, List dfps, SsaBasicBlockWrapper ssaBlock, Integer index) { 154 DefinitionFreePath path = new DefinitionFreePath(index); 155 path.addBlock(ssaBlock); 156 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 183 private void removeDuplicates(List definitionFreePaths) { 184 Map map = new HashMap(); 187 for (Iterator iter = definitionFreePaths.iterator(); iter.hasNext();) { 188 Object 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 204 private List computeDefinitionFreePaths( 205 DefinitionFreePath currentPath, 206 SsaBasicBlockWrapper block, 207 Integer index) { 208 assert currentPath != null : "currentPath must not be null"; List resultList = new ArrayList(); 210 if (startsLoop(currentPath, block)) { 211 currentPath.removeUnnecessaryBlocks(index); 213 resultList.add(currentPath); 214 return resultList; 215 } 216 217 currentPath.addBlock(block); 218 if (getDefinedVariableSSAIndices(block).contains(index)) { 219 currentPath.removeUnnecessaryBlocks(index); 221 resultList.add(currentPath); 222 return resultList; 223 } 224 225 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 (succs.length == 0) { 235 currentPath.removeUnnecessaryBlocks(index); 236 resultList.add(currentPath); 237 } 238 return resultList; 239 } 240 241 242 243 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 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 (store.getIndex())); 282 assert keys.size() < 2 : " Es gibt tatsaechlich mehr als 2 Eintraege fuer einen value"; indices.addAll(keys); 284 } 285 } 286 return indices; 287 } 288 289 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); } 346 } 347 return result; 348 } 349 350 361 public void visitCode(RegisteredMethod callback, Code code) { 362 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 (ssaBlockList != null) { 379 ssaBlockList.clear(); 380 } 381 } 382 383 } 384 | Popular Tags |