1.1 --- a/src/share/classes/com/sun/tools/classfile/Dependencies.java Tue Dec 25 17:23:59 2012 -0800 1.2 +++ b/src/share/classes/com/sun/tools/classfile/Dependencies.java Fri Dec 28 22:25:21 2012 -0800 1.3 @@ -142,6 +142,15 @@ 1.4 } 1.5 1.6 /** 1.7 + * Get a finder to do class dependency analysis. 1.8 + * 1.9 + * @return a Class dependency finder 1.10 + */ 1.11 + public static Finder getClassDependencyFinder() { 1.12 + return new ClassDependencyFinder(); 1.13 + } 1.14 + 1.15 + /** 1.16 * Get the finder used to locate the dependencies for a class. 1.17 * @return the finder 1.18 */ 1.19 @@ -246,8 +255,6 @@ 1.20 return results; 1.21 } 1.22 1.23 - 1.24 - 1.25 /** 1.26 * Find the dependencies of a class, using the current 1.27 * {@link Dependencies#getFinder finder} and 1.28 @@ -306,38 +313,44 @@ 1.29 * A location identifying a class. 1.30 */ 1.31 static class SimpleLocation implements Location { 1.32 - public SimpleLocation(String className) { 1.33 - this.className = className; 1.34 + public SimpleLocation(String name) { 1.35 + this.name = name; 1.36 + this.className = name.replace('/', '.').replace('$', '.'); 1.37 } 1.38 1.39 - /** 1.40 - * Get the name of the class being depended on. This name will be used to 1.41 - * locate the class file for transitive dependency analysis. 1.42 - * @return the name of the class being depended on 1.43 - */ 1.44 + public String getName() { 1.45 + return name; 1.46 + } 1.47 + 1.48 public String getClassName() { 1.49 return className; 1.50 } 1.51 1.52 + public String getPackageName() { 1.53 + int i = name.lastIndexOf('/'); 1.54 + return (i > 0) ? name.substring(0, i).replace('/', '.') : ""; 1.55 + } 1.56 + 1.57 @Override 1.58 public boolean equals(Object other) { 1.59 if (this == other) 1.60 return true; 1.61 if (!(other instanceof SimpleLocation)) 1.62 return false; 1.63 - return (className.equals(((SimpleLocation) other).className)); 1.64 + return (name.equals(((SimpleLocation) other).name)); 1.65 } 1.66 1.67 @Override 1.68 public int hashCode() { 1.69 - return className.hashCode(); 1.70 + return name.hashCode(); 1.71 } 1.72 1.73 @Override 1.74 public String toString() { 1.75 - return className; 1.76 + return name; 1.77 } 1.78 1.79 + private String name; 1.80 private String className; 1.81 } 1.82 1.83 @@ -431,9 +444,7 @@ 1.84 } 1.85 1.86 public boolean accepts(Dependency dependency) { 1.87 - String cn = dependency.getTarget().getClassName(); 1.88 - int lastSep = cn.lastIndexOf("/"); 1.89 - String pn = (lastSep == -1 ? "" : cn.substring(0, lastSep)); 1.90 + String pn = dependency.getTarget().getPackageName(); 1.91 if (packageNames.contains(pn)) 1.92 return true; 1.93 1.94 @@ -451,8 +462,6 @@ 1.95 private final boolean matchSubpackages; 1.96 } 1.97 1.98 - 1.99 - 1.100 /** 1.101 * This class identifies class names directly or indirectly in the constant pool. 1.102 */ 1.103 @@ -462,6 +471,26 @@ 1.104 for (CPInfo cpInfo: classfile.constant_pool.entries()) { 1.105 v.scan(cpInfo); 1.106 } 1.107 + try { 1.108 + v.addClass(classfile.super_class); 1.109 + v.addClasses(classfile.interfaces); 1.110 + v.scan(classfile.attributes); 1.111 + 1.112 + for (Field f : classfile.fields) { 1.113 + v.scan(f.descriptor, f.attributes); 1.114 + } 1.115 + for (Method m : classfile.methods) { 1.116 + v.scan(m.descriptor, m.attributes); 1.117 + Exceptions_attribute e = 1.118 + (Exceptions_attribute)m.attributes.get(Attribute.Exceptions); 1.119 + if (e != null) { 1.120 + v.addClasses(e.exception_index_table); 1.121 + } 1.122 + } 1.123 + } catch (ConstantPoolException e) { 1.124 + throw new ClassFileError(e); 1.125 + } 1.126 + 1.127 return v.deps; 1.128 } 1.129 } 1.130 @@ -558,9 +587,7 @@ 1.131 void scan(Descriptor d, Attributes attrs) { 1.132 try { 1.133 scan(new Signature(d.index).getType(constant_pool)); 1.134 - Signature_attribute sa = (Signature_attribute) attrs.get(Attribute.Signature); 1.135 - if (sa != null) 1.136 - scan(new Signature(sa.signature_index).getType(constant_pool)); 1.137 + scan(attrs); 1.138 } catch (ConstantPoolException e) { 1.139 throw new ClassFileError(e); 1.140 } 1.141 @@ -574,6 +601,43 @@ 1.142 t.accept(this, null); 1.143 } 1.144 1.145 + void scan(Attributes attrs) { 1.146 + try { 1.147 + Signature_attribute sa = (Signature_attribute)attrs.get(Attribute.Signature); 1.148 + if (sa != null) 1.149 + scan(sa.getParsedSignature().getType(constant_pool)); 1.150 + 1.151 + scan((RuntimeVisibleAnnotations_attribute) 1.152 + attrs.get(Attribute.RuntimeVisibleAnnotations)); 1.153 + scan((RuntimeVisibleParameterAnnotations_attribute) 1.154 + attrs.get(Attribute.RuntimeVisibleParameterAnnotations)); 1.155 + } catch (ConstantPoolException e) { 1.156 + throw new ClassFileError(e); 1.157 + } 1.158 + } 1.159 + 1.160 + private void scan(RuntimeAnnotations_attribute attr) throws ConstantPoolException { 1.161 + if (attr == null) { 1.162 + return; 1.163 + } 1.164 + for (int i = 0; i < attr.annotations.length; i++) { 1.165 + int index = attr.annotations[i].type_index; 1.166 + scan(new Signature(index).getType(constant_pool)); 1.167 + } 1.168 + } 1.169 + 1.170 + private void scan(RuntimeParameterAnnotations_attribute attr) throws ConstantPoolException { 1.171 + if (attr == null) { 1.172 + return; 1.173 + } 1.174 + for (int param = 0; param < attr.parameter_annotations.length; param++) { 1.175 + for (int i = 0; i < attr.parameter_annotations[param].length; i++) { 1.176 + int index = attr.parameter_annotations[param][i].type_index; 1.177 + scan(new Signature(index).getType(constant_pool)); 1.178 + } 1.179 + } 1.180 + } 1.181 + 1.182 void addClass(int index) throws ConstantPoolException { 1.183 if (index != 0) { 1.184 String name = constant_pool.getClassInfo(index).getBaseName(); 1.185 @@ -698,6 +762,7 @@ 1.186 findDependencies(type.paramTypes); 1.187 findDependencies(type.returnType); 1.188 findDependencies(type.throwsTypes); 1.189 + findDependencies(type.typeParamTypes); 1.190 return null; 1.191 } 1.192 1.193 @@ -709,7 +774,7 @@ 1.194 1.195 public Void visitClassType(ClassType type, Void p) { 1.196 findDependencies(type.outerType); 1.197 - addDependency(type.name); 1.198 + addDependency(type.getBinaryName()); 1.199 findDependencies(type.typeArgs); 1.200 return null; 1.201 }