2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / libjava / gnu / java / lang / reflect / TypeSignature.java
blob1cf55a698e929b066a9cbd5a89c07ffd3d35a7a5
1 /* TypeSignature.java -- Class used to compute type signatures
2 Copyright (C) 1998, 2000, 2002, 2003 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package gnu.java.lang.reflect;
41 import java.lang.reflect.Constructor;
42 import java.lang.reflect.Field;
43 import java.lang.reflect.Member;
44 import java.lang.reflect.Method;
46 /**
47 * This class provides static methods that can be used to compute
48 * type-signatures of <code>Class</code>s or <code>Member</code>s.
49 * More specific methods are also provided for computing the
50 * type-signature of <code>Constructor</code>s and
51 * <code>Method</code>s. Methods are also provided to go in the
52 * reverse direction.
54 * @author Eric Blake <ebb9@email.byu.edu>
56 public class TypeSignature
58 /**
59 * Returns a <code>String</code> representing the type-encoding of a class.
60 * The .class file format has different encodings for classes, depending
61 * on whether it must be disambiguated from primitive types or not; hence
62 * the descriptor parameter to choose between them. If you are planning
63 * on decoding primitive types along with classes, then descriptor should
64 * be true for correct results. Type-encodings are computed as follows:
66 * <pre>
67 * boolean -> "Z"
68 * byte -> "B"
69 * char -> "C"
70 * double -> "D"
71 * float -> "F"
72 * int -> "I"
73 * long -> "J"
74 * short -> "S"
75 * void -> "V"
76 * arrays -> "[" + descriptor format of component type
77 * object -> class format: fully qualified name with '.' replaced by '/'
78 * descriptor format: "L" + class format + ";"
79 * </pre>
81 * @param type the class name to encode
82 * @param descriptor true to return objects in descriptor format
83 * @return the class name, as it appears in bytecode constant pools
84 * @see #getClassForEncoding(String)
86 public static String getEncodingOfClass(String type, boolean descriptor)
88 if (! descriptor || type.charAt(0) == '[')
89 return type.replace('.', '/');
90 if (type.equals("boolean"))
91 return "Z";
92 if (type.equals("byte"))
93 return "B";
94 if (type.equals("short"))
95 return "S";
96 if (type.equals("char"))
97 return "C";
98 if (type.equals("int"))
99 return "I";
100 if (type.equals("long"))
101 return "J";
102 if (type.equals("float"))
103 return "F";
104 if (type.equals("double"))
105 return "D";
106 if (type.equals("void"))
107 return "V";
108 return 'L' + type.replace('.', '/') + ';';
112 * Gets the descriptor encoding for a class.
114 * @param clazz the class to encode
115 * @param descriptor true to return objects in descriptor format
116 * @return the class name, as it appears in bytecode constant pools
117 * @see #getEncodingOfClass(String, boolean)
119 public static String getEncodingOfClass(Class clazz, boolean descriptor)
121 return getEncodingOfClass(clazz.getName(), descriptor);
125 * Gets the descriptor encoding for a class.
127 * @param clazz the class to encode
128 * @return the class name, as it appears in bytecode constant pools
129 * @see #getEncodingOfClass(String, boolean)
131 public static String getEncodingOfClass(Class clazz)
133 return getEncodingOfClass(clazz.getName(), true);
138 * This function is the inverse of <code>getEncodingOfClass</code>. This
139 * accepts both object and descriptor formats, but must know which style
140 * of string is being passed in (usually, descriptor should be true). In
141 * descriptor format, "I" is treated as int.class, in object format, it
142 * is treated as a class named I in the unnamed package.
144 * @param type_code the class name to decode
145 * @param descriptor if the string is in descriptor format
146 * @return the corresponding Class object
147 * @throws ClassNotFoundException if the class cannot be located
148 * @see #getEncodingOfClass(Class, boolean)
150 public static Class getClassForEncoding(String type_code, boolean descriptor)
151 throws ClassNotFoundException
153 return getClassForEncoding(type_code, descriptor, null);
157 * This function is the inverse of <code>getEncodingOfClass</code>. This
158 * accepts both object and descriptor formats, but must know which style
159 * of string is being passed in (usually, descriptor should be true).In
160 * descriptor format, "I" is treated as int.class, in object format, it
161 * is treated as a class named I in the unnamed package. It also
162 * accepts a <code>ClassLoader</code>, which is used to load the class.
164 * @param type_code the class name to decode
165 * @param descriptor if the string is in descriptor format
166 * @param loader the class loader used to load the class
167 * @return the corresponding Class object
168 * @throws ClassNotFoundException if the class cannot be located
169 * @see #getEncodingOfClass(Class, boolean)
170 * @see #getClassForEncoding(String, boolean)
172 public static Class getClassForEncoding(String type_code, boolean descriptor,
173 ClassLoader loader)
174 throws ClassNotFoundException
176 if (descriptor)
178 switch (type_code.charAt(0))
180 case 'B':
181 return byte.class;
182 case 'C':
183 return char.class;
184 case 'D':
185 return double.class;
186 case 'F':
187 return float.class;
188 case 'I':
189 return int.class;
190 case 'J':
191 return long.class;
192 case 'S':
193 return short.class;
194 case 'V':
195 return void.class;
196 case 'Z':
197 return boolean.class;
198 default:
199 throw new ClassNotFoundException("Invalid class name: "
200 + type_code);
201 case 'L':
202 type_code = type_code.substring(1, type_code.length() - 1);
203 // Fallthrough.
204 case '[':
207 return Class.forName(type_code.replace('/', '.'));
211 * Gets the Class object for a type name.
213 * @param type_code the class name to decode
214 * @return the corresponding Class object
215 * @throws ClassNotFoundException if the class cannot be located
216 * @see #getClassForEncoding(String, boolean)
218 public static Class getClassForEncoding(String type_code)
219 throws ClassNotFoundException
221 return getClassForEncoding(type_code, true);
225 * Returns a <code>String</code> representing the type-encoding of a
226 * method. The type-encoding of a method is:
228 * "(" + parameter type descriptors + ")" + return type descriptor
230 * XXX This could be faster if it were implemented natively.
232 * @param m the method to encode
233 * @return the encoding
235 public static String getEncodingOfMethod(Method m)
237 Class[] paramTypes = m.getParameterTypes();
238 StringBuffer buf = new StringBuffer().append('(');
239 for (int i = 0; i < paramTypes.length; i++)
240 buf.append(getEncodingOfClass(paramTypes[i].getName(), true));
241 buf.append(')').append(getEncodingOfClass(m.getReturnType().getName(),
242 true));
243 return buf.toString();
247 * Returns a <code>String</code> representing the type-encoding of a
248 * constructor. The type-encoding of a method is:
250 * "(" + parameter type descriptors + ")V"
252 * XXX This could be faster if it were implemented natively.
254 * @param c the constructor to encode
255 * @return the encoding
257 public static String getEncodingOfConstructor(Constructor c)
259 Class[] paramTypes = c.getParameterTypes();
260 StringBuffer buf = new StringBuffer().append('(');
261 for (int i = 0; i < paramTypes.length; i++)
262 buf.append(getEncodingOfClass(paramTypes[i].getName(), true));
263 buf.append(")V");
264 return buf.toString();
268 * Returns a <code>String</code> representing the type-encoding of a
269 * class member. This appropriately handles Constructors, Methods, and
270 * Fields.
272 * @param mem the member to encode
273 * @return the encoding
275 public static String getEncodingOfMember(Member mem)
277 if (mem instanceof Constructor)
278 return getEncodingOfConstructor((Constructor) mem);
279 if (mem instanceof Method)
280 return getEncodingOfMethod((Method) mem);
281 else // Field
282 return getEncodingOfClass(((Field) mem).getType().getName(), true);
284 } // class TypeSignature