Mercurial > lasercutter
diff src/clojure/asm/Type.java @ 10:ef7dbbd6452c
added clojure source goodness
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 21 Aug 2010 06:25:44 -0400 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/clojure/asm/Type.java Sat Aug 21 06:25:44 2010 -0400 1.3 @@ -0,0 +1,872 @@ 1.4 +/*** 1.5 + * ASM: a very small and fast Java bytecode manipulation framework 1.6 + * Copyright (c) 2000-2005 INRIA, France Telecom 1.7 + * All rights reserved. 1.8 + * 1.9 + * Redistribution and use in source and binary forms, with or without 1.10 + * modification, are permitted provided that the following conditions 1.11 + * are met: 1.12 + * 1. Redistributions of source code must retain the above copyright 1.13 + * notice, this list of conditions and the following disclaimer. 1.14 + * 2. Redistributions in binary form must reproduce the above copyright 1.15 + * notice, this list of conditions and the following disclaimer in the 1.16 + * documentation and/or other materials provided with the distribution. 1.17 + * 3. Neither the name of the copyright holders nor the names of its 1.18 + * contributors may be used to endorse or promote products derived from 1.19 + * this software without specific prior written permission. 1.20 + * 1.21 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 1.22 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1.23 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1.24 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 1.25 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 1.26 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 1.27 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 1.28 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 1.29 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 1.30 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 1.31 + * THE POSSIBILITY OF SUCH DAMAGE. 1.32 + */ 1.33 +package clojure.asm; 1.34 + 1.35 +import java.lang.reflect.Constructor; 1.36 +import java.lang.reflect.Method; 1.37 + 1.38 +/** 1.39 + * A Java type. This class can be used to make it easier to manipulate type and 1.40 + * method descriptors. 1.41 + * 1.42 + * @author Eric Bruneton 1.43 + * @author Chris Nokleberg 1.44 + */ 1.45 +public class Type{ 1.46 + 1.47 +/** 1.48 + * The sort of the <tt>void</tt> type. See {@link #getSort getSort}. 1.49 + */ 1.50 +public final static int VOID = 0; 1.51 + 1.52 +/** 1.53 + * The sort of the <tt>boolean</tt> type. See {@link #getSort getSort}. 1.54 + */ 1.55 +public final static int BOOLEAN = 1; 1.56 + 1.57 +/** 1.58 + * The sort of the <tt>char</tt> type. See {@link #getSort getSort}. 1.59 + */ 1.60 +public final static int CHAR = 2; 1.61 + 1.62 +/** 1.63 + * The sort of the <tt>byte</tt> type. See {@link #getSort getSort}. 1.64 + */ 1.65 +public final static int BYTE = 3; 1.66 + 1.67 +/** 1.68 + * The sort of the <tt>short</tt> type. See {@link #getSort getSort}. 1.69 + */ 1.70 +public final static int SHORT = 4; 1.71 + 1.72 +/** 1.73 + * The sort of the <tt>int</tt> type. See {@link #getSort getSort}. 1.74 + */ 1.75 +public final static int INT = 5; 1.76 + 1.77 +/** 1.78 + * The sort of the <tt>float</tt> type. See {@link #getSort getSort}. 1.79 + */ 1.80 +public final static int FLOAT = 6; 1.81 + 1.82 +/** 1.83 + * The sort of the <tt>long</tt> type. See {@link #getSort getSort}. 1.84 + */ 1.85 +public final static int LONG = 7; 1.86 + 1.87 +/** 1.88 + * The sort of the <tt>double</tt> type. See {@link #getSort getSort}. 1.89 + */ 1.90 +public final static int DOUBLE = 8; 1.91 + 1.92 +/** 1.93 + * The sort of array reference types. See {@link #getSort getSort}. 1.94 + */ 1.95 +public final static int ARRAY = 9; 1.96 + 1.97 +/** 1.98 + * The sort of object reference type. See {@link #getSort getSort}. 1.99 + */ 1.100 +public final static int OBJECT = 10; 1.101 + 1.102 +/** 1.103 + * The <tt>void</tt> type. 1.104 + */ 1.105 +public final static Type VOID_TYPE = new Type(VOID); 1.106 + 1.107 +/** 1.108 + * The <tt>boolean</tt> type. 1.109 + */ 1.110 +public final static Type BOOLEAN_TYPE = new Type(BOOLEAN); 1.111 + 1.112 +/** 1.113 + * The <tt>char</tt> type. 1.114 + */ 1.115 +public final static Type CHAR_TYPE = new Type(CHAR); 1.116 + 1.117 +/** 1.118 + * The <tt>byte</tt> type. 1.119 + */ 1.120 +public final static Type BYTE_TYPE = new Type(BYTE); 1.121 + 1.122 +/** 1.123 + * The <tt>short</tt> type. 1.124 + */ 1.125 +public final static Type SHORT_TYPE = new Type(SHORT); 1.126 + 1.127 +/** 1.128 + * The <tt>int</tt> type. 1.129 + */ 1.130 +public final static Type INT_TYPE = new Type(INT); 1.131 + 1.132 +/** 1.133 + * The <tt>float</tt> type. 1.134 + */ 1.135 +public final static Type FLOAT_TYPE = new Type(FLOAT); 1.136 + 1.137 +/** 1.138 + * The <tt>long</tt> type. 1.139 + */ 1.140 +public final static Type LONG_TYPE = new Type(LONG); 1.141 + 1.142 +/** 1.143 + * The <tt>double</tt> type. 1.144 + */ 1.145 +public final static Type DOUBLE_TYPE = new Type(DOUBLE); 1.146 + 1.147 +// ------------------------------------------------------------------------ 1.148 +// Fields 1.149 +// ------------------------------------------------------------------------ 1.150 + 1.151 +/** 1.152 + * The sort of this Java type. 1.153 + */ 1.154 +private final int sort; 1.155 + 1.156 +/** 1.157 + * A buffer containing the descriptor of this Java type. This field is only 1.158 + * used for reference types. 1.159 + */ 1.160 +private char[] buf; 1.161 + 1.162 +/** 1.163 + * The offset of the descriptor of this Java type in {@link #buf buf}. This 1.164 + * field is only used for reference types. 1.165 + */ 1.166 +private int off; 1.167 + 1.168 +/** 1.169 + * The length of the descriptor of this Java type. 1.170 + */ 1.171 +private int len; 1.172 + 1.173 +// ------------------------------------------------------------------------ 1.174 +// Constructors 1.175 +// ------------------------------------------------------------------------ 1.176 + 1.177 +/** 1.178 + * Constructs a primitive type. 1.179 + * 1.180 + * @param sort the sort of the primitive type to be constructed. 1.181 + */ 1.182 +private Type(final int sort){ 1.183 + this.sort = sort; 1.184 + this.len = 1; 1.185 +} 1.186 + 1.187 +/** 1.188 + * Constructs a reference type. 1.189 + * 1.190 + * @param sort the sort of the reference type to be constructed. 1.191 + * @param buf a buffer containing the descriptor of the previous type. 1.192 + * @param off the offset of this descriptor in the previous buffer. 1.193 + * @param len the length of this descriptor. 1.194 + */ 1.195 +private Type(final int sort, final char[] buf, final int off, final int len){ 1.196 + this.sort = sort; 1.197 + this.buf = buf; 1.198 + this.off = off; 1.199 + this.len = len; 1.200 +} 1.201 + 1.202 +/** 1.203 + * Returns the Java type corresponding to the given type descriptor. 1.204 + * 1.205 + * @param typeDescriptor a type descriptor. 1.206 + * @return the Java type corresponding to the given type descriptor. 1.207 + */ 1.208 +public static Type getType(final String typeDescriptor){ 1.209 + return getType(typeDescriptor.toCharArray(), 0); 1.210 +} 1.211 + 1.212 +/** 1.213 + * Returns the Java type corresponding to the given class. 1.214 + * 1.215 + * @param c a class. 1.216 + * @return the Java type corresponding to the given class. 1.217 + */ 1.218 +public static Type getType(final Class c){ 1.219 + if(c.isPrimitive()) 1.220 + { 1.221 + if(c == Integer.TYPE) 1.222 + { 1.223 + return INT_TYPE; 1.224 + } 1.225 + else if(c == Void.TYPE) 1.226 + { 1.227 + return VOID_TYPE; 1.228 + } 1.229 + else if(c == Boolean.TYPE) 1.230 + { 1.231 + return BOOLEAN_TYPE; 1.232 + } 1.233 + else if(c == Byte.TYPE) 1.234 + { 1.235 + return BYTE_TYPE; 1.236 + } 1.237 + else if(c == Character.TYPE) 1.238 + { 1.239 + return CHAR_TYPE; 1.240 + } 1.241 + else if(c == Short.TYPE) 1.242 + { 1.243 + return SHORT_TYPE; 1.244 + } 1.245 + else if(c == Double.TYPE) 1.246 + { 1.247 + return DOUBLE_TYPE; 1.248 + } 1.249 + else if(c == Float.TYPE) 1.250 + { 1.251 + return FLOAT_TYPE; 1.252 + } 1.253 + else /* if (c == Long.TYPE) */ 1.254 + { 1.255 + return LONG_TYPE; 1.256 + } 1.257 + } 1.258 + else 1.259 + { 1.260 + return getType(getDescriptor(c)); 1.261 + } 1.262 +} 1.263 + 1.264 +/** 1.265 + * Returns the {@link Type#OBJECT} type for the given internal class name. 1.266 + * This is a shortcut method for <code>Type.getType("L"+name+";")</code>. 1.267 + * <i>Note that opposed to {@link Type#getType(String)}, this method takes 1.268 + * internal class names and not class descriptor.</i> 1.269 + * 1.270 + * @param name an internal class name. 1.271 + * @return the the {@link Type#OBJECT} type for the given class name. 1.272 + */ 1.273 +public static Type getObjectType(String name){ 1.274 + int l = name.length(); 1.275 + char[] buf = new char[l + 2]; 1.276 + buf[0] = 'L'; 1.277 + buf[l + 1] = ';'; 1.278 + name.getChars(0, l, buf, 1); 1.279 + return new Type(OBJECT, buf, 0, l + 2); 1.280 +} 1.281 + 1.282 +/** 1.283 + * Returns the Java types corresponding to the argument types of the given 1.284 + * method descriptor. 1.285 + * 1.286 + * @param methodDescriptor a method descriptor. 1.287 + * @return the Java types corresponding to the argument types of the given 1.288 + * method descriptor. 1.289 + */ 1.290 +public static Type[] getArgumentTypes(final String methodDescriptor){ 1.291 + char[] buf = methodDescriptor.toCharArray(); 1.292 + int off = 1; 1.293 + int size = 0; 1.294 + while(true) 1.295 + { 1.296 + char car = buf[off++]; 1.297 + if(car == ')') 1.298 + { 1.299 + break; 1.300 + } 1.301 + else if(car == 'L') 1.302 + { 1.303 + while(buf[off++] != ';') 1.304 + { 1.305 + } 1.306 + ++size; 1.307 + } 1.308 + else if(car != '[') 1.309 + { 1.310 + ++size; 1.311 + } 1.312 + } 1.313 + Type[] args = new Type[size]; 1.314 + off = 1; 1.315 + size = 0; 1.316 + while(buf[off] != ')') 1.317 + { 1.318 + args[size] = getType(buf, off); 1.319 + off += args[size].len; 1.320 + size += 1; 1.321 + } 1.322 + return args; 1.323 +} 1.324 + 1.325 +/** 1.326 + * Returns the Java types corresponding to the argument types of the given 1.327 + * method. 1.328 + * 1.329 + * @param method a method. 1.330 + * @return the Java types corresponding to the argument types of the given 1.331 + * method. 1.332 + */ 1.333 +public static Type[] getArgumentTypes(final Method method){ 1.334 + Class[] classes = method.getParameterTypes(); 1.335 + Type[] types = new Type[classes.length]; 1.336 + for(int i = classes.length - 1; i >= 0; --i) 1.337 + { 1.338 + types[i] = getType(classes[i]); 1.339 + } 1.340 + return types; 1.341 +} 1.342 + 1.343 +/** 1.344 + * Returns the Java type corresponding to the return type of the given 1.345 + * method descriptor. 1.346 + * 1.347 + * @param methodDescriptor a method descriptor. 1.348 + * @return the Java type corresponding to the return type of the given 1.349 + * method descriptor. 1.350 + */ 1.351 +public static Type getReturnType(final String methodDescriptor){ 1.352 + char[] buf = methodDescriptor.toCharArray(); 1.353 + return getType(buf, methodDescriptor.indexOf(')') + 1); 1.354 +} 1.355 + 1.356 +/** 1.357 + * Returns the Java type corresponding to the return type of the given 1.358 + * method. 1.359 + * 1.360 + * @param method a method. 1.361 + * @return the Java type corresponding to the return type of the given 1.362 + * method. 1.363 + */ 1.364 +public static Type getReturnType(final Method method){ 1.365 + return getType(method.getReturnType()); 1.366 +} 1.367 + 1.368 +/** 1.369 + * Returns the Java type corresponding to the given type descriptor. 1.370 + * 1.371 + * @param buf a buffer containing a type descriptor. 1.372 + * @param off the offset of this descriptor in the previous buffer. 1.373 + * @return the Java type corresponding to the given type descriptor. 1.374 + */ 1.375 +private static Type getType(final char[] buf, final int off){ 1.376 + int len; 1.377 + switch(buf[off]) 1.378 + { 1.379 + case'V': 1.380 + return VOID_TYPE; 1.381 + case'Z': 1.382 + return BOOLEAN_TYPE; 1.383 + case'C': 1.384 + return CHAR_TYPE; 1.385 + case'B': 1.386 + return BYTE_TYPE; 1.387 + case'S': 1.388 + return SHORT_TYPE; 1.389 + case'I': 1.390 + return INT_TYPE; 1.391 + case'F': 1.392 + return FLOAT_TYPE; 1.393 + case'J': 1.394 + return LONG_TYPE; 1.395 + case'D': 1.396 + return DOUBLE_TYPE; 1.397 + case'[': 1.398 + len = 1; 1.399 + while(buf[off + len] == '[') 1.400 + { 1.401 + ++len; 1.402 + } 1.403 + if(buf[off + len] == 'L') 1.404 + { 1.405 + ++len; 1.406 + while(buf[off + len] != ';') 1.407 + { 1.408 + ++len; 1.409 + } 1.410 + } 1.411 + return new Type(ARRAY, buf, off, len + 1); 1.412 + // case 'L': 1.413 + default: 1.414 + len = 1; 1.415 + while(buf[off + len] != ';') 1.416 + { 1.417 + ++len; 1.418 + } 1.419 + return new Type(OBJECT, buf, off, len + 1); 1.420 + } 1.421 +} 1.422 + 1.423 +// ------------------------------------------------------------------------ 1.424 +// Accessors 1.425 +// ------------------------------------------------------------------------ 1.426 + 1.427 +/** 1.428 + * Returns the sort of this Java type. 1.429 + * 1.430 + * @return {@link #VOID VOID}, {@link #BOOLEAN BOOLEAN}, 1.431 + * {@link #CHAR CHAR}, {@link #BYTE BYTE}, {@link #SHORT SHORT}, 1.432 + * {@link #INT INT}, {@link #FLOAT FLOAT}, {@link #LONG LONG}, 1.433 + * {@link #DOUBLE DOUBLE}, {@link #ARRAY ARRAY} or 1.434 + * {@link #OBJECT OBJECT}. 1.435 + */ 1.436 +public int getSort(){ 1.437 + return sort; 1.438 +} 1.439 + 1.440 +/** 1.441 + * Returns the number of dimensions of this array type. This method should 1.442 + * only be used for an array type. 1.443 + * 1.444 + * @return the number of dimensions of this array type. 1.445 + */ 1.446 +public int getDimensions(){ 1.447 + int i = 1; 1.448 + while(buf[off + i] == '[') 1.449 + { 1.450 + ++i; 1.451 + } 1.452 + return i; 1.453 +} 1.454 + 1.455 +/** 1.456 + * Returns the type of the elements of this array type. This method should 1.457 + * only be used for an array type. 1.458 + * 1.459 + * @return Returns the type of the elements of this array type. 1.460 + */ 1.461 +public Type getElementType(){ 1.462 + return getType(buf, off + getDimensions()); 1.463 +} 1.464 + 1.465 +/** 1.466 + * Returns the name of the class corresponding to this type. 1.467 + * 1.468 + * @return the fully qualified name of the class corresponding to this type. 1.469 + */ 1.470 +public String getClassName(){ 1.471 + switch(sort) 1.472 + { 1.473 + case VOID: 1.474 + return "void"; 1.475 + case BOOLEAN: 1.476 + return "boolean"; 1.477 + case CHAR: 1.478 + return "char"; 1.479 + case BYTE: 1.480 + return "byte"; 1.481 + case SHORT: 1.482 + return "short"; 1.483 + case INT: 1.484 + return "int"; 1.485 + case FLOAT: 1.486 + return "float"; 1.487 + case LONG: 1.488 + return "long"; 1.489 + case DOUBLE: 1.490 + return "double"; 1.491 + case ARRAY: 1.492 + StringBuffer b = new StringBuffer(getElementType().getClassName()); 1.493 + for(int i = getDimensions(); i > 0; --i) 1.494 + { 1.495 + b.append("[]"); 1.496 + } 1.497 + return b.toString(); 1.498 + // case OBJECT: 1.499 + default: 1.500 + return new String(buf, off + 1, len - 2).replace('/', '.'); 1.501 + } 1.502 +} 1.503 + 1.504 +/** 1.505 + * Returns the internal name of the class corresponding to this object type. 1.506 + * The internal name of a class is its fully qualified name, where '.' are 1.507 + * replaced by '/'. This method should only be used for an object type. 1.508 + * 1.509 + * @return the internal name of the class corresponding to this object type. 1.510 + */ 1.511 +public String getInternalName(){ 1.512 + return new String(buf, off + 1, len - 2); 1.513 +} 1.514 + 1.515 +// ------------------------------------------------------------------------ 1.516 +// Conversion to type descriptors 1.517 +// ------------------------------------------------------------------------ 1.518 + 1.519 +/** 1.520 + * Returns the descriptor corresponding to this Java type. 1.521 + * 1.522 + * @return the descriptor corresponding to this Java type. 1.523 + */ 1.524 +public String getDescriptor(){ 1.525 + StringBuffer buf = new StringBuffer(); 1.526 + getDescriptor(buf); 1.527 + return buf.toString(); 1.528 +} 1.529 + 1.530 +/** 1.531 + * Returns the descriptor corresponding to the given argument and return 1.532 + * types. 1.533 + * 1.534 + * @param returnType the return type of the method. 1.535 + * @param argumentTypes the argument types of the method. 1.536 + * @return the descriptor corresponding to the given argument and return 1.537 + * types. 1.538 + */ 1.539 +public static String getMethodDescriptor( 1.540 + final Type returnType, 1.541 + final Type[] argumentTypes){ 1.542 + StringBuffer buf = new StringBuffer(); 1.543 + buf.append('('); 1.544 + for(int i = 0; i < argumentTypes.length; ++i) 1.545 + { 1.546 + argumentTypes[i].getDescriptor(buf); 1.547 + } 1.548 + buf.append(')'); 1.549 + returnType.getDescriptor(buf); 1.550 + return buf.toString(); 1.551 +} 1.552 + 1.553 +/** 1.554 + * Appends the descriptor corresponding to this Java type to the given 1.555 + * string buffer. 1.556 + * 1.557 + * @param buf the string buffer to which the descriptor must be appended. 1.558 + */ 1.559 +private void getDescriptor(final StringBuffer buf){ 1.560 + switch(sort) 1.561 + { 1.562 + case VOID: 1.563 + buf.append('V'); 1.564 + return; 1.565 + case BOOLEAN: 1.566 + buf.append('Z'); 1.567 + return; 1.568 + case CHAR: 1.569 + buf.append('C'); 1.570 + return; 1.571 + case BYTE: 1.572 + buf.append('B'); 1.573 + return; 1.574 + case SHORT: 1.575 + buf.append('S'); 1.576 + return; 1.577 + case INT: 1.578 + buf.append('I'); 1.579 + return; 1.580 + case FLOAT: 1.581 + buf.append('F'); 1.582 + return; 1.583 + case LONG: 1.584 + buf.append('J'); 1.585 + return; 1.586 + case DOUBLE: 1.587 + buf.append('D'); 1.588 + return; 1.589 + // case ARRAY: 1.590 + // case OBJECT: 1.591 + default: 1.592 + buf.append(this.buf, off, len); 1.593 + } 1.594 +} 1.595 + 1.596 +// ------------------------------------------------------------------------ 1.597 +// Direct conversion from classes to type descriptors, 1.598 +// without intermediate Type objects 1.599 +// ------------------------------------------------------------------------ 1.600 + 1.601 +/** 1.602 + * Returns the internal name of the given class. The internal name of a 1.603 + * class is its fully qualified name, where '.' are replaced by '/'. 1.604 + * 1.605 + * @param c an object class. 1.606 + * @return the internal name of the given class. 1.607 + */ 1.608 +public static String getInternalName(final Class c){ 1.609 + return c.getName().replace('.', '/'); 1.610 +} 1.611 + 1.612 +/** 1.613 + * Returns the descriptor corresponding to the given Java type. 1.614 + * 1.615 + * @param c an object class, a primitive class or an array class. 1.616 + * @return the descriptor corresponding to the given class. 1.617 + */ 1.618 +public static String getDescriptor(final Class c){ 1.619 + StringBuffer buf = new StringBuffer(); 1.620 + getDescriptor(buf, c); 1.621 + return buf.toString(); 1.622 +} 1.623 + 1.624 +/** 1.625 + * Returns the descriptor corresponding to the given constructor. 1.626 + * 1.627 + * @param c a {@link Constructor Constructor} object. 1.628 + * @return the descriptor of the given constructor. 1.629 + */ 1.630 +public static String getConstructorDescriptor(final Constructor c){ 1.631 + Class[] parameters = c.getParameterTypes(); 1.632 + StringBuffer buf = new StringBuffer(); 1.633 + buf.append('('); 1.634 + for(int i = 0; i < parameters.length; ++i) 1.635 + { 1.636 + getDescriptor(buf, parameters[i]); 1.637 + } 1.638 + return buf.append(")V").toString(); 1.639 +} 1.640 + 1.641 +/** 1.642 + * Returns the descriptor corresponding to the given method. 1.643 + * 1.644 + * @param m a {@link Method Method} object. 1.645 + * @return the descriptor of the given method. 1.646 + */ 1.647 +public static String getMethodDescriptor(final Method m){ 1.648 + Class[] parameters = m.getParameterTypes(); 1.649 + StringBuffer buf = new StringBuffer(); 1.650 + buf.append('('); 1.651 + for(int i = 0; i < parameters.length; ++i) 1.652 + { 1.653 + getDescriptor(buf, parameters[i]); 1.654 + } 1.655 + buf.append(')'); 1.656 + getDescriptor(buf, m.getReturnType()); 1.657 + return buf.toString(); 1.658 +} 1.659 + 1.660 +/** 1.661 + * Appends the descriptor of the given class to the given string buffer. 1.662 + * 1.663 + * @param buf the string buffer to which the descriptor must be appended. 1.664 + * @param c the class whose descriptor must be computed. 1.665 + */ 1.666 +private static void getDescriptor(final StringBuffer buf, final Class c){ 1.667 + Class d = c; 1.668 + while(true) 1.669 + { 1.670 + if(d.isPrimitive()) 1.671 + { 1.672 + char car; 1.673 + if(d == Integer.TYPE) 1.674 + { 1.675 + car = 'I'; 1.676 + } 1.677 + else if(d == Void.TYPE) 1.678 + { 1.679 + car = 'V'; 1.680 + } 1.681 + else if(d == Boolean.TYPE) 1.682 + { 1.683 + car = 'Z'; 1.684 + } 1.685 + else if(d == Byte.TYPE) 1.686 + { 1.687 + car = 'B'; 1.688 + } 1.689 + else if(d == Character.TYPE) 1.690 + { 1.691 + car = 'C'; 1.692 + } 1.693 + else if(d == Short.TYPE) 1.694 + { 1.695 + car = 'S'; 1.696 + } 1.697 + else if(d == Double.TYPE) 1.698 + { 1.699 + car = 'D'; 1.700 + } 1.701 + else if(d == Float.TYPE) 1.702 + { 1.703 + car = 'F'; 1.704 + } 1.705 + else /* if (d == Long.TYPE) */ 1.706 + { 1.707 + car = 'J'; 1.708 + } 1.709 + buf.append(car); 1.710 + return; 1.711 + } 1.712 + else if(d.isArray()) 1.713 + { 1.714 + buf.append('['); 1.715 + d = d.getComponentType(); 1.716 + } 1.717 + else 1.718 + { 1.719 + buf.append('L'); 1.720 + String name = d.getName(); 1.721 + int len = name.length(); 1.722 + for(int i = 0; i < len; ++i) 1.723 + { 1.724 + char car = name.charAt(i); 1.725 + buf.append(car == '.' ? '/' : car); 1.726 + } 1.727 + buf.append(';'); 1.728 + return; 1.729 + } 1.730 + } 1.731 +} 1.732 + 1.733 +// ------------------------------------------------------------------------ 1.734 +// Corresponding size and opcodes 1.735 +// ------------------------------------------------------------------------ 1.736 + 1.737 +/** 1.738 + * Returns the size of values of this type. 1.739 + * 1.740 + * @return the size of values of this type, i.e., 2 for <tt>long</tt> and 1.741 + * <tt>double</tt>, and 1 otherwise. 1.742 + */ 1.743 +public int getSize(){ 1.744 + return sort == LONG || sort == DOUBLE ? 2 : 1; 1.745 +} 1.746 + 1.747 +/** 1.748 + * Returns a JVM instruction opcode adapted to this Java type. 1.749 + * 1.750 + * @param opcode a JVM instruction opcode. This opcode must be one of ILOAD, 1.751 + * ISTORE, IALOAD, IASTORE, IADD, ISUB, IMUL, IDIV, IREM, INEG, ISHL, 1.752 + * ISHR, IUSHR, IAND, IOR, IXOR and IRETURN. 1.753 + * @return an opcode that is similar to the given opcode, but adapted to 1.754 + * this Java type. For example, if this type is <tt>float</tt> and 1.755 + * <tt>opcode</tt> is IRETURN, this method returns FRETURN. 1.756 + */ 1.757 +public int getOpcode(final int opcode){ 1.758 + if(opcode == Opcodes.IALOAD || opcode == Opcodes.IASTORE) 1.759 + { 1.760 + switch(sort) 1.761 + { 1.762 + case BOOLEAN: 1.763 + case BYTE: 1.764 + return opcode + 5; 1.765 + case CHAR: 1.766 + return opcode + 6; 1.767 + case SHORT: 1.768 + return opcode + 7; 1.769 + case INT: 1.770 + return opcode; 1.771 + case FLOAT: 1.772 + return opcode + 2; 1.773 + case LONG: 1.774 + return opcode + 1; 1.775 + case DOUBLE: 1.776 + return opcode + 3; 1.777 + // case ARRAY: 1.778 + // case OBJECT: 1.779 + default: 1.780 + return opcode + 4; 1.781 + } 1.782 + } 1.783 + else 1.784 + { 1.785 + switch(sort) 1.786 + { 1.787 + case VOID: 1.788 + return opcode + 5; 1.789 + case BOOLEAN: 1.790 + case CHAR: 1.791 + case BYTE: 1.792 + case SHORT: 1.793 + case INT: 1.794 + return opcode; 1.795 + case FLOAT: 1.796 + return opcode + 2; 1.797 + case LONG: 1.798 + return opcode + 1; 1.799 + case DOUBLE: 1.800 + return opcode + 3; 1.801 + // case ARRAY: 1.802 + // case OBJECT: 1.803 + default: 1.804 + return opcode + 4; 1.805 + } 1.806 + } 1.807 +} 1.808 + 1.809 +// ------------------------------------------------------------------------ 1.810 +// Equals, hashCode and toString 1.811 +// ------------------------------------------------------------------------ 1.812 + 1.813 +/** 1.814 + * Tests if the given object is equal to this type. 1.815 + * 1.816 + * @param o the object to be compared to this type. 1.817 + * @return <tt>true</tt> if the given object is equal to this type. 1.818 + */ 1.819 +public boolean equals(final Object o){ 1.820 + if(this == o) 1.821 + { 1.822 + return true; 1.823 + } 1.824 + if(!(o instanceof Type)) 1.825 + { 1.826 + return false; 1.827 + } 1.828 + Type t = (Type) o; 1.829 + if(sort != t.sort) 1.830 + { 1.831 + return false; 1.832 + } 1.833 + if(sort == Type.OBJECT || sort == Type.ARRAY) 1.834 + { 1.835 + if(len != t.len) 1.836 + { 1.837 + return false; 1.838 + } 1.839 + for(int i = off, j = t.off, end = i + len; i < end; i++, j++) 1.840 + { 1.841 + if(buf[i] != t.buf[j]) 1.842 + { 1.843 + return false; 1.844 + } 1.845 + } 1.846 + } 1.847 + return true; 1.848 +} 1.849 + 1.850 +/** 1.851 + * Returns a hash code value for this type. 1.852 + * 1.853 + * @return a hash code value for this type. 1.854 + */ 1.855 +public int hashCode(){ 1.856 + int hc = 13 * sort; 1.857 + if(sort == Type.OBJECT || sort == Type.ARRAY) 1.858 + { 1.859 + for(int i = off, end = i + len; i < end; i++) 1.860 + { 1.861 + hc = 17 * (hc + buf[i]); 1.862 + } 1.863 + } 1.864 + return hc; 1.865 +} 1.866 + 1.867 +/** 1.868 + * Returns a string representation of this type. 1.869 + * 1.870 + * @return the descriptor of this type. 1.871 + */ 1.872 +public String toString(){ 1.873 + return getDescriptor(); 1.874 +} 1.875 +}