1 19 20 25 26 27 package soot.jimple.toolkits.typing; 28 29 import soot.*; 30 import soot.jimple.*; 31 import soot.util.*; 32 import java.util.*; 33 34 37 class TypeNode 38 { 39 private static final boolean DEBUG = false; 40 41 private final int id; 42 private final Type type; 43 private final ClassHierarchy hierarchy; 44 45 private TypeNode parentClass; 46 private TypeNode element; 47 private TypeNode array; 48 49 private List parents = Collections.EMPTY_LIST; 50 private final BitVector ancestors = new BitVector(0); 51 private final BitVector descendants = new BitVector(0); 52 53 public TypeNode(int id, Type type, ClassHierarchy hierarchy) 54 { 55 if(type == null || hierarchy == null) 56 { 57 throw new InternalTypingException(); 58 } 59 60 if(!((type instanceof PrimType) || (type instanceof RefType) || 61 (type instanceof ArrayType) || (type instanceof NullType))) 62 { 63 G.v().out.println("Unhandled type: " + type); 64 throw new InternalTypingException(); 65 } 66 67 this.id = id; 68 this.type = type; 69 this.hierarchy = hierarchy; 70 71 if(DEBUG) 72 { 73 G.v().out.println("creating node " + this); 74 } 75 } 76 77 public TypeNode(int id, RefType type, ClassHierarchy hierarchy) 78 { 79 this(id, (Type) type, hierarchy); 80 81 { 82 SootClass sClass = type.getSootClass(); 83 if( sClass == null ) throw new RuntimeException ( "Oops, forgot to load "+type ); 84 List plist = new LinkedList(); 85 86 if(sClass.hasSuperclass() && 87 !sClass.getName().equals("java.lang.Object")) 88 { 89 TypeNode parent = hierarchy.typeNode(RefType.v(sClass.getSuperclass().getName())); 90 plist.add(parent); 91 parentClass = parent; 92 } 93 94 for(Iterator i = sClass.getInterfaces().iterator(); i.hasNext();) 95 { 96 TypeNode parent = hierarchy.typeNode(RefType.v(((SootClass) i.next()).getName())); 97 plist.add(parent); 98 } 99 100 parents = Collections.unmodifiableList(plist); 101 } 102 103 descendants.set(hierarchy.NULL.id); 104 hierarchy.NULL.ancestors.set(id); 105 106 for( Iterator parentIt = parents.iterator(); parentIt.hasNext(); ) { 107 108 final TypeNode parent = (TypeNode) parentIt.next(); 109 ancestors.set(parent.id); 110 ancestors.or(parent.ancestors); 111 parent.fixDescendants(id); 112 } 113 } 114 115 public TypeNode(int id, ArrayType type, ClassHierarchy hierarchy) 116 { 117 this(id, (Type) type, hierarchy); 118 119 if(type.numDimensions < 1) 120 { 121 throw new InternalTypingException(); 122 } 123 124 if(type.numDimensions == 1) 125 { 126 element = hierarchy.typeNode(type.baseType); 127 } 128 else 129 { 130 element = hierarchy.typeNode(ArrayType.v(type.baseType, type.numDimensions - 1)); 131 } 132 133 if(element != hierarchy.INT) 134 { 135 if(element.array != null) 136 { 137 throw new InternalTypingException(); 138 } 139 140 element.array = this; 141 } 142 143 { 144 List plist = new LinkedList(); 145 if(type.baseType instanceof RefType) 146 { 147 RefType baseType = (RefType) type.baseType; 148 SootClass sClass = baseType.getSootClass(); 149 if(sClass.hasSuperclass() && !sClass.getName().equals("java.lang.Object")) 150 { 151 TypeNode parent = hierarchy.typeNode(ArrayType.v(RefType.v(sClass.getSuperclass().getName()), type.numDimensions)); 152 plist.add(parent); 153 parentClass = parent; 154 } 155 else if(type.numDimensions == 1) 156 { 157 plist.add(hierarchy.OBJECT); 158 159 if (!G.v().isJ2ME) { 161 plist.add(hierarchy.CLONEABLE); 162 plist.add(hierarchy.SERIALIZABLE); 163 } 164 165 parentClass = hierarchy.OBJECT; 166 } 167 else 168 { 169 plist.add(hierarchy.typeNode(ArrayType.v(hierarchy.OBJECT.type(), type.numDimensions - 1))); 170 171 if (!G.v().isJ2ME) { 173 plist.add(hierarchy.typeNode(ArrayType.v(hierarchy.CLONEABLE.type(), type.numDimensions - 1))); 174 plist.add(hierarchy.typeNode(ArrayType.v(hierarchy.SERIALIZABLE.type(), type.numDimensions - 1))); 175 } 176 177 parentClass = hierarchy.typeNode(ArrayType.v(hierarchy.OBJECT.type(), type.numDimensions - 1)); 178 } 179 180 for(Iterator i = sClass.getInterfaces().iterator(); i.hasNext(); ) 181 { 182 TypeNode parent = hierarchy.typeNode(ArrayType.v(RefType.v(((SootClass) i.next()).getName()), type.numDimensions)); 183 plist.add(parent); 184 } 185 } 186 else if(type.numDimensions == 1) 187 { 188 plist.add(hierarchy.OBJECT); 189 190 if (!G.v().isJ2ME) { 192 plist.add(hierarchy.CLONEABLE); 193 plist.add(hierarchy.SERIALIZABLE); 194 } 195 196 parentClass = hierarchy.OBJECT; 197 } 198 else 199 { 200 plist.add(hierarchy.typeNode(ArrayType.v(hierarchy.OBJECT.type(), type.numDimensions - 1))); 201 if (!G.v().isJ2ME) { 203 plist.add(hierarchy.typeNode(ArrayType.v(hierarchy.CLONEABLE.type(), type.numDimensions - 1))); 204 plist.add(hierarchy.typeNode(ArrayType.v(hierarchy.SERIALIZABLE.type(), type.numDimensions - 1))); 205 } 206 207 parentClass = hierarchy.typeNode(ArrayType.v(hierarchy.OBJECT.type(), type.numDimensions - 1)); 208 } 209 210 parents = Collections.unmodifiableList(plist); 211 } 212 213 descendants.set(hierarchy.NULL.id); 214 hierarchy.NULL.ancestors.set(id); 215 216 for( Iterator parentIt = parents.iterator(); parentIt.hasNext(); ) { 217 218 final TypeNode parent = (TypeNode) parentIt.next(); 219 ancestors.set(parent.id); 220 ancestors.or(parent.ancestors); 221 parent.fixDescendants(id); 222 } 223 } 224 225 226 private void fixDescendants(int id) 227 { 228 if(descendants.get(id)) 229 { 230 return; 231 } 232 233 for( Iterator parentIt = parents.iterator(); parentIt.hasNext(); ) { 234 235 final TypeNode parent = (TypeNode) parentIt.next(); 236 parent.fixDescendants(id); 237 } 238 239 descendants.set(id); 240 } 241 242 243 public int id() 244 { 245 return id; 246 } 247 248 249 public Type type() 250 { 251 return type; 252 } 253 254 public boolean hasAncestor(TypeNode typeNode) 255 { 256 return ancestors.get(typeNode.id); 257 } 258 259 public boolean hasAncestorOrSelf(TypeNode typeNode) 260 { 261 if(typeNode == this) 262 return true; 263 264 return ancestors.get(typeNode.id); 265 } 266 267 public boolean hasDescendant(TypeNode typeNode) 268 { 269 return descendants.get(typeNode.id); 270 } 271 272 public boolean hasDescendantOrSelf(TypeNode typeNode) 273 { 274 if(typeNode == this) 275 return true; 276 277 return descendants.get(typeNode.id); 278 } 279 280 public List parents() 281 { 282 return parents; 283 } 284 285 public TypeNode parentClass() 286 { 287 return parentClass; 288 } 289 290 public String toString() 291 { 292 return type.toString()+ "(" + id + ")"; 293 } 294 295 public TypeNode lca(TypeNode type) throws TypeException 296 { 297 TypeNode initial = type; 298 299 if(type == null) 300 { 301 throw new InternalTypingException(); 302 } 303 304 if(type == this) 305 { 306 return this; 307 } 308 309 if(hasAncestor(type)) 310 { 311 return type; 312 } 313 314 if(hasDescendant(type)) 315 { 316 return this; 317 } 318 319 do 320 { 321 type = type.parentClass; 322 323 if(type == null) 324 { 325 try 326 { 327 TypeVariable.error("Type Error(12)"); 328 } 329 catch(TypeException e) 330 { 331 if(DEBUG) e.printStackTrace(); 332 throw e; 333 } 334 } 335 } 336 while(!hasAncestor(type)); 337 338 return type; 339 } 340 341 public TypeNode lcaIfUnique(TypeNode type) throws TypeException 342 { 343 TypeNode initial = type; 344 345 if(type == null) 346 { 347 throw new InternalTypingException(); 348 } 349 350 if(type == this) 351 { 352 return this; 353 } 354 355 if(hasAncestor(type)) 356 { 357 return type; 358 } 359 360 if(hasDescendant(type)) 361 { 362 return this; 363 } 364 365 do 366 { 367 if(type.parents.size() == 1) 368 { 369 type = (TypeNode) type.parents.get(0); 370 } 371 else 372 { 373 if(DEBUG) 374 { 375 G.v().out.println("lca " + initial + " (" + type + ") & " + this + " ="); 376 for(Iterator i = type.parents.iterator(); i.hasNext(); ) 377 { 378 G.v().out.println(" " + i.next()); 379 } 380 } 381 return null; 382 } 383 } 384 while(!hasAncestor(type)); 385 386 return type; 387 } 388 389 public boolean hasElement() 390 { 391 return element != null; 392 } 393 394 public TypeNode element() 395 { 396 if(element == null) 397 { 398 throw new InternalTypingException(); 399 } 400 401 return element; 402 } 403 404 public TypeNode array() 405 { 406 if(array != null) 407 { 408 return array; 409 } 410 411 if(type instanceof ArrayType) 412 { 413 ArrayType atype = (ArrayType) type; 414 array = hierarchy.typeNode(ArrayType.v(atype.baseType, atype.numDimensions + 1)); 415 return array; 416 } 417 418 if(type instanceof PrimType || type instanceof RefType) 419 { 420 array = hierarchy.typeNode(ArrayType.v(type, 1)); 421 return array; 422 } 423 424 throw new InternalTypingException(); 425 } 426 427 public boolean isNull() 428 { 429 if(type instanceof NullType) 430 { 431 return true; 432 } 433 434 return false; 435 } 436 437 public boolean isClass() 438 { 439 if(type instanceof ArrayType || 440 type instanceof NullType || 441 (type instanceof RefType && 442 !((RefType) type).getSootClass().isInterface())) 443 { 444 return true; 445 } 446 447 return false; 448 } 449 450 public boolean isClassOrInterface() 451 { 452 if(type instanceof ArrayType || 453 type instanceof NullType || 454 type instanceof RefType) 455 { 456 return true; 457 } 458 459 return false; 460 } 461 462 public boolean isArray() 463 { 464 if(type instanceof ArrayType || 465 type instanceof NullType) 466 { 467 return true; 468 } 469 470 return false; 471 } 472 } 473 | Popular Tags |