00001 package de.fub.bytecode.generic;
00002
00003 import de.fub.bytecode.Constants;
00004 import de.fub.bytecode.classfile.*;
00005 import java.io.*;
00006 import java.util.Vector;
00007
00008
00009
00010
00011
00012
00013
00014
00015 public abstract class Type implements Constants {
00016 protected byte type;
00017 protected String signature;
00018
00019
00020
00021 public static final BasicType VOID = new BasicType(T_VOID);
00022 public static final BasicType BOOLEAN = new BasicType(T_BOOLEAN);
00023 public static final BasicType INT = new BasicType(T_INT);
00024 public static final BasicType SHORT = new BasicType(T_SHORT);
00025 public static final BasicType BYTE = new BasicType(T_BYTE);
00026 public static final BasicType LONG = new BasicType(T_LONG);
00027 public static final BasicType DOUBLE = new BasicType(T_DOUBLE);
00028 public static final BasicType FLOAT = new BasicType(T_FLOAT);
00029 public static final BasicType CHAR = new BasicType(T_CHAR);
00030 public static final ObjectType OBJECT = new ObjectType("java.lang.Object");
00031 public static final ObjectType STRING = new ObjectType("java.lang.String");
00032 public static final ObjectType STRINGBUFFER = new ObjectType("java.lang.StringBuffer");
00033 public static final Type[] NO_ARGS = new Type[0];
00034 public static final ReferenceType NULL = new ReferenceType();
00035
00036 private static int consumed_chars=0;
00037
00038 protected Type(byte t, String s) {
00039 type = t;
00040 signature = s;
00041 }
00042
00043
00044
00045
00046
00047 public static Type[] getArgumentTypes(String signature) {
00048 Vector vec = new Vector();
00049 int index;
00050 Type[] types;
00051
00052 try {
00053 if(signature.charAt(0) != '(')
00054 throw new ClassFormatError("Invalid method signature: " + signature);
00055
00056 index = 1;
00057
00058 while(signature.charAt(index) != ')') {
00059 vec.addElement(getType(signature.substring(index)));
00060 index += consumed_chars;
00061 }
00062 } catch(StringIndexOutOfBoundsException e) {
00063 throw new ClassFormatError("Invalid method signature: " + signature);
00064 }
00065
00066 types = new Type[vec.size()];
00067 vec.copyInto(types);
00068 return types;
00069 }
00070
00071
00072
00073
00074
00075
00076
00077
00078 public static String getMethodSignature(Type return_type, Type[] arg_types) {
00079 StringBuffer buf = new StringBuffer("(");
00080 int length = (arg_types == null)? 0 : arg_types.length;
00081
00082 for(int i=0; i < length; i++)
00083 buf.append(arg_types[i].getSignature());
00084
00085 buf.append(')');
00086 buf.append(return_type.getSignature());
00087
00088 return buf.toString();
00089 }
00090
00091
00092
00093
00094
00095 public static Type getReturnType(String signature) {
00096 try {
00097
00098 int index = signature.lastIndexOf(')') + 1;
00099 return getType(signature.substring(index));
00100 } catch(StringIndexOutOfBoundsException e) {
00101 throw new ClassFormatError("Invalid method signature: " + signature);
00102 }
00103 }
00104
00105
00106
00107 public String getSignature() { return signature; }
00108
00109
00110
00111 public int getSize() {
00112 switch(type) {
00113 case T_DOUBLE:
00114 case T_LONG: return 2;
00115 case T_VOID: return 0;
00116 default: return 1;
00117 }
00118 }
00119
00120
00121
00122 public byte getType() { return type; }
00123
00124
00125
00126
00127
00128 public static final Type getType(String signature)
00129 throws StringIndexOutOfBoundsException
00130 {
00131 byte type = Utility.typeOfSignature(signature);
00132
00133 if(type <= T_VOID) {
00134 consumed_chars = 1;
00135 return BasicType.getType(type);
00136 }
00137 else if(type == T_ARRAY) {
00138 int dim=0;
00139 do {
00140 dim++;
00141 } while(signature.charAt(dim) == '[');
00142
00143
00144 Type t = getType(signature.substring(dim));
00145
00146 consumed_chars += dim;
00147
00148 return new ArrayType(t, dim);
00149 }
00150 else {
00151 int index = signature.indexOf(';');
00152
00153 if(index < 0)
00154 throw new ClassFormatError("Invalid signature: " + signature);
00155
00156 consumed_chars = index + 1;
00157
00158 return new ObjectType(signature.substring(1, index).replace('/', '.'));
00159 }
00160 }
00161
00162
00163
00164 public String toString() { return Utility.signatureToString(signature, false); }
00165 }