1 26 27 package net.sourceforge.groboutils.codecoverage.v2.module; 28 29 30 import net.sourceforge.groboutils.codecoverage.v2.IAnalysisMetaData; 31 import net.sourceforge.groboutils.codecoverage.v2.IMethodCode; 32 33 import org.apache.bcel.classfile.CodeException; 34 import org.apache.bcel.generic.IfInstruction; 35 import org.apache.bcel.generic.Instruction; 36 import org.apache.bcel.generic.InstructionHandle; 37 import org.apache.bcel.generic.JsrInstruction; 38 import org.apache.bcel.generic.Select; 39 40 41 62 public class BranchCountMeasure extends AbstractMeasure 63 { 64 67 70 public String getMeasureName() 71 { 72 return "Branch"; 73 } 74 75 78 public String getMeasureUnit() 79 { 80 return "branches"; 81 } 82 83 84 88 public String getMimeEncoding() 89 { 90 return "text/plain"; 91 } 92 93 94 97 public void analyze( IMethodCode method ) 98 { 99 BytecodeLineUtil blu = new BytecodeLineUtil( method ); 100 InstructionHandle handles[] = blu.getHandles(); 101 102 markInstruction( method, 0, createAMD( "Start of Method", 105 blu.getLineNumberForInstructionPos( 0 ) ), false ); 106 107 108 for (int i = 0; i < handles.length; ++i) 110 { 111 InstructionHandle h = handles[i]; 112 Instruction instr = h.getInstruction(); 113 114 if (instr instanceof IfInstruction) 116 { 117 markIf( method, (IfInstruction)instr, i, blu ); 118 } 119 else 120 if (instr instanceof Select) 121 { 122 markSelect( method, (Select)instr, i, blu ); 123 } 124 else 125 if (instr instanceof JsrInstruction) 126 { 127 markJsr( method, (JsrInstruction)instr, i, blu ); 128 } 129 } 130 131 CodeException exceptions[] = method.getOriginalMethod().getCode(). 133 getExceptionTable(); 134 for (int i = 0; i < exceptions.length; ++i) 135 { 136 markExceptionHandler( method, exceptions[i], blu ); 137 } 138 } 139 140 141 144 private void markIf( IMethodCode method, IfInstruction instr, 145 int i, BytecodeLineUtil blu ) 146 { 147 int lineNo = blu.getLineNumberForInstructionPos( i+1 ); 148 149 markInstruction( method, i+1, 154 createAMD( "'True' branch", lineNo ), false ); 155 156 InstructionHandle target = instr.getTarget(); 157 markTarget( method, target, blu, "'False' branch" ); 158 } 159 160 161 164 private void markSelect( IMethodCode method, Select instr, 165 int i, BytecodeLineUtil blu ) 166 { 167 int lineNo = blu.getLineNumberForInstructionPos( i+1 ); 168 markInstruction( method, i+1, 169 createAMD( "After switch", lineNo ), false ); 170 171 InstructionHandle targets[] = instr.getTargets(); 172 for (int tIndex = 0; tIndex < targets.length; ++tIndex) 173 { 174 markTarget( method, 175 targets[ tIndex ], 176 blu, 177 "Case index "+Integer.toString( tIndex + 1 ) ); 178 } 179 } 180 181 182 185 private void markJsr( IMethodCode method, JsrInstruction instr, 186 int i, BytecodeLineUtil blu ) 187 { 188 InstructionHandle target = instr.getTarget(); 190 markTarget( method, target, blu, "Finally block" ); 191 } 192 193 194 197 private void markExceptionHandler( IMethodCode method, CodeException ce, 198 BytecodeLineUtil blu ) 199 { 200 int pc = ce.getHandlerPC(); 201 202 markInstruction( method, 204 blu.getInstructionPosForBytecodePos( pc ), 205 createAMD( "Exception handler", 206 blu.getLineNumberForBytecodePos( pc ) ), 207 false ); 208 } 209 210 211 private void markTarget( IMethodCode method, InstructionHandle target, 212 BytecodeLineUtil blu, String branchDesc ) 213 { 214 if (target != null) 215 { 216 markInstruction( method, 218 blu.getInstructionPosForBytecodePos( target.getPosition() ), 219 createAMD( 220 branchDesc, 221 blu.getLineNumber( target ) ), 222 false ); 223 } 224 } 225 226 227 230 private IAnalysisMetaData createAMD( String type, int lineNo ) 231 { 232 return new DefaultAnalysisMetaData( 233 type+" at line "+lineNo, 234 "Didn't cover "+type+" at line "+lineNo, 235 (byte)0 ); 236 } 237 } 238 | Popular Tags |