Main Page   Packages   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

Type.java

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  * Abstract super class for all possible java types, namely basic types
00010  * such as int, object types like String and array types, e.g. int[]
00011  *
00012  * @version $Id: Type.java,v 1.1.1.1 2002/01/24 03:44:02 pserver Exp $
00013  * @author  <A HREF="http://www.inf.fu-berlin.de/~dahm">M. Dahm</A>
00014  */
00015 public abstract class Type implements Constants {
00016   protected byte   type;
00017   protected String signature; // signature for the type
00018 
00019   /** Predefined constants
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; // Remember position in string, see getArgumentTypes
00037 
00038   protected Type(byte t, String s) {
00039     type      = t;
00040     signature = s;
00041   }  
00042   /**
00043    * Convert arguments of a method (signature) to an array of Type objects.
00044    * @param signature signature string such as (Ljava/lang/String;)V
00045    * @return array of argument types
00046    */
00047   public static Type[] getArgumentTypes(String signature) {
00048     Vector vec = new Vector();
00049     int    index;
00050     Type[] types;
00051 
00052     try { // Read all declarations between for `(' and `)'
00053       if(signature.charAt(0) != '(')
00054     throw new ClassFormatError("Invalid method signature: " + signature);
00055 
00056       index = 1; // current string position
00057 
00058       while(signature.charAt(index) != ')') {
00059     vec.addElement(getType(signature.substring(index)));
00060     index += consumed_chars; // update position
00061       }
00062     } catch(StringIndexOutOfBoundsException e) { // Should never occur
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    * Convert type to Java method signature, e.g. int[] f(java.lang.String x)
00072    * becomes (Ljava/lang/String;)[I
00073    *
00074    * @param return_type what the method returns
00075    * @param arg_types what are the argument types
00076    * @return method signature for given type(s).
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    * Convert arguments of a method (signature) to a Type object.
00092    * @param signature signature string such as (Ljava/lang/String;)V
00093    * @return return type
00094    */
00095   public static Type getReturnType(String signature) {
00096     try {
00097       // Read return type after `)'
00098       int index = signature.lastIndexOf(')') + 1;
00099       return getType(signature.substring(index));
00100     } catch(StringIndexOutOfBoundsException e) { // Should never occur
00101       throw new ClassFormatError("Invalid method signature: " + signature);
00102     }
00103   }  
00104   /**
00105    * @return signature for given type.
00106    */
00107   public String getSignature() { return signature; }  
00108   /**
00109    * @return stack size of this type (2 for long and double, 0 for void, 1 otherwise)
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    * @return type as defined in Constants
00121    */
00122   public byte getType() { return type; }  
00123   /**
00124    * Convert signature to a Type object.
00125    * @param signature signature string such as Ljava/lang/String;
00126    * @return type object
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 { // Count dimensions
00140     dim++;
00141       } while(signature.charAt(dim) == '[');
00142 
00143       // Recurse, but just once, if the signature is ok
00144       Type t = getType(signature.substring(dim));
00145 
00146       consumed_chars += dim; // update counter
00147 
00148       return new ArrayType(t, dim);
00149     }
00150     else { // type == T_REFERENCE
00151       int index = signature.indexOf(';'); // Look for closing `;'
00152 
00153       if(index < 0)
00154     throw new ClassFormatError("Invalid signature: " + signature);
00155     
00156       consumed_chars = index + 1; // "Lblabla;" `L' and `;' are removed
00157 
00158       return new ObjectType(signature.substring(1, index).replace('/', '.'));
00159     }
00160   }  
00161   /**
00162    * @return Type string, e.g. `int[]'
00163    */
00164   public String toString() { return Utility.signatureToString(signature, false); }  
00165 }

Generated at Thu Feb 7 06:58:37 2002 for Bandera by doxygen1.2.10 written by Dimitri van Heesch, © 1997-2001