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