1 4 package de.uka.ipd.coverage.recording; 5 6 import java.io.Serializable ; 7 import java.util.*; 8 9 21 22 public class Path implements Cloneable , Serializable , Comparable { 23 24 protected LinkedList enteredBlocks = new LinkedList(); 26 private RuntimeBasicBlockWrapper currentBlock = null; 27 28 public Path() {} 29 30 41 public CoverageState includes(Path path) { 42 if (path == null) { 43 throw new IllegalArgumentException ("Path must be non-null for " + "a coverage decision"); } 46 if (path.enteredBlocks.isEmpty()) { 47 return CoverageState.FULL_COVERAGE; 49 } else if (this.enteredBlocks.isEmpty()) { 50 return CoverageState.NO_COVERAGE; 51 } 52 RuntimeBasicBlockWrapper pathFirstElement = 53 (RuntimeBasicBlockWrapper) path.enteredBlocks.get(0); 54 55 62 for (ListIterator iter = (ListIterator)enteredBlocks.iterator(); iter.hasNext();) { 63 RuntimeBasicBlockWrapper element = (RuntimeBasicBlockWrapper) iter.next(); 64 CoverageState firstPathElementCoverage 65 = element.covers(pathFirstElement); 66 67 if (CoverageState.FULL_COVERAGE == firstPathElementCoverage) { 68 int elementIndex = iter.nextIndex() - 1; 70 List sublist = enteredBlocks.subList(elementIndex, enteredBlocks.size()); 71 return getCoverage(sublist, path.enteredBlocks); 72 } else if (CoverageState.PARTIAL_COVERAGE == firstPathElementCoverage) { 73 return CoverageState.PARTIAL_COVERAGE; 75 } 76 } 77 return CoverageState.NO_COVERAGE; 78 } 79 80 90 private CoverageState getCoverage(List sublist, List path) { 91 Iterator compIter = sublist.iterator(); 92 Iterator pathIter = path.iterator(); 93 RuntimeBasicBlockWrapper compElement = (RuntimeBasicBlockWrapper) compIter.next(); 94 RuntimeBasicBlockWrapper pathElement = (RuntimeBasicBlockWrapper) pathIter.next(); 95 while(CoverageState.FULL_COVERAGE == compElement.covers(pathElement)) { 96 if (!pathIter.hasNext()) { 97 return CoverageState.FULL_COVERAGE; 99 } else if (!compIter.hasNext()) { return CoverageState.PARTIAL_COVERAGE; 104 } 105 compElement = (RuntimeBasicBlockWrapper) compIter.next(); 106 pathElement = (RuntimeBasicBlockWrapper) pathIter.next(); 107 } 108 return CoverageState.PARTIAL_COVERAGE; 111 } 112 113 public void addEnteredBlock(IBasicBlock block) { 114 currentBlock = new RuntimeBasicBlockWrapper(block); 115 currentBlock.triggerEntered(); 116 this.enteredBlocks.add(currentBlock); 117 } 118 119 public void addExitedBlock(IBasicBlock block) { 120 assert currentBlock != null 121 && currentBlock.isEntered() 122 && !currentBlock.isExited() : 123 "currentBlock not entered but exited!"; currentBlock.triggerExited(); 125 currentBlock = null; 126 } 127 128 133 public String toString() { 134 String result = "[ "; boolean afterfirstIteration = false; 136 for (Iterator iter = enteredBlocks.iterator(); iter.hasNext();) { 137 if (afterfirstIteration) { 138 result += ", "; } 140 RuntimeBasicBlockWrapper element = (RuntimeBasicBlockWrapper) iter.next(); 141 result += "("; if (!element.isEntered()) { 143 result += "!"; } 145 result += element.getStartLine() + ","; if (!element.isExited()) { 147 result += "!"; } 149 result += element.getEndLine() + ")" ; afterfirstIteration = true; 151 } 152 result += " ]"; return result; 154 } 155 156 public boolean equals(Object obj) { 157 if (obj instanceof Path) { 158 Path comPath = (Path) obj; 159 if (!this.getRegisteredMethod().equals(comPath.getRegisteredMethod())) { 160 return false; 161 } 162 Iterator compIter = comPath.enteredBlocks.iterator(); 163 Iterator iter = enteredBlocks.iterator(); 164 while (compIter.hasNext() & iter.hasNext()) { 165 if (!iter.next().equals(compIter.next())) { 166 return false; 167 } 168 } 169 if (compIter.hasNext() != iter.hasNext()) { 170 return false; 171 } 172 return true; 173 } 174 return false; 175 } 176 177 public int hashCode() { 178 int pow = (int) Math.pow(enteredBlocks.size(), 4); 179 return pow % 151; 181 } 182 183 public Object clone() { 184 Path result = new Path(); 185 cloneFields(result); 186 assert this.equals(result) : "Cloned objects are not really cloned"; return result; 188 } 189 190 protected void cloneFields(Path target) { 191 if (currentBlock != null) { 192 target.currentBlock = (RuntimeBasicBlockWrapper) this.currentBlock.clone(); 193 } 194 target.enteredBlocks = (LinkedList) this.enteredBlocks.clone(); 195 } 196 197 201 public RegisteredMethod getRegisteredMethod() { 202 if (enteredBlocks.isEmpty()) { 203 return null; 204 } 205 return ((IBasicBlock) enteredBlocks.getFirst()).getRegisteredMethod(); 206 } 207 208 public IBasicBlock[] getEnteredBlocks() { 209 return (IBasicBlock[]) enteredBlocks.toArray(new IBasicBlock[enteredBlocks.size()]); 210 } 211 212 public IBasicBlock[] getEnteredBlocksWithoutReiteratedLoops() { 213 List result = new ArrayList(enteredBlocks); 214 snipReiteratedLoops(result); 215 return (IBasicBlock[]) result.toArray(new IBasicBlock[result.size()]); 216 } 217 218 public int length() { 219 return enteredBlocks.size(); 220 } 221 222 public int compareTo(Object o) { 223 if (o instanceof Path) { 224 Path cPath = (Path) o; 225 return this.compareTo(cPath, 0); 226 } 227 throw new AssertionError ("compared object not of class Path!"); } 229 230 private int compareTo(Path path, int recursion) { 231 if (recursion == enteredBlocks.size()) { 232 return 0; 233 } else if (recursion == path.enteredBlocks.size()) { 234 return -1; 235 } 236 237 IBasicBlock cBlock = (IBasicBlock) path.enteredBlocks.get(recursion); 238 IBasicBlock block = (IBasicBlock) enteredBlocks.get(recursion); 239 if (block.getStartLine() > cBlock.getStartLine()) { 240 return 1; 241 } else if (block.getStartLine() < cBlock.getStartLine()) { 242 return 0; 243 } else { 244 return compareTo(path, recursion + 1); 245 } 246 } 247 248 254 public CoverageState loopIncludes(Path subPathWithoutLoops) { 255 if (subPathWithoutLoops == null) { 256 throw new IllegalArgumentException ("Path must be non-null for " + "a coverage decision"); } 259 if (subPathWithoutLoops.enteredBlocks.isEmpty()) { 260 return CoverageState.FULL_COVERAGE; 262 } else if (this.enteredBlocks.isEmpty()) { 263 return CoverageState.NO_COVERAGE; 264 } 265 RuntimeBasicBlockWrapper pathFirstElement = 266 (RuntimeBasicBlockWrapper) subPathWithoutLoops.enteredBlocks.get(0); 267 268 275 for (ListIterator iter = (ListIterator)enteredBlocks.iterator(); iter.hasNext();) { 276 RuntimeBasicBlockWrapper element = (RuntimeBasicBlockWrapper) iter.next(); 277 CoverageState firstPathElementCoverage 278 = element.covers(pathFirstElement); 279 280 if (CoverageState.FULL_COVERAGE == firstPathElementCoverage) { 281 int elementIndex = iter.nextIndex() - 1; 283 List sublist = enteredBlocks.subList(elementIndex, enteredBlocks.size()); 284 List clonedSublist = new ArrayList(sublist); 285 snipReiteratedLoops(clonedSublist); 286 return getCoverage(clonedSublist, subPathWithoutLoops.enteredBlocks); 287 } else if (CoverageState.PARTIAL_COVERAGE == firstPathElementCoverage) { 288 return CoverageState.PARTIAL_COVERAGE; 290 } 291 } 292 return CoverageState.NO_COVERAGE; 293 } 294 295 private void snipReiteratedLoops(List sublist) { 296 int loopStart = getStartLoopPosition(sublist); 297 int loopStop = Integer.MAX_VALUE; 298 while (loopStart >= 0 && loopStop >= loopStart) { 299 loopStop = getStopLoopPosition(sublist, loopStart); 300 sublist.subList(loopStart, loopStop + 1).clear(); 301 loopStart = getStartLoopPosition(sublist); 302 } 303 } 304 305 private int getStopLoopPosition(List list, int loopstart) { 306 List sublist = list.subList(loopstart, list.size()); 307 Object searchObject = list.get(loopstart - 1); 308 int stopPos = sublist.indexOf(searchObject); 309 return stopPos + loopstart; 310 } 311 312 317 private int getStartLoopPosition(List sublist) { 318 List history = new ArrayList(); 319 int result = 0; 320 for (Iterator iter = sublist.iterator(); iter.hasNext();) { 321 IBasicBlock current = (IBasicBlock) iter.next(); 322 if (containsBlock(history, current)) { 323 return result; 324 } 325 history.add(current); 326 result++; 327 } 328 return Integer.MIN_VALUE; 329 } 330 331 private boolean containsBlock(List history, IBasicBlock current) { 332 for (Iterator iter = history.iterator(); iter.hasNext();) { 333 IBasicBlock element = (IBasicBlock) iter.next(); 334 if (CoverageState.FULL_COVERAGE == element.covers(current)) { 335 return true; 336 } 337 } 338 return false; 339 } 340 } 341 | Popular Tags |