diff --git a/src/main/javassist/CtClass.java b/src/main/javassist/CtClass.java
index 8880b1f6..dec20de6 100644
--- a/src/main/javassist/CtClass.java
+++ b/src/main/javassist/CtClass.java
@@ -550,6 +550,43 @@ public void fix(String name) {}
return null;
}
+ /**
+ * Returns a collection of the names of all the classes
+ * referenced in this class.
+ * This reference contains a reference to the generic.
+ * If you wish to exclude generics,see this method{@link CtClass#getRefClasses()}
+ * That collection includes the name of this class.
+ *
+ *
This method may return null
.
+ *
+ * @return a Collection<String>
object.
+ */
+ public synchronized Collection getAllRefClasses() {
+ ClassFile cf = getClassFile2();
+ if (cf != null) {
+ ClassMap cm = new ClassMap() {
+ /** default serialVersionUID */
+ private static final long serialVersionUID = 1L;
+ @Override
+ public String put(String oldname, String newname) {
+ return put0(oldname, newname);
+ }
+ @Override
+ public String get(Object jvmClassName) {
+ String n = toJavaName((String)jvmClassName);
+ put0(n, n);
+ return null;
+ }
+
+ @Override
+ public void fix(String name) {}
+ };
+ cf.getAllRefClasses(cm);
+ return cm.values();
+ }
+ return null;
+ }
+
/**
* Determines whether this object represents a class or an interface.
* It returns true
if this object represents an interface.
diff --git a/src/main/javassist/bytecode/ClassFile.java b/src/main/javassist/bytecode/ClassFile.java
index 5e7475a6..96e27ada 100644
--- a/src/main/javassist/bytecode/ClassFile.java
+++ b/src/main/javassist/bytecode/ClassFile.java
@@ -522,6 +522,39 @@ public final void getRefClasses(Map classnames) {
}
}
+ /**
+ * Internal-use only.
+ * CtClass.getAllRefClasses()
calls this method.
+ */
+ public final void getAllRefClasses(Map classnames) {
+ constPool.renameClass(classnames);
+
+ AttributeInfo.getRefClasses(attributes, classnames);
+ for (MethodInfo minfo : methods) {
+ String genericDesc = getGenericDesc(minfo);
+ if (genericDesc != null)
+ Descriptor.renameIncludeGenerics(genericDesc, classnames);
+ else
+ Descriptor.rename(minfo.getDescriptor(), classnames);
+ AttributeInfo.getRefClasses(minfo.getAttributes(), classnames);
+ }
+
+ for (FieldInfo finfo : fields) {
+ String desc = finfo.getDescriptor();
+ Descriptor.rename(desc, classnames);
+ AttributeInfo.getRefClasses(finfo.getAttributes(), classnames);
+ }
+ }
+
+ /**
+ * Returns the generic signature
+ */
+ private String getGenericDesc(MethodInfo methodInfo) {
+ SignatureAttribute sa
+ = (SignatureAttribute) methodInfo.getAttribute(SignatureAttribute.tag);
+ return sa == null ? null : sa.getSignature();
+ }
+
/**
* Returns the names of the interfaces implemented by the class.
* The returned array is read only.
diff --git a/src/main/javassist/bytecode/Descriptor.java b/src/main/javassist/bytecode/Descriptor.java
index 4e4fd863..a6491148 100644
--- a/src/main/javassist/bytecode/Descriptor.java
+++ b/src/main/javassist/bytecode/Descriptor.java
@@ -188,6 +188,55 @@ else if (desc.startsWith(oldname, j + 1)
return newdesc.toString();
}
+ /**
+ * Substitutes class names and generics in the given descriptor string
+ * according to the given map
.
+ *
+ * @param map a map between replaced and substituted
+ * JVM class names.
+ * @see Descriptor#toJvmName(String)
+ */
+ public static String renameIncludeGenerics(String desc, Map map) {
+ if (map == null)
+ return desc;
+
+ StringBuilder newdesc = new StringBuilder();
+ int head = 0;
+ int i = 0;
+ for (; ; ) {
+ int j = desc.indexOf('L', i);
+ if (j < 0)
+ break;
+
+ int x = desc.indexOf('<', j);
+ int y = desc.indexOf(';', j);
+ if (x == y)
+ break;
+ int k = x == -1 ? y : 0;
+ if (k == 0)
+ k = Math.min(x,y);
+
+ i = k + 1;
+ String name = desc.substring(j + 1, k);
+ String name2 = map.get(name);
+ if (name2 != null) {
+ newdesc.append(desc.substring(head, j));
+ newdesc.append('L');
+ newdesc.append(name2);
+ newdesc.append(';');
+ head = i;
+ }
+ }
+
+ if (head == 0)
+ return desc;
+ int len = desc.length();
+ if (head < len)
+ newdesc.append(desc.substring(head, len));
+
+ return newdesc.toString();
+ }
+
/**
* Substitutes class names in the given descriptor string
* according to the given map
.
diff --git a/src/test/javassist/JvstTest4.java b/src/test/javassist/JvstTest4.java
index 259451b9..cbc4ae25 100644
--- a/src/test/javassist/JvstTest4.java
+++ b/src/test/javassist/JvstTest4.java
@@ -481,6 +481,28 @@ public void testGetAllRefC() throws Exception {
}
}
+ public void testGetAllRefD() throws Exception {
+ CtClass cc = sloader.get("test4.GetAllRefD");
+ HashSet set = new HashSet();
+ set.add("java.lang.Object");
+ set.add("java.lang.String");
+ set.add("test4.GetAllRefC");
+ set.add("test4.GetAllRefAnno");
+ set.add("test4.GetAllRefEnum");
+ set.add("test4.GetAllRefAnnoC");
+ set.add("test4.GetAllRefAnnoC2");
+ set.add("test4.GetAllRefAnnoC3");
+ set.add("test4.GetAllRefAnnoC4");
+ set.add("java.util.List");
+ set.add("test4.GetAllRefD");
+ java.util.Collection refs
+ = (java.util.Collection)cc.getAllRefClasses();
+ assertEquals(set.size(), refs.size());
+ for (String s: refs) {
+ assertTrue(set.contains(s));
+ }
+ }
+
public void testGetAllRefInner() throws Exception {
HashSet set = new HashSet();
set.add("java.lang.Object");
diff --git a/src/test/test4/GetAllRef.java b/src/test/test4/GetAllRef.java
index c19bfabd..e5244555 100644
--- a/src/test/test4/GetAllRef.java
+++ b/src/test/test4/GetAllRef.java
@@ -1,5 +1,7 @@
package test4;
+import java.util.List;
+
enum GetAllRefEnum { A, B };
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@@ -31,3 +33,11 @@ void bar(@GetAllRefAnnoC3 int i, int j,
@GetAllRefAnnoC void foo() {}
@GetAllRefAnnoC2 int value;
}
+
+@GetAllRefAnno(getA = GetAllRefEnum.A, getC = String.class)
+interface GetAllRefD {
+ void bar(@GetAllRefAnnoC3 int i, int j,
+ @GetAllRefAnnoC2 @GetAllRefAnnoC4 boolean b);
+ @GetAllRefAnnoC
+ List foo();
+}