1 21 package proguard.classfile; 22 23 import proguard.classfile.util.*; 24 import proguard.classfile.visitor.*; 25 import proguard.classfile.attribute.visitor.AttributeVisitor; 26 import proguard.classfile.constant.*; 27 import proguard.classfile.constant.visitor.ConstantVisitor; 28 29 34 public class LibraryClass implements Clazz 35 { 36 public int u2accessFlags; 37 public String thisClassName; 38 public String superClassName; 39 public String [] interfaceNames; 40 public LibraryField[] fields; 41 public LibraryMethod[] methods; 42 43 47 public Clazz superClass; 48 49 53 public Clazz[] interfaceClasses; 54 55 59 public Clazz[] subClasses; 60 61 64 public Object visitorInfo; 65 66 67 70 public LibraryClass() {} 71 72 73 76 boolean isVisible() 77 { 78 return (u2accessFlags & ClassConstants.INTERNAL_ACC_PUBLIC) != 0; 79 } 80 81 82 86 private String toName(Constant[] constantPool, int constantIndex) 87 { 88 ClassConstant classEntry = (ClassConstant)constantPool[constantIndex]; 89 Utf8Constant nameEntry = (Utf8Constant)constantPool[classEntry.u2nameIndex]; 90 91 return nameEntry.getString(); 92 } 93 94 95 97 public int getAccessFlags() 98 { 99 return u2accessFlags; 100 } 101 102 public String getName() 103 { 104 return thisClassName; 105 } 106 107 public String getSuperName() 108 { 109 return superClassName; 111 } 112 113 public int getInterfaceCount() 114 { 115 return interfaceClasses.length; 116 } 117 118 public String getInterfaceName(int index) 119 { 120 return interfaceNames[index]; 121 } 122 123 public int getTag(int constantIndex) 124 { 125 throw new UnsupportedOperationException ("Library class ["+thisClassName+"] doesn't store constant pool"); 126 } 127 128 public String getString(int constantIndex) 129 { 130 throw new UnsupportedOperationException ("Library class ["+thisClassName+"] doesn't store constant pool"); 131 } 132 133 public String getStringString(int constantIndex) 134 { 135 throw new UnsupportedOperationException ("Library class ["+thisClassName+"] doesn't store constant pool"); 136 } 137 138 public String getClassName(int constantIndex) 139 { 140 throw new UnsupportedOperationException ("Library class ["+thisClassName+"] doesn't store constant pool"); 141 } 142 143 public String getName(int constantIndex) 144 { 145 throw new UnsupportedOperationException ("Library class ["+thisClassName+"] doesn't store constant pool"); 146 } 147 148 public String getType(int constantIndex) 149 { 150 throw new UnsupportedOperationException ("Library class ["+thisClassName+"] doesn't store constant pool"); 151 } 152 153 154 public void addSubClass(Clazz clazz) 155 { 156 if (subClasses == null) 157 { 158 subClasses = new Clazz[1]; 159 } 160 else 161 { 162 Clazz[] temp = new Clazz[subClasses.length+1]; 164 System.arraycopy(subClasses, 0, temp, 0, subClasses.length); 165 subClasses = temp; 166 } 167 168 subClasses[subClasses.length-1] = clazz; 169 } 170 171 172 public Clazz getSuperClass() 173 { 174 return superClass; 175 } 176 177 178 public Clazz getInterface(int index) 179 { 180 return interfaceClasses[index]; 181 } 182 183 184 public boolean extends_(Clazz clazz) 185 { 186 if (this.equals(clazz)) 187 { 188 return true; 189 } 190 191 Clazz superClass = getSuperClass(); 192 return superClass != null && 193 superClass.extends_(clazz); 194 } 195 196 197 public boolean extendsOrImplements(Clazz clazz) 198 { 199 if (this.equals(clazz)) 200 { 201 return true; 202 } 203 204 Clazz superClass = getSuperClass(); 205 if (superClass != null && 206 superClass.extendsOrImplements(clazz)) 207 { 208 return true; 209 } 210 211 if (interfaceClasses != null) 212 { 213 for (int index = 0; index < interfaceClasses.length; index++) 214 { 215 Clazz interfaceClass = interfaceClasses[index]; 216 if (interfaceClass != null && 217 interfaceClass.extendsOrImplements(clazz)) 218 { 219 return true; 220 } 221 } 222 } 223 224 return false; 225 } 226 227 228 public Field findField(String name, String descriptor) 229 { 230 for (int index = 0; index < fields.length; index++) 231 { 232 Field field = fields[index]; 233 if (field != null && 234 (name == null || field.getName(this).equals(name)) && 235 (descriptor == null || field.getDescriptor(this).equals(descriptor))) 236 { 237 return field; 238 } 239 } 240 241 return null; 242 } 243 244 245 public Method findMethod(String name, String descriptor) 246 { 247 for (int index = 0; index < methods.length; index++) 248 { 249 Method method = methods[index]; 250 if (method != null && 251 (name == null || method.getName(this).equals(name)) && 252 (descriptor == null || method.getDescriptor(this).equals(descriptor))) 253 { 254 return method; 255 } 256 } 257 258 return null; 259 } 260 261 262 public void accept(ClassVisitor classVisitor) 263 { 264 classVisitor.visitLibraryClass(this); 265 } 266 267 268 public void hierarchyAccept(boolean visitThisClass, 269 boolean visitSuperClass, 270 boolean visitInterfaces, 271 boolean visitSubclasses, 272 ClassVisitor classVisitor) 273 { 274 if (visitThisClass) 276 { 277 accept(classVisitor); 278 } 279 280 if (visitSuperClass) 282 { 283 if (superClass != null) 284 { 285 superClass.hierarchyAccept(true, 286 true, 287 visitInterfaces, 288 false, 289 classVisitor); 290 } 291 } 292 293 if (visitInterfaces) 295 { 296 if (interfaceClasses != null) 297 { 298 for (int index = 0; index < interfaceClasses.length; index++) 299 { 300 Clazz interfaceClass = interfaceClasses[index]; 301 if (interfaceClass != null) 302 { 303 interfaceClass.hierarchyAccept(true, 304 true, 305 true, 306 false, 307 classVisitor); 308 } 309 } 310 } 311 } 312 313 if (visitSubclasses) 315 { 316 if (subClasses != null) 317 { 318 for (int index = 0; index < subClasses.length; index++) 319 { 320 subClasses[index].hierarchyAccept(true, 321 false, 322 false, 323 true, 324 classVisitor); 325 } 326 } 327 } 328 } 329 330 331 public void constantPoolEntriesAccept(ConstantVisitor constantVisitor) 332 { 333 } 335 336 337 public void constantPoolEntryAccept(int index, ConstantVisitor constantVisitor) 338 { 339 } 341 342 343 public void fieldsAccept(MemberVisitor memberVisitor) 344 { 345 for (int index = 0; index < fields.length; index++) 346 { 347 Field field = fields[index]; 348 if (field != null) 349 { 350 field.accept(this, memberVisitor); 351 } 352 } 353 } 354 355 356 public void fieldAccept(String name, String descriptor, MemberVisitor memberVisitor) 357 { 358 Field field = findField(name, descriptor); 359 if (field != null) 360 { 361 field.accept(this, memberVisitor); 362 } 363 } 364 365 366 public void methodsAccept(MemberVisitor memberVisitor) 367 { 368 for (int index = 0; index < methods.length; index++) 369 { 370 Method method = methods[index]; 371 if (method != null) 372 { 373 method.accept(this, memberVisitor); 374 } 375 } 376 } 377 378 379 public void methodAccept(String name, String descriptor, MemberVisitor memberVisitor) 380 { 381 Method method = findMethod(name, descriptor); 382 if (method != null) 383 { 384 method.accept(this, memberVisitor); 385 } 386 } 387 388 389 public boolean mayHaveImplementations(Method method) 390 { 391 return 392 (u2accessFlags & ClassConstants.INTERNAL_ACC_FINAL) == 0 && 393 (method == null || 394 ((method.getAccessFlags() & (ClassConstants.INTERNAL_ACC_PRIVATE | 395 ClassConstants.INTERNAL_ACC_STATIC | 396 ClassConstants.INTERNAL_ACC_FINAL)) == 0 && 397 !method.getName(this).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT))); 398 } 399 400 401 private boolean isSpecial(Method method) 402 { 403 return 404 (method.getAccessFlags() & (ClassConstants.INTERNAL_ACC_PRIVATE | 405 ClassConstants.INTERNAL_ACC_STATIC)) != 0 || 406 method.getName(this).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT); 407 } 408 409 410 public void methodImplementationsAccept(Method method, 411 boolean visitThisMethod, 412 MemberVisitor memberVisitor) 413 { 414 methodImplementationsAccept(method.getName(this), 415 method.getDescriptor(this), 416 method, 417 visitThisMethod, 418 true, 419 true, 420 true, 421 memberVisitor); 422 } 423 424 425 public void methodImplementationsAccept(String name, 426 String descriptor, 427 boolean visitThisMethod, 428 MemberVisitor memberVisitor) 429 { 430 methodImplementationsAccept(name, 431 descriptor, 432 visitThisMethod, 433 true, 434 true, 435 true, 436 memberVisitor); 437 } 438 439 440 public void methodImplementationsAccept(String name, 441 String descriptor, 442 boolean visitThisMethod, 443 boolean visitSpecialMethods, 444 boolean visitSuperMethods, 445 boolean visitOverridingMethods, 446 MemberVisitor memberVisitor) 447 { 448 methodImplementationsAccept(name, 449 descriptor, 450 findMethod(name, descriptor), 451 visitThisMethod, 452 visitSpecialMethods, 453 visitSuperMethods, 454 visitOverridingMethods, 455 memberVisitor); 456 } 457 458 459 public void methodImplementationsAccept(String name, 460 String descriptor, 461 Method method, 462 boolean visitThisMethod, 463 boolean visitSpecialMethods, 464 boolean visitSuperMethods, 465 boolean visitOverridingMethods, 466 MemberVisitor memberVisitor) 467 { 468 if (method != null) 470 { 471 if (isSpecial(method)) 473 { 474 if (visitSpecialMethods) 476 { 477 method.accept(this, memberVisitor); 478 479 return; 481 } 482 } 483 else 484 { 485 if (visitThisMethod) 487 { 488 method.accept(this, memberVisitor); 489 } 490 491 if (!mayHaveImplementations(method)) 494 { 495 visitOverridingMethods = false; 496 } 497 498 if ((method.getAccessFlags() & ClassConstants.INTERNAL_ACC_ABSTRACT) == 0) 501 { 502 visitSuperMethods = false; 503 } 504 } 505 } 506 507 if (visitOverridingMethods) 509 { 510 if (subClasses != null) 512 { 513 for (int index = 0; index < subClasses.length; index++) 514 { 515 Clazz subClass = subClasses[index]; 516 subClass.methodImplementationsAccept(name, 517 descriptor, 518 true, 519 false, 520 visitSuperMethods, 521 true, 522 memberVisitor); 523 } 524 } 525 526 if ((u2accessFlags & (ClassConstants.INTERNAL_ACC_INTERFACE | 529 ClassConstants.INTERNAL_ACC_ABSTRACT)) != 0) 530 { 531 visitSuperMethods = false; 532 } 533 } 534 535 if (visitSuperMethods) 537 { 538 Clazz superClass = getSuperClass(); 539 if (superClass != null) 540 { 541 superClass.methodImplementationsAccept(name, 542 descriptor, 543 true, 544 false, 545 true, 546 false, 547 memberVisitor); 548 } 549 } 550 } 551 552 553 public void attributesAccept(AttributeVisitor attributeVisitor) 554 { 555 throw new UnsupportedOperationException ("Library class ["+thisClassName+"] doesn't store attributes"); 556 } 557 558 559 561 public Object getVisitorInfo() 562 { 563 return visitorInfo; 564 } 565 566 public void setVisitorInfo(Object visitorInfo) 567 { 568 this.visitorInfo = visitorInfo; 569 } 570 } 571 | Popular Tags |