1 19 20 package edu.umd.cs.findbugs.ba; 21 22 import java.util.Locale ; 23 import java.util.Set ; 24 25 import org.apache.bcel.generic.InstructionHandle; 26 27 import edu.umd.cs.findbugs.graph.AbstractEdge; 28 29 36 public class Edge extends AbstractEdge<Edge, BasicBlock> implements EdgeTypes, Debug { 37 38 41 42 private int type; 43 private int flags; 44 45 48 49 55 public Edge(BasicBlock source, BasicBlock dest) { 56 super(source, dest); 57 } 58 59 public int getId() { 60 return getLabel(); 61 } 62 63 66 public int getType() { 67 return type; 68 } 69 70 73 public void setType(int type) { 74 this.type = type; 75 } 76 77 80 public int getFlags() { 81 return flags; 82 } 83 84 87 public void setFlags(int flags) { 88 this.flags = flags; 89 } 90 91 97 public boolean isFlagSet(int flag) { 98 return (this.flags & flag) != 0; 99 } 100 101 104 public boolean isExceptionEdge() { 105 return type == HANDLED_EXCEPTION_EDGE || type == UNHANDLED_EXCEPTION_EDGE; 106 } 107 108 @Override 109 public boolean equals(Object o) { 110 if (o == null || this.getClass() != o.getClass()) 111 return false; 112 Edge other = (Edge) o; 113 return this.getSource() == other.getSource() && this.getTarget() == other.getTarget() 114 && this.getType() == other.getType(); 115 } 116 117 @Override 118 public int hashCode() { 119 return 2003 * getSource().getLabel() + getTarget().getLabel(); 120 } 121 122 125 @Override 126 public int compareTo(Edge other) { 127 int cmp = super.compareTo(other); 128 if (cmp != 0) 129 return cmp; 130 return type - other.type; 131 } 132 133 @Override 134 public String toString() { 135 return formatAsString(false); 136 } 137 138 public boolean isBackwardInBytecode() { 139 BasicBlock source = getSource(); 140 BasicBlock target = getTarget(); 141 142 InstructionHandle sourceInstruction = source.getLastInstruction(); 143 InstructionHandle targetInstruction = target.getFirstInstruction(); 144 145 if (targetInstruction == null || sourceInstruction == null) return false; 146 return targetInstruction.getPosition() < sourceInstruction.getPosition(); 147 148 } 149 150 public boolean sourceIsTopOfLoop(Set <Integer > positions) { 151 BasicBlock source = getSource(); 152 153 InstructionHandle sourceInstruction = source.getLastInstruction(); 154 155 if ( sourceInstruction == null) return false; 156 return positions.contains(sourceInstruction.getPosition()); 157 158 159 } 160 163 public String formatAsString(boolean reverse) { 164 BasicBlock source = getSource(); 165 BasicBlock target = getTarget(); 166 167 StringBuffer buf = new StringBuffer (); 168 buf.append(reverse ? "REVERSE_EDGE(" : "EDGE("); 169 buf.append(getLabel()); 170 buf.append(") type "); 171 buf.append(edgeTypeToString(type)); 172 buf.append(" from block "); 173 buf.append(reverse ? target.getId() : source.getId()); 174 buf.append(" to block "); 175 buf.append(reverse ? source.getId() : target.getId()); 176 InstructionHandle sourceInstruction = source.getLastInstruction(); 177 InstructionHandle targetInstruction = target.getFirstInstruction(); 178 String exInfo = " -> "; 179 if (targetInstruction == null && target.isExceptionThrower()) { 180 targetInstruction = target.getExceptionThrower(); 181 exInfo = " => "; 182 } 183 if (sourceInstruction != null && targetInstruction != null) { 184 buf.append(" [bytecode "); 185 buf.append(sourceInstruction.getPosition()); 186 buf.append(exInfo); 187 buf.append(targetInstruction.getPosition()); 188 buf.append(']'); 189 } else if (source.isExceptionThrower()) { 190 if (type == FALL_THROUGH_EDGE) 191 buf.append(" [successful check]"); 192 else { 193 buf.append(" [failed check for "); 194 buf.append(source.getExceptionThrower().getPosition()); 195 if (targetInstruction != null) { 196 buf.append(" to "); 197 buf.append(targetInstruction.getPosition()); 198 } 199 buf.append(']'); 200 } 201 } 202 return buf.toString(); 203 } 204 205 208 public static String edgeTypeToString(int edgeType) { 209 switch (edgeType) { 210 case FALL_THROUGH_EDGE: 211 return "FALL_THROUGH"; 212 case IFCMP_EDGE: 213 return "IFCMP"; 214 case SWITCH_EDGE: 215 return "SWITCH"; 216 case SWITCH_DEFAULT_EDGE: 217 return "SWITCH_DEFAULT"; 218 case JSR_EDGE: 219 return "JSR"; 220 case RET_EDGE: 221 return "RET"; 222 case GOTO_EDGE: 223 return "GOTO"; 224 case RETURN_EDGE: 225 return "RETURN"; 226 case UNHANDLED_EXCEPTION_EDGE: 227 return "UNHANDLED_EXCEPTION"; 228 case HANDLED_EXCEPTION_EDGE: 229 return "HANDLED_EXCEPTION"; 230 case START_EDGE: 231 return "START"; 232 case BACKEDGE_TARGET_EDGE: 233 return "BACKEDGE_TARGET_EDGE"; 234 case BACKEDGE_SOURCE_EDGE: 235 return "BACKEDGE_SOURCE_EDGE"; 236 case EXIT_EDGE: 237 return "EXIT_EDGE"; 238 } 239 throw new IllegalStateException ("unknown edge type: " + edgeType); 240 } 241 242 245 public static int stringToEdgeType(String s) { 246 s = s.toUpperCase(Locale.ENGLISH); 247 248 if (s.equals("FALL_THROUGH")) 249 return FALL_THROUGH_EDGE; 250 else if (s.equals("IFCMP")) 251 return IFCMP_EDGE; 252 else if (s.equals("SWITCH")) 253 return SWITCH_EDGE; 254 else if (s.equals("SWITCH_DEFAULT")) 255 return SWITCH_DEFAULT_EDGE; 256 else if (s.equals("JSR")) 257 return JSR_EDGE; 258 else if (s.equals("RET")) 259 return RET_EDGE; 260 else if (s.equals("GOTO")) 261 return GOTO_EDGE; 262 else if (s.equals("RETURN")) 263 return RETURN_EDGE; 264 else if (s.equals("UNHANDLED_EXCEPTION")) 265 return UNHANDLED_EXCEPTION_EDGE; 266 else if (s.equals("HANDLED_EXCEPTION")) 267 return HANDLED_EXCEPTION_EDGE; 268 else if (s.equals("START")) 269 return START_EDGE; 270 else if (s.equals("BACKEDGE_TARGET_EDGE")) 271 return BACKEDGE_TARGET_EDGE; 272 else if (s.equals("BACKEDGE_SOURCE_EDGE")) 273 return BACKEDGE_SOURCE_EDGE; 274 else if (s.equals("EXIT_EDGE")) 275 return EXIT_EDGE; 276 else 277 throw new IllegalArgumentException ("Unknown edge type: " + s); 278 } 279 } 280 281 | Popular Tags |