    View Javadoc
    1   package org.apache.bcel.generic;
    2
    3   /* ====================================================================
    4    * The Apache Software License, Version 1.1
    5    *
    6    * Copyright (c) 2001 The Apache Software Foundation.  All rights
    7    * reserved.
    8    *
    9    * Redistribution and use in source and binary forms, with or without
    10   * modification, are permitted provided that the following conditions
    11   * are met:
    12   *
    13   * 1. Redistributions of source code must retain the above copyright
    14   *    notice, this list of conditions and the following disclaimer.
    15   *
    16   * 2. Redistributions in binary form must reproduce the above copyright
    17   *    notice, this list of conditions and the following disclaimer in
    18   *    the documentation and/or other materials provided with the
    19   *    distribution.
    20   *
    21   * 3. The end-user documentation included with the redistribution,
    22   *    if any, must include the following acknowledgment:
    23   *       "This product includes software developed by the
    24   *        Apache Software Foundation (http://www.apache.org/)."
    25   *    Alternately, this acknowledgment may appear in the software itself,
    26   *    if and wherever such third-party acknowledgments normally appear.
    27   *
    28   * 4. The names "Apache" and "Apache Software Foundation" and
    29   *    "Apache BCEL" must not be used to endorse or promote products
    30   *    derived from this software without prior written permission. For
    31   *    written permission, please contact apache@apache.org.
    32   *
    33   * 5. Products derived from this software may not be called "Apache",
    34   *    "Apache BCEL", nor may "Apache" appear in their name, without
    35   *    prior written permission of the Apache Software Foundation.
    36   *
    37   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
    38   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    39   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    40   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
    41   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    42   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    43   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
    44   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    45   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
    46   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
    47   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    48   * SUCH DAMAGE.
    49   * ====================================================================
    50   *
    51   * This software consists of voluntary contributions made by many
    52   * individuals on behalf of the Apache Software Foundation.  For more
    53   * information on the Apache Software Foundation, please see
    54   * <http://www.apache.org/>;.
    55   */
    56
    57  import org.apache.bcel.Constants;
    58  import org.apache.bcel.classfile.*;
    59  import java.util.ArrayList;
    60
    61  /***
    62   * Abstract super class for all possible java types, namely basic types
    63   * such as int, object types like String and array types, e.g. int[]
    64   *
    65   * @version $Id: Type.java,v 1.8 2002/08/07 18:01:32 mdahm Exp $
    66   * @author  <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
    67   */
    68  public abstract class Type implements java.io.Serializable {
    69    protected byte   type;
    70    protected String signature; // signature for the type
    71
    72    /*** Predefined constants
    73     */
    74    public static final BasicType     VOID         = new BasicType(Constants.T_VOID);
    75    public static final BasicType     BOOLEAN      = new BasicType(Constants.T_BOOLEAN);
    76    public static final BasicType     INT          = new BasicType(Constants.T_INT);
    77    public static final BasicType     SHORT        = new BasicType(Constants.T_SHORT);
    78    public static final BasicType     BYTE         = new BasicType(Constants.T_BYTE);
    79    public static final BasicType     LONG         = new BasicType(Constants.T_LONG);
    80    public static final BasicType     DOUBLE       = new BasicType(Constants.T_DOUBLE);
    81    public static final BasicType     FLOAT        = new BasicType(Constants.T_FLOAT);
    82    public static final BasicType     CHAR         = new BasicType(Constants.T_CHAR);
    83    public static final ObjectType    OBJECT       = new ObjectType("java.lang.Object");
    84    public static final ObjectType    STRING       = new ObjectType("java.lang.String");
    85    public static final ObjectType    STRINGBUFFER = new ObjectType("java.lang.StringBuffer");
    86    public static final ObjectType    THROWABLE    = new ObjectType("java.lang.Throwable");
    87    public static final Type[]        NO_ARGS      = new Type[0];
    88    public static final ReferenceType NULL         = new ReferenceType(){};
    89    public static final Type          UNKNOWN      = new Type(Constants.T_UNKNOWN,
    90  							    "<unknown object>"){};
    91
    92    protected Type(byte t, String s) {
    93      type      = t;
    94      signature = s;
    95    }
    96
    97    /***
    98     * @return signature for given type.
    99     */
    100   public String getSignature() { return signature; }
    101
    102   /***
    103    * @return type as defined in Constants
    104    */
    105   public byte getType() { return type; }
    106
    107   /***
    108    * @return stack size of this type (2 for long and double, 0 for void, 1 otherwise)
    109    */
    110   public int getSize() {
    111     switch(type) {
    112     case Constants.T_DOUBLE:
    113     case Constants.T_LONG: return 2;
    114     case Constants.T_VOID: return 0;
    115     default:     return 1;
    116     }
    117   }
    118
    119   /***
    120    * @return Type string, e.g. `int[]'
    121    */
    122   public String toString() {
    123     return ((this.equals(Type.NULL) || (type >= Constants.T_UNKNOWN)))? signature :
    124       Utility.signatureToString(signature, false);
    125   }
    126
    127   /***
    128    * Convert type to Java method signature, e.g. int[] f(java.lang.String x)
    129    * becomes (Ljava/lang/String;)[I
    130    *
    131    * @param return_type what the method returns
    132    * @param arg_types what are the argument types
    133    * @return method signature for given type(s).
    134    */
    135   public static String getMethodSignature(Type return_type, Type[] arg_types) {
    136     StringBuffer buf = new StringBuffer("(");
    137     int length = (arg_types == null)? 0 : arg_types.length;
    138
    139     for(int i=0; i < length; i++)
    140       buf.append(arg_types[i].getSignature());
    141
    142     buf.append(')');
    143     buf.append(return_type.getSignature());
    144
    145     return buf.toString();
    146   }
    147
    148   private static int consumed_chars=0; // Remember position in string, see getArgumentTypes
    149
    150   /***
    151    * Convert signature to a Type object.
    152    * @param signature signature string such as Ljava/lang/String;
    153    * @return type object
    154    */
    155   public static final Type getType(String signature)
    156     throws StringIndexOutOfBoundsException
    157   {
    158     byte type = Utility.typeOfSignature(signature);
    159
    160     if(type <= Constants.T_VOID) {
    161       consumed_chars = 1;
    162       return BasicType.getType(type);
    163     } else if(type == Constants.T_ARRAY) {
    164       int dim=0;
    165       do { // Count dimensions
    166 	dim++;
    167       } while(signature.charAt(dim) == '[');
    168
    169       // Recurse, but just once, if the signature is ok
    170       Type t = getType(signature.substring(dim));
    171
    172       consumed_chars += dim; // update counter
    173
    174       return new ArrayType(t, dim);
    175     } else { // type == T_REFERENCE
    176       int index = signature.indexOf(';'); // Look for closing `;'
    177
    178       if(index < 0)
    179 	throw new ClassFormatException("Invalid signature: " + signature);
    180
    181       consumed_chars = index + 1; // "Lblabla;" `L' and `;' are removed
    182
    183       return new ObjectType(signature.substring(1, index).replace('/', '.'));
    184     }
    185   }
    186
    187   /***
    188    * Convert return value of a method (signature) to a Type object.
    189    *
    190    * @param signature signature string such as (Ljava/lang/String;)V
    191    * @return return type
    192    */
    193   public static Type getReturnType(String signature) {
    194     try {
    195       // Read return type after `)'
    196       int index = signature.lastIndexOf(')') + 1;
    197       return getType(signature.substring(index));
    198     } catch(StringIndexOutOfBoundsException e) { // Should never occur
    199       throw new ClassFormatException("Invalid method signature: " + signature);
    200     }
    201   }
    202
    203   /***
    204    * Convert arguments of a method (signature) to an array of Type objects.
    205    * @param signature signature string such as (Ljava/lang/String;)V
    206    * @return array of argument types
    207    */
    208   public static Type[] getArgumentTypes(String signature) {
    209     ArrayList vec = new ArrayList();
    210     int       index;
    211     Type[]     types;
    212
    213     try { // Read all declarations between for `(' and `)'
    214       if(signature.charAt(0) != '(')
    215 	throw new ClassFormatException("Invalid method signature: " + signature);
    216
    217       index = 1; // current string position
    218
    219       while(signature.charAt(index) != ')') {
    220 	vec.add(getType(signature.substring(index)));
    221 	index += consumed_chars; // update position
    222       }
    223     } catch(StringIndexOutOfBoundsException e) { // Should never occur
    224       throw new ClassFormatException("Invalid method signature: " + signature);
    225     }
    226
    227     types = new Type[vec.size()];
    228     vec.toArray(types);
    229     return types;
    230   }
    231
    232   /*** Convert runtime java.lang.Class to BCEL Type object.
    233    * @param cl Java class
    234    * @return corresponding Type object
    235    */
    236   public static Type getType(java.lang.Class cl) {
    237     if(cl == null) {
    238       throw new IllegalArgumentException("Class must not be null");
    239     }
    240
    241     /* That's an amzingly easy case, because getName() returns
    242      * the signature. That's what we would have liked anyway.
    243      */
    244     if(cl.isArray()) {
    245       return getType(cl.getName());
    246     } else if(cl.isPrimitive()) {
    247       if(cl == Integer.TYPE) {
    248 	return INT;
    249       } else if(cl == Void.TYPE) {
    250 	return VOID;
    251       } else if(cl == Double.TYPE) {
    252 	return DOUBLE;
    253       } else if(cl == Float.TYPE) {
    254 	return FLOAT;
    255       } else if(cl == Boolean.TYPE) {
    256 	return BOOLEAN;
    257       } else if(cl == Byte.TYPE) {
    258 	return BYTE;
    259       } else if(cl == Short.TYPE) {
    260 	return SHORT;
    261       } else if(cl == Byte.TYPE) {
    262 	return BYTE;
    263       } else if(cl == Long.TYPE) {
    264 	return LONG;
    265       } else if(cl == Character.TYPE) {
    266 	return CHAR;
    267       } else {
    268 	throw new IllegalStateException("Ooops, what primitive type is " + cl);
    269       }
    270     } else { // "Real" class
    271       return new ObjectType(cl.getName());
    272     }
    273   }
    274
    275   public static String getSignature(java.lang.reflect.Method meth) {
    276     StringBuffer sb = new StringBuffer("(");
    277     Class[] params = meth.getParameterTypes(); // avoid clone
    278
    279     for(int j = 0; j < params.length; j++) {
    280       sb.append(getType(params[j]).getSignature());
    281     }
    282
    283     sb.append(")");
    284     sb.append(getType(meth.getReturnType()).getSignature());
    285     return sb.toString();
    286   }
    287 }

This page was automatically generated by Maven