325N/A/*
325N/A * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved.
325N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
325N/A *
325N/A * This code is free software; you can redistribute it and/or modify it
325N/A * under the terms of the GNU General Public License version 2 only, as
325N/A * published by the Free Software Foundation. Oracle designates this
325N/A * particular file as subject to the "Classpath" exception as provided
325N/A * by Oracle in the LICENSE file that accompanied this code.
325N/A *
325N/A * This code is distributed in the hope that it will be useful, but WITHOUT
325N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
325N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
325N/A * version 2 for more details (a copy is included in the LICENSE file that
325N/A * accompanied this code).
325N/A *
325N/A * You should have received a copy of the GNU General Public License version
325N/A * 2 along with this work; if not, write to the Free Software Foundation,
325N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
325N/A *
325N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
325N/A * or visit www.oracle.com if you need additional information or have any
325N/A * questions.
325N/A */
325N/A
325N/A/*
325N/A * This file is available under and governed by the GNU General Public
325N/A * License version 2 only, as published by the Free Software Foundation.
325N/A * However, the following notice accompanied the original version of this
325N/A * file:
325N/A *
325N/A * ASM: a very small and fast Java bytecode manipulation framework
325N/A * Copyright (c) 2000-2007 INRIA, France Telecom
325N/A * All rights reserved.
325N/A *
325N/A * Redistribution and use in source and binary forms, with or without
325N/A * modification, are permitted provided that the following conditions
325N/A * are met:
325N/A * 1. Redistributions of source code must retain the above copyright
325N/A * notice, this list of conditions and the following disclaimer.
325N/A * 2. Redistributions in binary form must reproduce the above copyright
325N/A * notice, this list of conditions and the following disclaimer in the
325N/A * documentation and/or other materials provided with the distribution.
325N/A * 3. Neither the name of the copyright holders nor the names of its
325N/A * contributors may be used to endorse or promote products derived from
325N/A * this software without specific prior written permission.
325N/A *
325N/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
325N/A * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
325N/A * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
325N/A * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
325N/A * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
325N/A * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
325N/A * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
325N/A * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
325N/A * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
325N/A * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
325N/A * THE POSSIBILITY OF SUCH DAMAGE.
325N/A */
325N/Apackage com.sun.xml.internal.ws.org.objectweb.asm;
325N/A
325N/Aimport java.lang.reflect.Constructor;
325N/Aimport java.lang.reflect.Method;
325N/A
325N/A/**
325N/A * A Java type. This class can be used to make it easier to manipulate type and
325N/A * method descriptors.
325N/A *
325N/A * @author Eric Bruneton
325N/A * @author Chris Nokleberg
325N/A */
325N/Apublic class Type {
325N/A
325N/A /**
325N/A * The sort of the <tt>void</tt> type. See {@link #getSort getSort}.
325N/A */
325N/A public static final int VOID = 0;
325N/A
325N/A /**
325N/A * The sort of the <tt>boolean</tt> type. See {@link #getSort getSort}.
325N/A */
325N/A public static final int BOOLEAN = 1;
325N/A
325N/A /**
325N/A * The sort of the <tt>char</tt> type. See {@link #getSort getSort}.
325N/A */
325N/A public static final int CHAR = 2;
325N/A
325N/A /**
325N/A * The sort of the <tt>byte</tt> type. See {@link #getSort getSort}.
325N/A */
325N/A public static final int BYTE = 3;
325N/A
325N/A /**
325N/A * The sort of the <tt>short</tt> type. See {@link #getSort getSort}.
325N/A */
325N/A public static final int SHORT = 4;
325N/A
325N/A /**
325N/A * The sort of the <tt>int</tt> type. See {@link #getSort getSort}.
325N/A */
325N/A public static final int INT = 5;
325N/A
325N/A /**
325N/A * The sort of the <tt>float</tt> type. See {@link #getSort getSort}.
325N/A */
325N/A public static final int FLOAT = 6;
325N/A
325N/A /**
325N/A * The sort of the <tt>long</tt> type. See {@link #getSort getSort}.
325N/A */
325N/A public static final int LONG = 7;
325N/A
325N/A /**
325N/A * The sort of the <tt>double</tt> type. See {@link #getSort getSort}.
325N/A */
325N/A public static final int DOUBLE = 8;
325N/A
325N/A /**
325N/A * The sort of array reference types. See {@link #getSort getSort}.
325N/A */
325N/A public static final int ARRAY = 9;
325N/A
325N/A /**
325N/A * The sort of object reference type. See {@link #getSort getSort}.
325N/A */
325N/A public static final int OBJECT = 10;
325N/A
325N/A /**
325N/A * The <tt>void</tt> type.
325N/A */
325N/A public static final Type VOID_TYPE = new Type(VOID);
325N/A
325N/A /**
325N/A * The <tt>boolean</tt> type.
325N/A */
325N/A public static final Type BOOLEAN_TYPE = new Type(BOOLEAN);
325N/A
325N/A /**
325N/A * The <tt>char</tt> type.
325N/A */
325N/A public static final Type CHAR_TYPE = new Type(CHAR);
325N/A
325N/A /**
325N/A * The <tt>byte</tt> type.
325N/A */
325N/A public static final Type BYTE_TYPE = new Type(BYTE);
325N/A
325N/A /**
325N/A * The <tt>short</tt> type.
325N/A */
325N/A public static final Type SHORT_TYPE = new Type(SHORT);
325N/A
325N/A /**
325N/A * The <tt>int</tt> type.
325N/A */
325N/A public static final Type INT_TYPE = new Type(INT);
325N/A
325N/A /**
325N/A * The <tt>float</tt> type.
325N/A */
325N/A public static final Type FLOAT_TYPE = new Type(FLOAT);
325N/A
325N/A /**
325N/A * The <tt>long</tt> type.
325N/A */
325N/A public static final Type LONG_TYPE = new Type(LONG);
325N/A
325N/A /**
325N/A * The <tt>double</tt> type.
325N/A */
325N/A public static final Type DOUBLE_TYPE = new Type(DOUBLE);
325N/A
325N/A // ------------------------------------------------------------------------
325N/A // Fields
325N/A // ------------------------------------------------------------------------
325N/A
325N/A /**
325N/A * The sort of this Java type.
325N/A */
325N/A private final int sort;
325N/A
325N/A /**
325N/A * A buffer containing the internal name of this Java type. This field is
325N/A * only used for reference types.
325N/A */
325N/A private final char[] buf;
325N/A
325N/A /**
325N/A * The offset of the internal name of this Java type in {@link #buf buf}.
325N/A * This field is only used for reference types.
325N/A */
325N/A private final int off;
325N/A
325N/A /**
325N/A * The length of the internal name of this Java type. This field is only
325N/A * used for reference types.
325N/A */
325N/A private final int len;
325N/A
325N/A // ------------------------------------------------------------------------
325N/A // Constructors
325N/A // ------------------------------------------------------------------------
325N/A
325N/A /**
325N/A * Constructs a primitive type.
325N/A *
325N/A * @param sort the sort of the primitive type to be constructed.
325N/A */
325N/A private Type(final int sort) {
325N/A this(sort, null, 0, 1);
325N/A }
325N/A
325N/A /**
325N/A * Constructs a reference type.
325N/A *
325N/A * @param sort the sort of the reference type to be constructed.
325N/A * @param buf a buffer containing the descriptor of the previous type.
325N/A * @param off the offset of this descriptor in the previous buffer.
325N/A * @param len the length of this descriptor.
325N/A */
325N/A private Type(final int sort, final char[] buf, final int off, final int len)
325N/A {
325N/A this.sort = sort;
325N/A this.buf = buf;
325N/A this.off = off;
325N/A this.len = len;
325N/A }
325N/A
325N/A /**
325N/A * Returns the Java type corresponding to the given type descriptor.
325N/A *
325N/A * @param typeDescriptor a type descriptor.
325N/A * @return the Java type corresponding to the given type descriptor.
325N/A */
325N/A public static Type getType(final String typeDescriptor) {
325N/A return getType(typeDescriptor.toCharArray(), 0);
325N/A }
325N/A
325N/A /**
325N/A * Returns the Java type corresponding to the given internal name.
325N/A *
325N/A * @param internalName an internal name.
325N/A * @return the Java type corresponding to the given internal name.
325N/A */
325N/A public static Type getObjectType(final String internalName) {
325N/A char[] buf = internalName.toCharArray();
325N/A return new Type(buf[0] == '[' ? ARRAY : OBJECT, buf, 0, buf.length);
325N/A }
325N/A
325N/A /**
325N/A * Returns the Java type corresponding to the given class.
325N/A *
325N/A * @param c a class.
325N/A * @return the Java type corresponding to the given class.
325N/A */
325N/A public static Type getType(final Class c) {
325N/A if (c.isPrimitive()) {
325N/A if (c == Integer.TYPE) {
325N/A return INT_TYPE;
325N/A } else if (c == Void.TYPE) {
325N/A return VOID_TYPE;
325N/A } else if (c == Boolean.TYPE) {
325N/A return BOOLEAN_TYPE;
325N/A } else if (c == Byte.TYPE) {
325N/A return BYTE_TYPE;
325N/A } else if (c == Character.TYPE) {
325N/A return CHAR_TYPE;
325N/A } else if (c == Short.TYPE) {
325N/A return SHORT_TYPE;
325N/A } else if (c == Double.TYPE) {
325N/A return DOUBLE_TYPE;
325N/A } else if (c == Float.TYPE) {
325N/A return FLOAT_TYPE;
325N/A } else /* if (c == Long.TYPE) */{
325N/A return LONG_TYPE;
325N/A }
325N/A } else {
325N/A return getType(getDescriptor(c));
325N/A }
325N/A }
325N/A
325N/A /**
325N/A * Returns the Java types corresponding to the argument types of the given
325N/A * method descriptor.
325N/A *
325N/A * @param methodDescriptor a method descriptor.
325N/A * @return the Java types corresponding to the argument types of the given
325N/A * method descriptor.
325N/A */
325N/A public static Type[] getArgumentTypes(final String methodDescriptor) {
325N/A char[] buf = methodDescriptor.toCharArray();
325N/A int off = 1;
325N/A int size = 0;
325N/A while (true) {
325N/A char car = buf[off++];
325N/A if (car == ')') {
325N/A break;
325N/A } else if (car == 'L') {
325N/A while (buf[off++] != ';') {
325N/A }
325N/A ++size;
325N/A } else if (car != '[') {
325N/A ++size;
325N/A }
325N/A }
325N/A Type[] args = new Type[size];
325N/A off = 1;
325N/A size = 0;
325N/A while (buf[off] != ')') {
325N/A args[size] = getType(buf, off);
325N/A off += args[size].len + (args[size].sort == OBJECT ? 2 : 0);
325N/A size += 1;
325N/A }
325N/A return args;
325N/A }
325N/A
325N/A /**
325N/A * Returns the Java types corresponding to the argument types of the given
325N/A * method.
325N/A *
325N/A * @param method a method.
325N/A * @return the Java types corresponding to the argument types of the given
325N/A * method.
325N/A */
325N/A public static Type[] getArgumentTypes(final Method method) {
325N/A Class[] classes = method.getParameterTypes();
325N/A Type[] types = new Type[classes.length];
325N/A for (int i = classes.length - 1; i >= 0; --i) {
325N/A types[i] = getType(classes[i]);
325N/A }
325N/A return types;
325N/A }
325N/A
325N/A /**
325N/A * Returns the Java type corresponding to the return type of the given
325N/A * method descriptor.
325N/A *
325N/A * @param methodDescriptor a method descriptor.
325N/A * @return the Java type corresponding to the return type of the given
325N/A * method descriptor.
325N/A */
325N/A public static Type getReturnType(final String methodDescriptor) {
325N/A char[] buf = methodDescriptor.toCharArray();
325N/A return getType(buf, methodDescriptor.indexOf(')') + 1);
325N/A }
325N/A
325N/A /**
325N/A * Returns the Java type corresponding to the return type of the given
325N/A * method.
325N/A *
325N/A * @param method a method.
325N/A * @return the Java type corresponding to the return type of the given
325N/A * method.
325N/A */
325N/A public static Type getReturnType(final Method method) {
325N/A return getType(method.getReturnType());
325N/A }
325N/A
325N/A /**
325N/A * Returns the Java type corresponding to the given type descriptor.
325N/A *
325N/A * @param buf a buffer containing a type descriptor.
325N/A * @param off the offset of this descriptor in the previous buffer.
325N/A * @return the Java type corresponding to the given type descriptor.
325N/A */
325N/A private static Type getType(final char[] buf, final int off) {
325N/A int len;
325N/A switch (buf[off]) {
325N/A case 'V':
325N/A return VOID_TYPE;
325N/A case 'Z':
325N/A return BOOLEAN_TYPE;
325N/A case 'C':
325N/A return CHAR_TYPE;
325N/A case 'B':
325N/A return BYTE_TYPE;
325N/A case 'S':
325N/A return SHORT_TYPE;
325N/A case 'I':
325N/A return INT_TYPE;
325N/A case 'F':
325N/A return FLOAT_TYPE;
325N/A case 'J':
325N/A return LONG_TYPE;
325N/A case 'D':
325N/A return DOUBLE_TYPE;
325N/A case '[':
325N/A len = 1;
325N/A while (buf[off + len] == '[') {
325N/A ++len;
325N/A }
325N/A if (buf[off + len] == 'L') {
325N/A ++len;
325N/A while (buf[off + len] != ';') {
325N/A ++len;
325N/A }
325N/A }
325N/A return new Type(ARRAY, buf, off, len + 1);
325N/A // case 'L':
325N/A default:
325N/A len = 1;
325N/A while (buf[off + len] != ';') {
325N/A ++len;
325N/A }
325N/A return new Type(OBJECT, buf, off + 1, len - 1);
325N/A }
325N/A }
325N/A
325N/A // ------------------------------------------------------------------------
325N/A // Accessors
325N/A // ------------------------------------------------------------------------
325N/A
325N/A /**
325N/A * Returns the sort of this Java type.
325N/A *
325N/A * @return {@link #VOID VOID}, {@link #BOOLEAN BOOLEAN},
325N/A * {@link #CHAR CHAR}, {@link #BYTE BYTE}, {@link #SHORT SHORT},
325N/A * {@link #INT INT}, {@link #FLOAT FLOAT}, {@link #LONG LONG},
325N/A * {@link #DOUBLE DOUBLE}, {@link #ARRAY ARRAY} or
325N/A * {@link #OBJECT OBJECT}.
325N/A */
325N/A public int getSort() {
325N/A return sort;
325N/A }
325N/A
325N/A /**
325N/A * Returns the number of dimensions of this array type. This method should
325N/A * only be used for an array type.
325N/A *
325N/A * @return the number of dimensions of this array type.
325N/A */
325N/A public int getDimensions() {
325N/A int i = 1;
325N/A while (buf[off + i] == '[') {
325N/A ++i;
325N/A }
325N/A return i;
325N/A }
325N/A
325N/A /**
325N/A * Returns the type of the elements of this array type. This method should
325N/A * only be used for an array type.
325N/A *
325N/A * @return Returns the type of the elements of this array type.
325N/A */
325N/A public Type getElementType() {
325N/A return getType(buf, off + getDimensions());
325N/A }
325N/A
325N/A /**
325N/A * Returns the name of the class corresponding to this type.
325N/A *
325N/A * @return the fully qualified name of the class corresponding to this type.
325N/A */
325N/A public String getClassName() {
325N/A switch (sort) {
325N/A case VOID:
325N/A return "void";
325N/A case BOOLEAN:
325N/A return "boolean";
325N/A case CHAR:
325N/A return "char";
325N/A case BYTE:
325N/A return "byte";
325N/A case SHORT:
325N/A return "short";
325N/A case INT:
325N/A return "int";
325N/A case FLOAT:
325N/A return "float";
325N/A case LONG:
325N/A return "long";
325N/A case DOUBLE:
325N/A return "double";
325N/A case ARRAY:
325N/A StringBuffer b = new StringBuffer(getElementType().getClassName());
325N/A for (int i = getDimensions(); i > 0; --i) {
325N/A b.append("[]");
325N/A }
325N/A return b.toString();
325N/A // case OBJECT:
325N/A default:
325N/A return new String(buf, off, len).replace('/', '.');
325N/A }
325N/A }
325N/A
325N/A /**
325N/A * Returns the internal name of the class corresponding to this object or
325N/A * array type. The internal name of a class is its fully qualified name (as
325N/A * returned by Class.getName(), where '.' are replaced by '/'. This method
325N/A * should only be used for an object or array type.
325N/A *
325N/A * @return the internal name of the class corresponding to this object type.
325N/A */
325N/A public String getInternalName() {
325N/A return new String(buf, off, len);
325N/A }
325N/A
325N/A // ------------------------------------------------------------------------
325N/A // Conversion to type descriptors
325N/A // ------------------------------------------------------------------------
325N/A
325N/A /**
325N/A * Returns the descriptor corresponding to this Java type.
325N/A *
325N/A * @return the descriptor corresponding to this Java type.
325N/A */
325N/A public String getDescriptor() {
325N/A StringBuffer buf = new StringBuffer();
325N/A getDescriptor(buf);
325N/A return buf.toString();
325N/A }
325N/A
325N/A /**
325N/A * Returns the descriptor corresponding to the given argument and return
325N/A * types.
325N/A *
325N/A * @param returnType the return type of the method.
325N/A * @param argumentTypes the argument types of the method.
325N/A * @return the descriptor corresponding to the given argument and return
325N/A * types.
325N/A */
325N/A public static String getMethodDescriptor(
325N/A final Type returnType,
325N/A final Type[] argumentTypes)
325N/A {
325N/A StringBuffer buf = new StringBuffer();
325N/A buf.append('(');
325N/A for (int i = 0; i < argumentTypes.length; ++i) {
325N/A argumentTypes[i].getDescriptor(buf);
325N/A }
325N/A buf.append(')');
325N/A returnType.getDescriptor(buf);
325N/A return buf.toString();
325N/A }
325N/A
325N/A /**
325N/A * Appends the descriptor corresponding to this Java type to the given
325N/A * string buffer.
325N/A *
325N/A * @param buf the string buffer to which the descriptor must be appended.
325N/A */
325N/A private void getDescriptor(final StringBuffer buf) {
325N/A switch (sort) {
325N/A case VOID:
325N/A buf.append('V');
325N/A return;
325N/A case BOOLEAN:
325N/A buf.append('Z');
325N/A return;
325N/A case CHAR:
325N/A buf.append('C');
325N/A return;
325N/A case BYTE:
325N/A buf.append('B');
325N/A return;
325N/A case SHORT:
325N/A buf.append('S');
325N/A return;
325N/A case INT:
325N/A buf.append('I');
325N/A return;
325N/A case FLOAT:
325N/A buf.append('F');
325N/A return;
325N/A case LONG:
325N/A buf.append('J');
325N/A return;
325N/A case DOUBLE:
325N/A buf.append('D');
325N/A return;
325N/A case ARRAY:
325N/A buf.append(this.buf, off, len);
325N/A return;
325N/A // case OBJECT:
325N/A default:
325N/A buf.append('L');
325N/A buf.append(this.buf, off, len);
325N/A buf.append(';');
325N/A }
325N/A }
325N/A
325N/A // ------------------------------------------------------------------------
325N/A // Direct conversion from classes to type descriptors,
325N/A // without intermediate Type objects
325N/A // ------------------------------------------------------------------------
325N/A
325N/A /**
325N/A * Returns the internal name of the given class. The internal name of a
325N/A * class is its fully qualified name, as returned by Class.getName(), where
325N/A * '.' are replaced by '/'.
325N/A *
325N/A * @param c an object or array class.
325N/A * @return the internal name of the given class.
325N/A */
325N/A public static String getInternalName(final Class c) {
325N/A return c.getName().replace('.', '/');
325N/A }
325N/A
325N/A /**
325N/A * Returns the descriptor corresponding to the given Java type.
325N/A *
325N/A * @param c an object class, a primitive class or an array class.
325N/A * @return the descriptor corresponding to the given class.
325N/A */
325N/A public static String getDescriptor(final Class c) {
325N/A StringBuffer buf = new StringBuffer();
325N/A getDescriptor(buf, c);
325N/A return buf.toString();
325N/A }
325N/A
325N/A /**
325N/A * Returns the descriptor corresponding to the given constructor.
325N/A *
325N/A * @param c a {@link Constructor Constructor} object.
325N/A * @return the descriptor of the given constructor.
325N/A */
325N/A public static String getConstructorDescriptor(final Constructor c) {
325N/A Class[] parameters = c.getParameterTypes();
325N/A StringBuffer buf = new StringBuffer();
325N/A buf.append('(');
325N/A for (int i = 0; i < parameters.length; ++i) {
325N/A getDescriptor(buf, parameters[i]);
325N/A }
325N/A return buf.append(")V").toString();
325N/A }
325N/A
325N/A /**
325N/A * Returns the descriptor corresponding to the given method.
325N/A *
325N/A * @param m a {@link Method Method} object.
325N/A * @return the descriptor of the given method.
325N/A */
325N/A public static String getMethodDescriptor(final Method m) {
325N/A Class[] parameters = m.getParameterTypes();
325N/A StringBuffer buf = new StringBuffer();
325N/A buf.append('(');
325N/A for (int i = 0; i < parameters.length; ++i) {
325N/A getDescriptor(buf, parameters[i]);
325N/A }
325N/A buf.append(')');
325N/A getDescriptor(buf, m.getReturnType());
325N/A return buf.toString();
325N/A }
325N/A
325N/A /**
325N/A * Appends the descriptor of the given class to the given string buffer.
325N/A *
325N/A * @param buf the string buffer to which the descriptor must be appended.
325N/A * @param c the class whose descriptor must be computed.
325N/A */
325N/A private static void getDescriptor(final StringBuffer buf, final Class c) {
325N/A Class d = c;
325N/A while (true) {
325N/A if (d.isPrimitive()) {
325N/A char car;
325N/A if (d == Integer.TYPE) {
325N/A car = 'I';
325N/A } else if (d == Void.TYPE) {
325N/A car = 'V';
325N/A } else if (d == Boolean.TYPE) {
325N/A car = 'Z';
325N/A } else if (d == Byte.TYPE) {
325N/A car = 'B';
325N/A } else if (d == Character.TYPE) {
325N/A car = 'C';
325N/A } else if (d == Short.TYPE) {
325N/A car = 'S';
325N/A } else if (d == Double.TYPE) {
325N/A car = 'D';
325N/A } else if (d == Float.TYPE) {
325N/A car = 'F';
325N/A } else /* if (d == Long.TYPE) */{
325N/A car = 'J';
325N/A }
325N/A buf.append(car);
325N/A return;
325N/A } else if (d.isArray()) {
325N/A buf.append('[');
325N/A d = d.getComponentType();
325N/A } else {
325N/A buf.append('L');
325N/A String name = d.getName();
325N/A int len = name.length();
325N/A for (int i = 0; i < len; ++i) {
325N/A char car = name.charAt(i);
325N/A buf.append(car == '.' ? '/' : car);
325N/A }
325N/A buf.append(';');
325N/A return;
325N/A }
325N/A }
325N/A }
325N/A
325N/A // ------------------------------------------------------------------------
325N/A // Corresponding size and opcodes
325N/A // ------------------------------------------------------------------------
325N/A
325N/A /**
325N/A * Returns the size of values of this type.
325N/A *
325N/A * @return the size of values of this type, i.e., 2 for <tt>long</tt> and
325N/A * <tt>double</tt>, and 1 otherwise.
325N/A */
325N/A public int getSize() {
325N/A return sort == LONG || sort == DOUBLE ? 2 : 1;
325N/A }
325N/A
325N/A /**
325N/A * Returns a JVM instruction opcode adapted to this Java type.
325N/A *
325N/A * @param opcode a JVM instruction opcode. This opcode must be one of ILOAD,
325N/A * ISTORE, IALOAD, IASTORE, IADD, ISUB, IMUL, IDIV, IREM, INEG, ISHL,
325N/A * ISHR, IUSHR, IAND, IOR, IXOR and IRETURN.
325N/A * @return an opcode that is similar to the given opcode, but adapted to
325N/A * this Java type. For example, if this type is <tt>float</tt> and
325N/A * <tt>opcode</tt> is IRETURN, this method returns FRETURN.
325N/A */
325N/A public int getOpcode(final int opcode) {
325N/A if (opcode == Opcodes.IALOAD || opcode == Opcodes.IASTORE) {
325N/A switch (sort) {
325N/A case BOOLEAN:
325N/A case BYTE:
325N/A return opcode + 5;
325N/A case CHAR:
325N/A return opcode + 6;
325N/A case SHORT:
325N/A return opcode + 7;
325N/A case INT:
325N/A return opcode;
325N/A case FLOAT:
325N/A return opcode + 2;
325N/A case LONG:
325N/A return opcode + 1;
325N/A case DOUBLE:
325N/A return opcode + 3;
325N/A // case ARRAY:
325N/A // case OBJECT:
325N/A default:
325N/A return opcode + 4;
325N/A }
325N/A } else {
325N/A switch (sort) {
325N/A case VOID:
325N/A return opcode + 5;
325N/A case BOOLEAN:
325N/A case CHAR:
325N/A case BYTE:
325N/A case SHORT:
325N/A case INT:
325N/A return opcode;
325N/A case FLOAT:
325N/A return opcode + 2;
325N/A case LONG:
325N/A return opcode + 1;
325N/A case DOUBLE:
325N/A return opcode + 3;
325N/A // case ARRAY:
325N/A // case OBJECT:
325N/A default:
325N/A return opcode + 4;
325N/A }
325N/A }
325N/A }
325N/A
325N/A // ------------------------------------------------------------------------
325N/A // Equals, hashCode and toString
325N/A // ------------------------------------------------------------------------
325N/A
325N/A /**
325N/A * Tests if the given object is equal to this type.
325N/A *
325N/A * @param o the object to be compared to this type.
325N/A * @return <tt>true</tt> if the given object is equal to this type.
325N/A */
325N/A public boolean equals(final Object o) {
325N/A if (this == o) {
325N/A return true;
325N/A }
325N/A if (!(o instanceof Type)) {
325N/A return false;
325N/A }
325N/A Type t = (Type) o;
325N/A if (sort != t.sort) {
325N/A return false;
325N/A }
325N/A if (sort == OBJECT || sort == ARRAY) {
325N/A if (len != t.len) {
325N/A return false;
325N/A }
325N/A for (int i = off, j = t.off, end = i + len; i < end; i++, j++) {
325N/A if (buf[i] != t.buf[j]) {
325N/A return false;
325N/A }
325N/A }
325N/A }
325N/A return true;
325N/A }
325N/A
325N/A /**
325N/A * Returns a hash code value for this type.
325N/A *
325N/A * @return a hash code value for this type.
325N/A */
325N/A public int hashCode() {
325N/A int hc = 13 * sort;
325N/A if (sort == OBJECT || sort == ARRAY) {
325N/A for (int i = off, end = i + len; i < end; i++) {
325N/A hc = 17 * (hc + buf[i]);
325N/A }
325N/A }
325N/A return hc;
325N/A }
325N/A
325N/A /**
325N/A * Returns a string representation of this type.
325N/A *
325N/A * @return the descriptor of this type.
325N/A */
325N/A public String toString() {
325N/A return getDescriptor();
325N/A }
325N/A}