A support class for dealing with descriptors.
See chapter 4.3 in "The Java Virtual Machine Specification (2nd ed.)"
| Method from javassist.bytecode.Descriptor Detail: |
public static String appendParameter(String classname,
String desc) {
int i = desc.indexOf(')');
if (i < 0)
return desc;
else {
StringBuffer newdesc = new StringBuffer();
newdesc.append(desc.substring(0, i));
newdesc.append('L');
newdesc.append(classname.replace('.', '/'));
newdesc.append(';');
newdesc.append(desc.substring(i));
return newdesc.toString();
}
}
|
public static String appendParameter(CtClass type,
String descriptor) {
int i = descriptor.indexOf(')');
if (i < 0)
return descriptor;
else {
StringBuffer newdesc = new StringBuffer();
newdesc.append(descriptor.substring(0, i));
toDescriptor(newdesc, type);
newdesc.append(descriptor.substring(i));
return newdesc.toString();
}
}
Appends a parameter type to the parameter list represented
by the given descriptor. The appended parameter becomes
the last parameter. |
public static int arrayDimension(String desc) {
int dim = 0;
while (desc.charAt(dim) == '[')
++dim;
return dim;
}
Computes the dimension of the array represented by the given
descriptor. For example, if the descriptor is "[[I",
then this method returns 2. |
public static String changeReturnType(String classname,
String desc) {
int i = desc.indexOf(')');
if (i < 0)
return desc;
else {
StringBuffer newdesc = new StringBuffer();
newdesc.append(desc.substring(0, i + 1));
newdesc.append('L');
newdesc.append(classname.replace('.', '/'));
newdesc.append(';');
return newdesc.toString();
}
}
|
public static int dataSize(String desc) {
return dataSize(desc, true);
}
Computes the data size specified by the given descriptor.
For example, if the descriptor is "D", this method returns 2.
If the descriptor represents a method type, this method returns
(the size of the returned value) - (the sum of the data sizes
of all the parameters). For example, if the descriptor is
"(I)D", then this method returns 1 (= 2 - 1). |
public static boolean eqParamTypes(String desc1,
String desc2) {
if (desc1.charAt(0) != '(')
return false;
for (int i = 0; true; ++i) {
char c = desc1.charAt(i);
if (c != desc2.charAt(i))
return false;
if (c == ')')
return true;
}
}
Returns true if the list of the parameter types of desc1 is equal to
that of desc2.
For example, "(II)V" and "(II)I" are equal. |
public static String getParamDescriptor(String decl) {
return decl.substring(0, decl.indexOf(')') + 1);
}
Returns the signature of the given descriptor. The signature does
not include the return type. For example, the signature of "(I)V"
is "(I)". |
public static CtClass[] getParameterTypes(String desc,
ClassPool cp) throws NotFoundException {
if (desc.charAt(0) != '(')
return null;
else {
int num = numOfParameters(desc);
CtClass[] args = new CtClass[num];
int n = 0;
int i = 1;
do {
i = toCtClass(cp, desc, i, args, n++);
} while (i > 0);
return args;
}
}
Returns the CtClass objects representing the parameter
types specified by the given descriptor. |
public static CtClass getReturnType(String desc,
ClassPool cp) throws NotFoundException {
int i = desc.indexOf(')');
if (i < 0)
return null;
else {
CtClass[] type = new CtClass[1];
toCtClass(cp, desc, i + 1, type, 0);
return type[0];
}
}
Returns the CtClass object representing the return
type specified by the given descriptor. |
public static String insertParameter(String classname,
String desc) {
if (desc.charAt(0) != '(')
return desc;
else
return "(L" + classname.replace('.', '/') + ';'
+ desc.substring(1);
}
|
public static String insertParameter(CtClass type,
String descriptor) {
if (descriptor.charAt(0) != '(')
return descriptor;
else
return "(" + of(type) + descriptor.substring(1);
}
Inserts a parameter type at the beginning of the parameter
list represented
by the given descriptor. |
public static int numOfParameters(String desc) {
int n = 0;
int i = 1;
for (;;) {
char c = desc.charAt(i);
if (c == ')')
break;
while (c == '[')
c = desc.charAt(++i);
if (c == 'L') {
i = desc.indexOf(';', i) + 1;
if (i < = 0)
throw new IndexOutOfBoundsException("bad descriptor");
}
else
++i;
++n;
}
return n;
}
Returns the number of the prameters included in the given
descriptor. |
public static String of(String classname) {
if (classname.equals("void"))
return "V";
else if (classname.equals("int"))
return "I";
else if (classname.equals("byte"))
return "B";
else if (classname.equals("long"))
return "J";
else if (classname.equals("double"))
return "D";
else if (classname.equals("float"))
return "F";
else if (classname.equals("char"))
return "C";
else if (classname.equals("short"))
return "S";
else if (classname.equals("boolean"))
return "Z";
else
return "L" + toJvmName(classname) + ";";
}
Converts to a descriptor from a Java class name |
public static String of(CtClass type) {
StringBuffer sbuf = new StringBuffer();
toDescriptor(sbuf, type);
return sbuf.toString();
}
Returns the descriptor representing the given type. |
public static String ofConstructor(CtClass[] paramTypes) {
return ofMethod(CtClass.voidType, paramTypes);
}
Returns the descriptor representing a constructor receiving
the given parameter types. |
public static String ofMethod(CtClass returnType,
CtClass[] paramTypes) {
StringBuffer desc = new StringBuffer();
desc.append('(');
if (paramTypes != null) {
int n = paramTypes.length;
for (int i = 0; i < n; ++i)
toDescriptor(desc, paramTypes[i]);
}
desc.append(')');
if (returnType != null)
toDescriptor(desc, returnType);
return desc.toString();
}
Returns the descriptor representing a method that receives
the given parameter types and returns the given type. |
public static String ofParameters(CtClass[] paramTypes) {
return ofMethod(null, paramTypes);
}
Returns the descriptor representing a list of parameter types.
For example, if the given parameter types are two int,
then this method returns "(II)". |
public static int paramSize(String desc) {
return -dataSize(desc, false);
}
Computes the data size of parameters.
If one of the parameters is double type, the size of that parameter
is 2 words. For example, if the given descriptor is
"(IJ)D", then this method returns 3. The size of the
return type is not computed. |
public static String rename(String desc,
Map map) {
if (map == null)
return desc;
StringBuffer newdesc = new StringBuffer();
int head = 0;
int i = 0;
for (;;) {
int j = desc.indexOf('L', i);
if (j < 0)
break;
int k = desc.indexOf(';', j);
if (k < 0)
break;
i = k + 1;
String name = desc.substring(j + 1, k);
String name2 = (String)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;
else {
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. |
public static String rename(String desc,
String oldname,
String newname) {
if (desc.indexOf(oldname) < 0)
return desc;
StringBuffer newdesc = new StringBuffer();
int head = 0;
int i = 0;
for (;;) {
int j = desc.indexOf('L', i);
if (j < 0)
break;
else if (desc.startsWith(oldname, j + 1)
&& desc.charAt(j + oldname.length() + 1) == ';') {
newdesc.append(desc.substring(head, j));
newdesc.append('L');
newdesc.append(newname);
newdesc.append(';');
head = i = j + oldname.length() + 2;
}
else {
i = desc.indexOf(';', j) + 1;
if (i < 1)
break; // ';' was not found.
}
}
if (head == 0)
return desc;
else {
int len = desc.length();
if (head < len)
newdesc.append(desc.substring(head, len));
return newdesc.toString();
}
}
Substitutes a class name
in the given descriptor string. |
public static String toArrayComponent(String desc,
int dim) {
return desc.substring(dim);
}
Returns the descriptor of the type of the array component.
For example, if the given descriptor is
"[[Ljava/lang/String;" and the given dimension is 2,
then this method returns "Ljava/lang/String;". |
public static String toClassName(String descriptor) {
int arrayDim = 0;
int i = 0;
char c = descriptor.charAt(0);
while (c == '[') {
++arrayDim;
c = descriptor.charAt(++i);
}
String name;
if (c == 'L') {
int i2 = descriptor.indexOf(';', i++);
name = descriptor.substring(i, i2).replace('/', '.');
i = i2;
}
else if (c == 'V')
name = "void";
else if (c == 'I')
name = "int";
else if (c == 'B')
name = "byte";
else if (c == 'J')
name = "long";
else if (c == 'D')
name = "double";
else if (c == 'F')
name = "float";
else if (c == 'C')
name = "char";
else if (c == 'S')
name = "short";
else if (c == 'Z')
name = "boolean";
else
throw new RuntimeException("bad descriptor: " + descriptor);
if (i + 1 != descriptor.length())
throw new RuntimeException("multiple descriptors?: " + descriptor);
if (arrayDim == 0)
return name;
else {
StringBuffer sbuf = new StringBuffer(name);
do {
sbuf.append("[]");
} while (--arrayDim > 0);
return sbuf.toString();
}
}
Converts to a Java class name from a descriptor. |
public static CtClass toCtClass(String desc,
ClassPool cp) throws NotFoundException {
CtClass[] clazz = new CtClass[1];
int res = toCtClass(cp, desc, 0, clazz, 0);
if (res >= 0)
return clazz[0];
else {
// maybe, you forgot to surround the class name with
// L and ;. It violates the protocol, but I'm tolerant...
return cp.get(desc.replace('/', '.'));
}
}
Returns a CtClass object representing the type
specified by the given descriptor.
This method works even if the package-class separator is
not / but . (period). For example,
it accepts Ljava.lang.Object;
as well as Ljava/lang/Object;. |
public static String toJavaName(String classname) {
return classname.replace('/', '.');
}
Converts a class name from the internal representation used in
the JVM to the normal one used in Java.
This method does not deal with an array type name such as
"[Ljava/lang/Object;" and "[I;". For such names, use
toClassName(). |
public static String toJvmName(String classname) {
return classname.replace('.', '/');
}
|
public static String toJvmName(CtClass clazz) {
if (clazz.isArray())
return of(clazz);
else
return toJvmName(clazz.getName());
}
Returns the internal representation of the class name in the
JVM. |
static CtClass toPrimitiveClass(char c) {
CtClass type = null;
switch (c) {
case 'Z' :
type = CtClass.booleanType;
break;
case 'C' :
type = CtClass.charType;
break;
case 'B' :
type = CtClass.byteType;
break;
case 'S' :
type = CtClass.shortType;
break;
case 'I' :
type = CtClass.intType;
break;
case 'J' :
type = CtClass.longType;
break;
case 'F' :
type = CtClass.floatType;
break;
case 'D' :
type = CtClass.doubleType;
break;
case 'V' :
type = CtClass.voidType;
break;
}
return type;
}
|
public static String toString(String desc) {
return PrettyPrinter.toString(desc);
}
Returns a human-readable representation of the
given descriptor. For example, Ljava/lang/Object;
is converted into java.lang.Object.
(I[I)V is converted into (int, int[])
(the return type is ignored). |