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

Print this page

        

@@ -140,10 +140,19 @@
     public static Finder getAPIFinder(int access) {
         return new APIDependencyFinder(access);
     }
 
     /**
+     * Get a finder to do class dependency analysis.
+     *
+     * @return a Class dependency finder
+     */
+    public static Finder getClassDependencyFinder() {
+        return new ClassDependencyFinder();
+    }
+
+    /**
      * Get the finder used to locate the dependencies for a class.
      * @return the finder
      */
     public Finder getFinder() {
         if (finder == null)

@@ -244,12 +253,10 @@
         };
         findAllDependencies(classFinder, rootClassNames, transitiveClosure, r);
         return results;
     }
 
-
-
     /**
      * Find the dependencies of a class, using the current
      * {@link Dependencies#getFinder finder} and
      * {@link Dependencies#getFilter filter}.
      * The search may optionally include the transitive closure of all the

@@ -304,42 +311,48 @@
 
     /**
      * A location identifying a class.
      */
     static class SimpleLocation implements Location {
-        public SimpleLocation(String className) {
-            this.className = className;
+        public SimpleLocation(String name) {
+            this.name = name;
+            this.className = name.replace('/', '.');
         }
 
-        /**
-         * Get the name of the class being depended on. This name will be used to
-         * locate the class file for transitive dependency analysis.
-         * @return the name of the class being depended on
-         */
+        public String getName() {
+            return name;
+        }
+
         public String getClassName() {
             return className;
         }
 
+        public String getPackageName() {
+            int i = className.lastIndexOf('.');
+            return (i > 0) ? className.substring(0, i) : "";
+        }
+
         @Override
         public boolean equals(Object other) {
             if (this == other)
                 return true;
             if (!(other instanceof SimpleLocation))
                 return false;
-            return (className.equals(((SimpleLocation) other).className));
+            return (name.equals(((SimpleLocation) other).name));
         }
 
         @Override
         public int hashCode() {
-            return className.hashCode();
+            return name.hashCode();
         }
 
         @Override
         public String toString() {
-            return className;
+            return name;
         }
 
+        private String name;
         private String className;
     }
 
     /**
      * A dependency of one class on another.

@@ -429,13 +442,11 @@
             this.packageNames = packageNames;
             this.matchSubpackages = matchSubpackages;
         }
 
         public boolean accepts(Dependency dependency) {
-            String cn = dependency.getTarget().getClassName();
-            int lastSep = cn.lastIndexOf("/");
-            String pn = (lastSep == -1 ? "" : cn.substring(0, lastSep));
+            String pn = dependency.getTarget().getPackageName();
             if (packageNames.contains(pn))
                 return true;
 
             if (matchSubpackages) {
                 for (String n: packageNames) {

@@ -449,21 +460,39 @@
 
         private final Set<String> packageNames;
         private final boolean matchSubpackages;
     }
 
-
-
     /**
      * This class identifies class names directly or indirectly in the constant pool.
      */
     static class ClassDependencyFinder extends BasicDependencyFinder {
         public Iterable<? extends Dependency> findDependencies(ClassFile classfile) {
             Visitor v = new Visitor(classfile);
             for (CPInfo cpInfo: classfile.constant_pool.entries()) {
                 v.scan(cpInfo);
             }
+            try {
+                v.addClass(classfile.super_class);
+                v.addClasses(classfile.interfaces);
+                v.scan(classfile.attributes);
+
+                for (Field f : classfile.fields) {
+                    v.scan(f.descriptor, f.attributes);
+                }
+                for (Method m : classfile.methods) {
+                    v.scan(m.descriptor, m.attributes);
+                    Exceptions_attribute e =
+                        (Exceptions_attribute)m.attributes.get(Attribute.Exceptions);
+                    if (e != null) {
+                        v.addClasses(e.exception_index_table);
+                    }
+                }
+            } catch (ConstantPoolException e) {
+                throw new ClassFileError(e);
+            }
+
             return v.deps;
         }
     }
 
     /**

@@ -556,13 +585,11 @@
             }
 
             void scan(Descriptor d, Attributes attrs) {
                 try {
                     scan(new Signature(d.index).getType(constant_pool));
-                    Signature_attribute sa = (Signature_attribute) attrs.get(Attribute.Signature);
-                    if (sa != null)
-                        scan(new Signature(sa.signature_index).getType(constant_pool));
+                    scan(attrs);
                 } catch (ConstantPoolException e) {
                     throw new ClassFileError(e);
                 }
             }
 

@@ -572,10 +599,47 @@
 
             void scan(Type t) {
                 t.accept(this, null);
             }
 
+            void scan(Attributes attrs) {
+                try {
+                    Signature_attribute sa = (Signature_attribute)attrs.get(Attribute.Signature);
+                    if (sa != null)
+                        scan(sa.getParsedSignature().getType(constant_pool));
+
+                    scan((RuntimeVisibleAnnotations_attribute)
+                            attrs.get(Attribute.RuntimeVisibleAnnotations));
+                    scan((RuntimeVisibleParameterAnnotations_attribute)
+                            attrs.get(Attribute.RuntimeVisibleParameterAnnotations));
+                } catch (ConstantPoolException e) {
+                    throw new ClassFileError(e);
+                }
+            }
+
+            private void scan(RuntimeAnnotations_attribute attr) throws ConstantPoolException {
+                if (attr == null) {
+                    return;
+                }
+                for (int i = 0; i < attr.annotations.length; i++) {
+                    int index = attr.annotations[i].type_index;
+                    scan(new Signature(index).getType(constant_pool));
+                }
+            }
+
+            private void scan(RuntimeParameterAnnotations_attribute attr) throws ConstantPoolException {
+                if (attr == null) {
+                    return;
+                }
+                for (int param = 0; param < attr.parameter_annotations.length; param++) {
+                    for (int i = 0; i < attr.parameter_annotations[param].length; i++) {
+                        int index = attr.parameter_annotations[param][i].type_index;
+                        scan(new Signature(index).getType(constant_pool));
+                    }
+                }
+            }
+
             void addClass(int index) throws ConstantPoolException {
                 if (index != 0) {
                     String name = constant_pool.getClassInfo(index).getBaseName();
                     if (name != null)
                         addDependency(name);

@@ -696,10 +760,11 @@
 
             public Void visitMethodType(MethodType type, Void p) {
                 findDependencies(type.paramTypes);
                 findDependencies(type.returnType);
                 findDependencies(type.throwsTypes);
+                findDependencies(type.typeParamTypes);
                 return null;
             }
 
             public Void visitClassSigType(ClassSigType type, Void p) {
                 findDependencies(type.superclassType);

@@ -707,11 +772,11 @@
                 return null;
             }
 
             public Void visitClassType(ClassType type, Void p) {
                 findDependencies(type.outerType);
-                addDependency(type.name);
+                addDependency(type.getBinaryName());
                 findDependencies(type.typeArgs);
                 return null;
             }
 
             public Void visitTypeParamType(TypeParamType type, Void p) {