1 5 package de.uka.ipd.coverage.natures; 6 7 import java.util.*; 8 9 import org.apache.bcel.classfile.*; 10 import org.eclipse.jface.resource.ImageDescriptor; 11 12 import de.uka.ipd.coverage.plugin.CoveragePlugin; 13 import de.uka.ipd.coverage.plugin.ui.CoverageNatureDescriptor; 14 import de.uka.ipd.coverage.recording.*; 15 import de.uka.ipd.coverage.utils.Logger; 16 17 21 public class BlockCoverageNature implements CoverageNature { 22 23 private Logger logger = new Logger(this); 24 private List registeredMethods = new LinkedList(); private Map testedClasses = new HashMap(); 27 public static final CoverageNatureDescriptor DESCRIPTOR = new CoverageNatureDescriptor() { 28 29 public String getName() { 30 return Messages.getString("BlockCoverageNature.0"); } 32 33 public String getDescription() { 34 return Messages.getString("BlockCoverageNature.1"); } 36 37 public String getID() { 38 return "de.uka.ipd.coverage.natures.BlockCoverageNature"; } 40 41 public ImageDescriptor getImageDescriptor() { 42 String iconPath = "icons/coverageNatures/"; String [] icons = new String [] {"block_coverage_nature"}; return CoveragePlugin.getDefault().getImageDescriptors( 45 icons, iconPath)[0]; 46 } 47 48 49 }; 50 51 54 public TestedClass[] getMeasuredClasses() { 55 return (TestedClass[]) testedClasses.values().toArray( 56 new TestedClass[testedClasses.size()]); 57 } 58 59 62 public CompleteCoverage getCompleteCoverage(JavaClass jclass) { 63 List methodList = findRegisteredMethods(jclass); 65 CompleteCoverage result = new CompleteCoverage(jclass); 66 67 for (Iterator iter = methodList.iterator(); iter.hasNext();) { 69 70 RegisteredMethod element = (RegisteredMethod) iter.next(); 72 LineNumberTable lineNumberTable = 73 element.getMethod().getCode().getLineNumberTable(); 74 LineNumber[] lineNumbers = lineNumberTable.getLineNumberTable(); 75 TranslatingBasicBlock[] transBlocks = 76 (TranslatingBasicBlock[]) element.getBasicBlocks(); 77 78 recordLineNumbers(lineNumbers, transBlocks); 79 80 recordCoverageState(result, element, lineNumbers, transBlocks); 82 } 83 return result; 84 } 85 86 private void recordCoverageState( 87 CompleteCoverage result, 88 RegisteredMethod element, 89 LineNumber[] lineNumbers, 90 TranslatingBasicBlock[] transBlocks) { 91 int currentLineNumber = Integer.MIN_VALUE; 92 for (int i = 0; i < lineNumbers.length; i++) { 93 if (lineNumbers[i].getLineNumber() != currentLineNumber) { 94 currentLineNumber = lineNumbers[i].getLineNumber(); 95 TranslatingBasicBlock[] correspondingBlocks = 96 getCorrespondingBlocks(transBlocks, currentLineNumber); 97 98 assert correspondingBlocks.length > 0 : 99 "Line " + currentLineNumber + " in Method " + element.getMethod().getName() + " of class " + element.getJavaClass().getClassName() + " is not covered by a block!"; 104 CoverageState currentLineState 105 = correspondingBlocks[0].getCoverageState(); 106 for (int j = 1; j < correspondingBlocks.length; j++) { 107 CoverageState.mergeCoverages(currentLineState, 108 correspondingBlocks[j].getCoverageState()); 109 } 110 String reason = makeReason(currentLineState); 111 result.addLine(new SourceCodeLine(currentLineNumber), 112 currentLineState, reason); 113 } 114 } 115 } 116 117 120 private String makeReason(CoverageState currentLineState) { 121 String reason; 122 if (currentLineState == CoverageState.FULL_COVERAGE) { 123 reason = Messages.getString("BlockCoverageNature.10"); } else if (currentLineState == CoverageState.PARTIAL_COVERAGE) { 125 reason = Messages.getString("BlockCoverageNature.11"); } else { 127 reason = Messages.getString("BlockCoverageNature.12"); } 129 return reason; 130 } 131 132 private void recordLineNumbers(LineNumber[] lineNumbers, TranslatingBasicBlock[] transBlocks) { 133 for (int i = 0; i < transBlocks.length; i++) { 135 List correspondingLineNumbers = new ArrayList(); 136 for (int j = transBlocks[i].getStartLine(); 137 j <= transBlocks[i].getEndLine(); j++) { 138 LineNumber lineNumber = getCorrespondingLineNumber( 139 lineNumbers, j); 140 if (lineNumber != null) { 141 correspondingLineNumbers.add(lineNumber); 142 } 143 } 144 transBlocks[i].setCorrespondingLineNumbers( 145 (LineNumber[]) correspondingLineNumbers.toArray( 146 new LineNumber[correspondingLineNumbers.size()])); 147 } 148 } 149 150 156 private LineNumber getCorrespondingLineNumber( 157 LineNumber[] lineNumbers, 158 int pc) { 159 for (int i = 0; i < lineNumbers.length; i++) { 160 if (lineNumbers[i].getStartPC() == pc) { 161 return lineNumbers[i]; 162 } 163 } 164 return null; 165 } 166 167 173 private TranslatingBasicBlock[] getCorrespondingBlocks( 174 TranslatingBasicBlock[] transBlocks, 175 int currentLineNumber) { 176 List result = new ArrayList(); 177 for (int i = 0; i < transBlocks.length; i++) { 178 if (transBlocks[i].contains(currentLineNumber)) { 179 result.add(transBlocks[i]); 180 } 181 } 182 return (TranslatingBasicBlock[]) result.toArray( 183 new TranslatingBasicBlock[result.size()]); 184 } 185 186 189 private List findRegisteredMethods(JavaClass jclass) { 190 List result = new LinkedList(); 191 for (Iterator iter = registeredMethods.iterator(); iter.hasNext();) { 192 RegisteredMethod element = (RegisteredMethod) iter.next(); 193 if (element.getJavaClass().getClassName().equals(jclass.getClassName())) { 194 result.add(element); 195 } 196 } 197 return result; 198 } 199 200 203 public void visitCode(RegisteredMethod callback, Code code) { 204 BasicBlock[] blocks = callback.getBasicBlocks(); 205 TranslatingBasicBlock[] transBlocks = new TranslatingBasicBlock[blocks.length]; 206 if (blocks != null && blocks.length > 0) { 207 Path singleBlockPath = new Path(); 208 singleBlockPath.addEnteredBlock(blocks[0]); 209 singleBlockPath.addExitedBlock(blocks[0]); 210 CoverageState state = callback.isCovered(singleBlockPath); 211 for (int i = 0; i < blocks.length; i++) { 212 singleBlockPath = new Path(); 213 singleBlockPath.addEnteredBlock(blocks[i]); 214 singleBlockPath.addExitedBlock(blocks[i]); 215 CoverageState blockCoverage = callback.isCovered(singleBlockPath); 217 transBlocks[i] = new TranslatingBasicBlock(blocks[i], blockCoverage); 218 219 state = CoverageState.mergeCoverages(state, blockCoverage); 220 221 } 222 callback.setBasicBlocks(transBlocks); 223 224 TestedClass classRecord; 226 if (!testedClasses.containsKey(callback.getJavaClass())) { 227 classRecord = new TestedClass(callback.getJavaClass(), 228 state); 229 } else { 230 classRecord = (TestedClass) 231 testedClasses.get(callback.getJavaClass()); 232 CoverageState classCoverage = 233 CoverageState.mergeCoverages(classRecord.getState(), state); 234 classRecord.setState(classCoverage); 235 } 236 testedClasses.put(callback.getJavaClass(), classRecord); 237 registeredMethods.add(callback); 238 } 239 } 240 241 242 public CoverageNatureDescriptor getCoverageNatureDescriptor() { 243 return DESCRIPTOR; 244 } 245 246 249 public void clear() { 250 registeredMethods.clear(); 251 testedClasses.clear(); 252 } 253 254 } | Popular Tags |