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