src/share/classes/com/sun/tools/classfile/Dependencies.java

changeset 1472
0c244701188e
parent 1358
fc123bdeddb8
child 1715
57648bad3287
equal deleted inserted replaced
1468:690c41cdab55 1472:0c244701188e
140 public static Finder getAPIFinder(int access) { 140 public static Finder getAPIFinder(int access) {
141 return new APIDependencyFinder(access); 141 return new APIDependencyFinder(access);
142 } 142 }
143 143
144 /** 144 /**
145 * Get a finder to do class dependency analysis.
146 *
147 * @return a Class dependency finder
148 */
149 public static Finder getClassDependencyFinder() {
150 return new ClassDependencyFinder();
151 }
152
153 /**
145 * Get the finder used to locate the dependencies for a class. 154 * Get the finder used to locate the dependencies for a class.
146 * @return the finder 155 * @return the finder
147 */ 156 */
148 public Finder getFinder() { 157 public Finder getFinder() {
149 if (finder == null) 158 if (finder == null)
244 }; 253 };
245 findAllDependencies(classFinder, rootClassNames, transitiveClosure, r); 254 findAllDependencies(classFinder, rootClassNames, transitiveClosure, r);
246 return results; 255 return results;
247 } 256 }
248 257
249
250
251 /** 258 /**
252 * Find the dependencies of a class, using the current 259 * Find the dependencies of a class, using the current
253 * {@link Dependencies#getFinder finder} and 260 * {@link Dependencies#getFinder finder} and
254 * {@link Dependencies#getFilter filter}. 261 * {@link Dependencies#getFilter filter}.
255 * The search may optionally include the transitive closure of all the 262 * The search may optionally include the transitive closure of all the
304 311
305 /** 312 /**
306 * A location identifying a class. 313 * A location identifying a class.
307 */ 314 */
308 static class SimpleLocation implements Location { 315 static class SimpleLocation implements Location {
309 public SimpleLocation(String className) { 316 public SimpleLocation(String name) {
310 this.className = className; 317 this.name = name;
311 } 318 this.className = name.replace('/', '.').replace('$', '.');
312 319 }
313 /** 320
314 * Get the name of the class being depended on. This name will be used to 321 public String getName() {
315 * locate the class file for transitive dependency analysis. 322 return name;
316 * @return the name of the class being depended on 323 }
317 */ 324
318 public String getClassName() { 325 public String getClassName() {
319 return className; 326 return className;
327 }
328
329 public String getPackageName() {
330 int i = name.lastIndexOf('/');
331 return (i > 0) ? name.substring(0, i).replace('/', '.') : "";
320 } 332 }
321 333
322 @Override 334 @Override
323 public boolean equals(Object other) { 335 public boolean equals(Object other) {
324 if (this == other) 336 if (this == other)
325 return true; 337 return true;
326 if (!(other instanceof SimpleLocation)) 338 if (!(other instanceof SimpleLocation))
327 return false; 339 return false;
328 return (className.equals(((SimpleLocation) other).className)); 340 return (name.equals(((SimpleLocation) other).name));
329 } 341 }
330 342
331 @Override 343 @Override
332 public int hashCode() { 344 public int hashCode() {
333 return className.hashCode(); 345 return name.hashCode();
334 } 346 }
335 347
336 @Override 348 @Override
337 public String toString() { 349 public String toString() {
338 return className; 350 return name;
339 } 351 }
340 352
353 private String name;
341 private String className; 354 private String className;
342 } 355 }
343 356
344 /** 357 /**
345 * A dependency of one class on another. 358 * A dependency of one class on another.
429 this.packageNames = packageNames; 442 this.packageNames = packageNames;
430 this.matchSubpackages = matchSubpackages; 443 this.matchSubpackages = matchSubpackages;
431 } 444 }
432 445
433 public boolean accepts(Dependency dependency) { 446 public boolean accepts(Dependency dependency) {
434 String cn = dependency.getTarget().getClassName(); 447 String pn = dependency.getTarget().getPackageName();
435 int lastSep = cn.lastIndexOf("/");
436 String pn = (lastSep == -1 ? "" : cn.substring(0, lastSep));
437 if (packageNames.contains(pn)) 448 if (packageNames.contains(pn))
438 return true; 449 return true;
439 450
440 if (matchSubpackages) { 451 if (matchSubpackages) {
441 for (String n: packageNames) { 452 for (String n: packageNames) {
448 } 459 }
449 460
450 private final Set<String> packageNames; 461 private final Set<String> packageNames;
451 private final boolean matchSubpackages; 462 private final boolean matchSubpackages;
452 } 463 }
453
454
455 464
456 /** 465 /**
457 * This class identifies class names directly or indirectly in the constant pool. 466 * This class identifies class names directly or indirectly in the constant pool.
458 */ 467 */
459 static class ClassDependencyFinder extends BasicDependencyFinder { 468 static class ClassDependencyFinder extends BasicDependencyFinder {
460 public Iterable<? extends Dependency> findDependencies(ClassFile classfile) { 469 public Iterable<? extends Dependency> findDependencies(ClassFile classfile) {
461 Visitor v = new Visitor(classfile); 470 Visitor v = new Visitor(classfile);
462 for (CPInfo cpInfo: classfile.constant_pool.entries()) { 471 for (CPInfo cpInfo: classfile.constant_pool.entries()) {
463 v.scan(cpInfo); 472 v.scan(cpInfo);
464 } 473 }
474 try {
475 v.addClass(classfile.super_class);
476 v.addClasses(classfile.interfaces);
477 v.scan(classfile.attributes);
478
479 for (Field f : classfile.fields) {
480 v.scan(f.descriptor, f.attributes);
481 }
482 for (Method m : classfile.methods) {
483 v.scan(m.descriptor, m.attributes);
484 Exceptions_attribute e =
485 (Exceptions_attribute)m.attributes.get(Attribute.Exceptions);
486 if (e != null) {
487 v.addClasses(e.exception_index_table);
488 }
489 }
490 } catch (ConstantPoolException e) {
491 throw new ClassFileError(e);
492 }
493
465 return v.deps; 494 return v.deps;
466 } 495 }
467 } 496 }
468 497
469 /** 498 /**
556 } 585 }
557 586
558 void scan(Descriptor d, Attributes attrs) { 587 void scan(Descriptor d, Attributes attrs) {
559 try { 588 try {
560 scan(new Signature(d.index).getType(constant_pool)); 589 scan(new Signature(d.index).getType(constant_pool));
561 Signature_attribute sa = (Signature_attribute) attrs.get(Attribute.Signature); 590 scan(attrs);
562 if (sa != null)
563 scan(new Signature(sa.signature_index).getType(constant_pool));
564 } catch (ConstantPoolException e) { 591 } catch (ConstantPoolException e) {
565 throw new ClassFileError(e); 592 throw new ClassFileError(e);
566 } 593 }
567 } 594 }
568 595
570 cpInfo.accept(this, null); 597 cpInfo.accept(this, null);
571 } 598 }
572 599
573 void scan(Type t) { 600 void scan(Type t) {
574 t.accept(this, null); 601 t.accept(this, null);
602 }
603
604 void scan(Attributes attrs) {
605 try {
606 Signature_attribute sa = (Signature_attribute)attrs.get(Attribute.Signature);
607 if (sa != null)
608 scan(sa.getParsedSignature().getType(constant_pool));
609
610 scan((RuntimeVisibleAnnotations_attribute)
611 attrs.get(Attribute.RuntimeVisibleAnnotations));
612 scan((RuntimeVisibleParameterAnnotations_attribute)
613 attrs.get(Attribute.RuntimeVisibleParameterAnnotations));
614 } catch (ConstantPoolException e) {
615 throw new ClassFileError(e);
616 }
617 }
618
619 private void scan(RuntimeAnnotations_attribute attr) throws ConstantPoolException {
620 if (attr == null) {
621 return;
622 }
623 for (int i = 0; i < attr.annotations.length; i++) {
624 int index = attr.annotations[i].type_index;
625 scan(new Signature(index).getType(constant_pool));
626 }
627 }
628
629 private void scan(RuntimeParameterAnnotations_attribute attr) throws ConstantPoolException {
630 if (attr == null) {
631 return;
632 }
633 for (int param = 0; param < attr.parameter_annotations.length; param++) {
634 for (int i = 0; i < attr.parameter_annotations[param].length; i++) {
635 int index = attr.parameter_annotations[param][i].type_index;
636 scan(new Signature(index).getType(constant_pool));
637 }
638 }
575 } 639 }
576 640
577 void addClass(int index) throws ConstantPoolException { 641 void addClass(int index) throws ConstantPoolException {
578 if (index != 0) { 642 if (index != 0) {
579 String name = constant_pool.getClassInfo(index).getBaseName(); 643 String name = constant_pool.getClassInfo(index).getBaseName();
696 760
697 public Void visitMethodType(MethodType type, Void p) { 761 public Void visitMethodType(MethodType type, Void p) {
698 findDependencies(type.paramTypes); 762 findDependencies(type.paramTypes);
699 findDependencies(type.returnType); 763 findDependencies(type.returnType);
700 findDependencies(type.throwsTypes); 764 findDependencies(type.throwsTypes);
765 findDependencies(type.typeParamTypes);
701 return null; 766 return null;
702 } 767 }
703 768
704 public Void visitClassSigType(ClassSigType type, Void p) { 769 public Void visitClassSigType(ClassSigType type, Void p) {
705 findDependencies(type.superclassType); 770 findDependencies(type.superclassType);
707 return null; 772 return null;
708 } 773 }
709 774
710 public Void visitClassType(ClassType type, Void p) { 775 public Void visitClassType(ClassType type, Void p) {
711 findDependencies(type.outerType); 776 findDependencies(type.outerType);
712 addDependency(type.name); 777 addDependency(type.getBinaryName());
713 findDependencies(type.typeArgs); 778 findDependencies(type.typeArgs);
714 return null; 779 return null;
715 } 780 }
716 781
717 public Void visitTypeParamType(TypeParamType type, Void p) { 782 public Void visitTypeParamType(TypeParamType type, Void p) {

mercurial