* <http://www.apache.org/>.
*/
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.CharArrayReader;
+import java.io.CharArrayWriter;
+import java.io.DataOutputStream;
+import java.io.FilterReader;
+import java.io.FilterWriter;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+
import org.aspectj.apache.bcel.Constants;
import org.aspectj.apache.bcel.classfile.annotation.Annotation;
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePair;
import org.aspectj.apache.bcel.generic.ConstantPoolGen;
import org.aspectj.apache.bcel.generic.annotation.AnnotationGen;
import org.aspectj.apache.bcel.util.ByteSequence;
-import java.io.*;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.zip.*;
/**
* Utility functions that do not really belong to any class in particular.
*
- * @version $Id: Utility.java,v 1.2 2004/11/19 16:45:18 aclement Exp $
+ * @version $Id: Utility.java,v 1.3 2005/03/10 12:14:08 aclement Exp $
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ *
+ * modified: Andy Clement 2-mar-05 Removed unnecessary static and optimized
*/
public abstract class Utility {
- private static int consumed_chars; /* How many chars have been consumed
- * during parsing in signatureToString().
- * Read by methodSignatureToString().
- * Set by side effect,but only internally.
- */
+
private static boolean wide=false; /* The `WIDE' instruction is used in the
* byte code to allow 16-bit wide indices
* for local variables. This opcode
if(for_class && ((p == Constants.ACC_SUPER) || (p == Constants.ACC_INTERFACE)))
continue;
- buf.append(Constants.ACCESS_NAMES[i] + " ");
+ buf.append(Constants.ACCESS_NAMES[i]).append(" ");
}
}
return methodSignatureArgumentTypes(signature, true);
}
+
+
+
/**
* @param signature Method signature
- * @param chopit Shorten class names ?
- * @return Array of argument types
+ * @param chopit Shorten class names ?
+ * @return Array of argument types
* @throws ClassFormatException
*/
- public static final String[] methodSignatureArgumentTypes(String signature,
- boolean chopit)
- throws ClassFormatException
- {
+ public static final String[] methodSignatureArgumentTypes(String signature,boolean chopit) throws ClassFormatException {
ArrayList vec = new ArrayList();
int index;
String[] types;
index = 1; // current string position
while(signature.charAt(index) != ')') {
- vec.add(signatureToString(signature.substring(index), chopit));
- index += consumed_chars; // update position
+ ResultHolder rh = signatureToStringInternal(signature.substring(index),chopit);
+ vec.add(rh.getResult());
+ index += rh.getConsumedChars(); // update position
}
} catch(StringIndexOutOfBoundsException e) { // Should never occur
throw new ClassFormatException("Invalid method signature: " + signature);
vec.toArray(types);
return types;
}
+
+
/**
* @param signature Method signature
* @return return type of method
index = 1; // current string position
while(signature.charAt(index) != ')') {
- String param_type = signatureToString(signature.substring(index), chopit);
+ ResultHolder rh = signatureToStringInternal(signature.substring(index), chopit);
+ String param_type = rh.getResult();
buf.append(param_type);
if(vars != null) {
var_index++;
buf.append(", ");
- index += consumed_chars; // update position
+ index += rh.getConsumedChars(); // update position
}
index++; // update position
public static final String signatureToString(String signature) {
return signatureToString(signature, true);
}
+
+
+ public static final String signatureToString(String signature,boolean chopit) {
+ ResultHolder rh = signatureToStringInternal(signature,chopit);
+ return rh.getResult();
+ }
/**
* The field signature represents the value of an argument to a function or
* @throws ClassFormatException
*/
// J5TODO: This will have problems with nest generic types...(but then I think we all will)
- public static final String signatureToString(String signature,
- boolean chopit)
- {
- consumed_chars = 1; // This is the default, read just one char like `B'
+ public static final ResultHolder signatureToStringInternal(String signature,boolean chopit) {
+ int processedChars = 1; // This is the default, read just one char like `B'
try {
switch(signature.charAt(0)) {
- case 'B' : return "byte";
- case 'C' : return "char";
- case 'D' : return "double";
- case 'F' : return "float";
- case 'I' : return "int";
- case 'J' : return "long";
-
- case 'L' : { // Full class name
- int index = signature.indexOf(';'); // Look for closing `;'
- // Jump to the correct ';'
- if (index!=-1 &&
+ case 'B' : return ResultHolder.BYTE;
+ case 'C' : return ResultHolder.CHAR;
+ case 'D' : return ResultHolder.DOUBLE;
+ case 'F' : return ResultHolder.FLOAT;
+ case 'I' : return ResultHolder.INT;
+ case 'J' : return ResultHolder.LONG;
+
+ case 'L' : { // Full class name
+ int index = signature.indexOf(';'); // Look for closing `;'
+ // Jump to the correct ';'
+ if (index!=-1 &&
signature.length()>index+1 &&
signature.charAt(index+1)=='>') index = index+2;
- if(index < 0)
- throw new ClassFormatException("Invalid signature: " + signature);
-
- int genericStart = signature.indexOf('<');
- int genericEnd = signature.indexOf('>');
- if (genericStart !=-1) {
- return compactClassName(signature.substring(1,genericStart)+"<"+
- signatureToString(signature.substring(genericStart+1,genericEnd),chopit)+">",chopit);
- } else {
+ if (index < 0)
+ throw new ClassFormatException("Invalid signature: " + signature);
- consumed_chars = index + 1; // "Lblabla;" `L' and `;' are removed
-
- return compactClassName(signature.substring(1, index), chopit);
- }
- }
-
- case 'S' : return "short";
- case 'Z' : return "boolean";
+ int genericStart = signature.indexOf('<');
+ int genericEnd = signature.indexOf('>');
+ if (genericStart !=-1) {
+ // FIXME asc going to need a lot more work in here for generics
+ ResultHolder rh = signatureToStringInternal(signature.substring(genericStart+1,genericEnd),chopit);
+ ResultHolder retval = new ResultHolder(compactClassName(signature.substring(1,genericStart)+"<"+
+ rh.getResult()+">",chopit),genericEnd+1);
+ return retval;
+ } else {
+ processedChars = index + 1; // "Lblabla;" `L' and `;' are removed
+ ResultHolder retval = new ResultHolder(compactClassName(signature.substring(1, index), chopit),processedChars);
+ return retval;
+ }
+ }
+
+ case 'S' : return ResultHolder.SHORT;
+ case 'Z' : return ResultHolder.BOOLEAN;
case '[' : { // Array declaration
- int n;
- StringBuffer buf, brackets;
- String type;
- char ch;
- int consumed_chars; // Shadows global var
-
- brackets = new StringBuffer(); // Accumulate []'s
-
- // Count opening brackets and look for optional size argument
- for(n=0; signature.charAt(n) == '['; n++)
- brackets.append("[]");
-
- consumed_chars = n; // Remember value
-
- // The rest of the string denotes a `<field_type>'
- type = signatureToString(signature.substring(n), chopit);
+ StringBuffer brackets;
+ int consumedChars,n;
+
+ brackets = new StringBuffer(); // Accumulate []'s
+ // Count opening brackets and look for optional size argument
+ for(n=0; signature.charAt(n) == '['; n++)
+ brackets.append("[]");
+ consumedChars = n;
+ // The rest of the string denotes a `<field_type>'
+ ResultHolder restOfIt = signatureToStringInternal(signature.substring(n),chopit);
+
+ // type = signatureToString(signature.substring(n), chopit);
- Utility.consumed_chars += consumed_chars;
- return type + brackets.toString();
- }
+ consumedChars+= restOfIt.getConsumedChars();
+ return new ResultHolder(restOfIt.getResult() + brackets.toString(),consumedChars);
+ }
- case 'V' : return "void";
+ case 'V' : return ResultHolder.VOID;
default : throw new ClassFormatException("Invalid signature: `" +
signature + "'");
}
return null;
}
+
+ private static class ResultHolder {
+ private String result;
+ private int consumed;
+
+ public static final ResultHolder BYTE = new ResultHolder("byte",1);
+ public static final ResultHolder CHAR = new ResultHolder("char",1);
+ public static final ResultHolder DOUBLE = new ResultHolder("double",1);
+ public static final ResultHolder FLOAT = new ResultHolder("float",1);
+ public static final ResultHolder INT = new ResultHolder("int",1);
+ public static final ResultHolder LONG = new ResultHolder("long",1);
+ public static final ResultHolder SHORT = new ResultHolder("short",1);
+ public static final ResultHolder BOOLEAN = new ResultHolder("boolean",1);
+ public static final ResultHolder VOID = new ResultHolder("void",1);
+
+ public ResultHolder(String s,int c) {
+ result = s;
+ consumed = c;
+ }
+
+ public String getResult() { return result;}
+ public int getConsumedChars() { return consumed; }
+ }
+
}
import org.aspectj.apache.bcel.classfile.ClassFormatException;
import org.aspectj.apache.bcel.classfile.Utility;
+
/**
* Abstract super class for all possible java types, namely basic types
* such as int, object types like String and array types, e.g. int[]
*
- * @version $Id: Type.java,v 1.3 2004/11/22 08:31:27 aclement Exp $
+ * @version $Id: Type.java,v 1.4 2005/03/10 12:14:19 aclement Exp $
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ *
+ * modified:
+ * AndyClement 2-mar-05: Removed unnecessary static and optimized
*/
public abstract class Type implements java.io.Serializable {
protected byte type;
protected String signature; // signature for the type
- /** Predefined constants
- */
+ /* Predefined constants */
public static final BasicType VOID = new BasicType(Constants.T_VOID);
public static final BasicType BOOLEAN = new BasicType(Constants.T_BOOLEAN);
public static final BasicType INT = new BasicType(Constants.T_INT);
public static final ObjectType THROWABLE = new ObjectType("java.lang.Throwable");
public static final Type[] NO_ARGS = new Type[0];
public static final ReferenceType NULL = new ReferenceType(){};
- public static final Type UNKNOWN = new Type(Constants.T_UNKNOWN,
- "<unknown object>"){};
+ public static final Type UNKNOWN = new Type(Constants.T_UNKNOWN,"<unknown object>"){};
protected Type(byte t, String s) {
type = t;
*/
public int getSize() {
switch(type) {
- case Constants.T_DOUBLE:
- case Constants.T_LONG: return 2;
- case Constants.T_VOID: return 0;
- default: return 1;
+ case Constants.T_DOUBLE:
+ case Constants.T_LONG: return 2;
+ case Constants.T_VOID: return 0;
+ default: return 1;
}
}
/**
- * @return Type string, e.g. `int[]'
+ * @return Type string, e.g. 'int[]'
*/
public String toString() {
return ((this.equals(Type.NULL) || (type >= Constants.T_UNKNOWN)))? signature :
* @param arg_types what are the argument types
* @return method signature for given type(s).
*/
- public static String getMethodSignature(Type return_type, Type[] arg_types) {
+ public static String getMethodSignature(Type return_type, Type[] arg_types) {
StringBuffer buf = new StringBuffer("(");
int length = (arg_types == null)? 0 : arg_types.length;
for(int i=0; i < length; i++)
buf.append(arg_types[i].getSignature());
-
buf.append(')');
buf.append(return_type.getSignature());
-
+
return buf.toString();
}
- private static int consumed_chars=0; // Remember position in string, see getArgumentTypes
+ // private static int consumed_chars=0; // Remember position in string, see getArgumentTypes
+
+ public static final Type getType(String signature) {
+ TypeHolder th = getTypeInternal(signature);
+ return th.getType();
+ }
+
+
/**
* Convert signature to a Type object.
* @param signature signature string such as Ljava/lang/String;
* @return type object
*/
- public static final Type getType(String signature)
- throws StringIndexOutOfBoundsException
- {
+ public static final TypeHolder getTypeInternal(String signature) throws StringIndexOutOfBoundsException {
byte type = Utility.typeOfSignature(signature);
- if(type <= Constants.T_VOID) {
- consumed_chars = 1;
- return BasicType.getType(type);
- } else if(type == Constants.T_ARRAY) {
+ if (type <= Constants.T_VOID) {
+ return new TypeHolder(BasicType.getType(type),1);
+ } else if (type == Constants.T_ARRAY) {
int dim=0;
- do { // Count dimensions
- dim++;
- } while(signature.charAt(dim) == '[');
-
+ do { dim++; } while(signature.charAt(dim) == '[');
// Recurse, but just once, if the signature is ok
- Type t = getType(signature.substring(dim));
-
- consumed_chars += dim; // update counter
-
- return new ArrayType(t, dim);
+ TypeHolder th = getTypeInternal(signature.substring(dim));
+ return new TypeHolder(new ArrayType(th.getType(), dim),dim+th.getConsumed());
} else { // type == T_REFERENCE
+ // Format is 'Lblahblah;'
int index = signature.indexOf(';'); // Look for closing `;'
-
- if(index < 0)
- throw new ClassFormatException("Invalid signature: " + signature);
-
- consumed_chars = index + 1; // "Lblabla;" `L' and `;' are removed
-
- return new ObjectType(signature.substring(1, index).replace('/', '.'));
+ if(index < 0) throw new ClassFormatException("Invalid signature: " + signature);
+ return new TypeHolder(new ObjectType(signature.substring(1, index).replace('/', '.')),index+1);
}
}
Type[] types;
try { // Read all declarations between for `(' and `)'
- if(signature.charAt(0) != '(')
- throw new ClassFormatException("Invalid method signature: " + signature);
+ if (signature.charAt(0) != '(')
+ throw new ClassFormatException("Invalid method signature: " + signature);
index = 1; // current string position
while(signature.charAt(index) != ')') {
- vec.add(getType(signature.substring(index)));
- index += consumed_chars; // update position
+ TypeHolder th = getTypeInternal(signature.substring(index));
+ vec.add(th.getType());
+ index += th.getConsumed(); // update position
}
} catch(StringIndexOutOfBoundsException e) { // Should never occur
throw new ClassFormatException("Invalid method signature: " + signature);
throw new IllegalArgumentException("Class must not be null");
}
- /* That's an amzingly easy case, because getName() returns
+ /* That's an amazingly easy case, because getName() returns
* the signature. That's what we would have liked anyway.
*/
if(cl.isArray()) {
return new ObjectType(cl.getName());
}
}
-
+
public static String getSignature(java.lang.reflect.Method meth) {
StringBuffer sb = new StringBuffer("(");
Class[] params = meth.getParameterTypes(); // avoid clone
sb.append(getType(meth.getReturnType()).getSignature());
return sb.toString();
}
+
+ public static class TypeHolder {
+ private Type t;
+ private int consumed;
+
+ public Type getType() {return t;}
+ public int getConsumed() { return consumed;}
+
+ public TypeHolder(Type t,int i) { this.t=t;this.consumed = i;}
+ }
+
}