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('/', '.').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 = name.lastIndexOf('/');
+ return (i > 0) ? name.substring(0, i).replace('/', '.') : "";
+ }
+
@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) {