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 {
00016 protected byte type;
00017 protected String signature;
00018
00019
00020
00021 public static final BasicType VOID = new BasicType(Constants.T_VOID);
00022 public static final BasicType BOOLEAN = new BasicType(Constants.T_BOOLEAN);
00023 public static final BasicType INT = new BasicType(Constants.T_INT);
00024 public static final BasicType SHORT = new BasicType(Constants.T_SHORT);
00025 public static final BasicType BYTE = new BasicType(Constants.T_BYTE);
00026 public static final BasicType LONG = new BasicType(Constants.T_LONG);
00027 public static final BasicType DOUBLE = new BasicType(Constants.T_DOUBLE);
00028 public static final BasicType FLOAT = new BasicType(Constants.T_FLOAT);
00029 public static final BasicType CHAR = new BasicType(Constants.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 public static final Type UNKNOWN = new Type(Constants.T_UNKNOWN,
00036 "<unknown object>"){};
00037 public static final Type ADDRESS = new Type(Constants.T_ADDRESS,
00038 "<address>"){};
00039
00040 private static int consumed_chars=0;
00041
00042 protected Type(byte t, String s) {
00043 type = t;
00044 signature = s;
00045 }
00046
00047
00048
00049
00050
00051 public static synchronized Type[] getArgumentTypes(String signature) {
00052 Vector vec = new Vector();
00053 int index;
00054 Type[] types;
00055
00056 try {
00057 if(signature.charAt(0) != '(')
00058 throw new ClassFormatError("Invalid method signature: " + signature);
00059
00060 index = 1;
00061
00062 while(signature.charAt(index) != ')') {
00063 vec.addElement(getType(signature.substring(index)));
00064 index += consumed_chars;
00065 }
00066 } catch(StringIndexOutOfBoundsException e) {
00067 throw new ClassFormatError("Invalid method signature: " + signature);
00068 }
00069
00070 types = new Type[vec.size()];
00071 vec.copyInto(types);
00072 return types;
00073 }
00074
00075
00076
00077
00078
00079
00080
00081
00082 public static String getMethodSignature(Type return_type, Type[] arg_types) {
00083 StringBuffer buf = new StringBuffer("(");
00084 int length = (arg_types == null)? 0 : arg_types.length;
00085
00086 for(int i=0; i < length; i++)
00087 buf.append(arg_types[i].getSignature());
00088
00089 buf.append(')');
00090 buf.append(return_type.getSignature());
00091
00092 return buf.toString();
00093 }
00094
00095
00096
00097
00098
00099 public static Type getReturnType(String signature) {
00100 try {
00101
00102 int index = signature.lastIndexOf(')') + 1;
00103 return getType(signature.substring(index));
00104 } catch(StringIndexOutOfBoundsException e) {
00105 throw new ClassFormatError("Invalid method signature: " + signature);
00106 }
00107 }
00108
00109
00110
00111 public String getSignature() { return signature; }
00112
00113
00114
00115 public int getSize() {
00116 switch(type) {
00117 case Constants.T_DOUBLE:
00118 case Constants.T_LONG: return 2;
00119 case Constants.T_VOID: return 0;
00120 default: return 1;
00121 }
00122 }
00123
00124
00125
00126 public byte getType() { return type; }
00127
00128
00129
00130
00131
00132 public static synchronized final Type getType(String signature)
00133 throws StringIndexOutOfBoundsException
00134 {
00135 byte type = Utility.typeOfSignature(signature);
00136
00137 if(type <= Constants.T_VOID) {
00138 consumed_chars = 1;
00139 return BasicType.getType(type);
00140 }
00141 else if(type == Constants.T_ARRAY) {
00142 int dim=0;
00143 do {
00144 dim++;
00145 } while(signature.charAt(dim) == '[');
00146
00147
00148 Type t = getType(signature.substring(dim));
00149
00150 consumed_chars += dim;
00151
00152 return new ArrayType(t, dim);
00153 }
00154 else {
00155 int index = signature.indexOf(';');
00156
00157 if(index < 0)
00158 throw new ClassFormatError("Invalid signature: " + signature);
00159
00160 consumed_chars = index + 1;
00161
00162 return new ObjectType(signature.substring(1, index).replace('/', '.'));
00163 }
00164 }
00165
00166
00167
00168 public String toString() {
00169 return (type >= Constants.T_UNKNOWN)? signature :
00170 Utility.signatureToString(signature, false);
00171 }
00172 }