/* TypeSignature.java -- Class used to compute type signatures
   Copyright (C) 1998, 2000, 2002 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package gnu.java.lang.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;

/**
 * This class provides static methods that can be used to compute
 * type-signatures of <code>Class</code>s or <code>Member</code>s.
 * More specific methods are also provided for computing the
 * type-signature of <code>Constructor</code>s and
 * <code>Method</code>s.  Methods are also provided to go in the
 * reverse direction.
 *
 * @author Eric Blake (ebb9@email.byu.edu)
 */
public class TypeSignature
{
  /**
   * Returns a <code>String</code> representing the type-encoding of a class.
   * The .class file format has different encodings for classes, depending
   * on whether it must be disambiguated from primitive types or not; hence
   * the descriptor parameter to choose between them. If you are planning
   * on decoding primitive types along with classes, then descriptor should
   * be true for correct results. Type-encodings are computed as follows:
   *
   * <pre>
   * boolean -> "Z"
   * byte    -> "B"
   * char    -> "C"
   * double  -> "D"
   * float   -> "F"
   * int     -> "I"
   * long    -> "J"
   * short   -> "S"
   * void    -> "V"
   * arrays  -> "[" + descriptor format of component type
   * object  -> class format: fully qualified name with '.' replaced by '/'
   *            descriptor format: "L" + class format + ";"
   * </pre>
   *
   * @param type the class name to encode
   * @param descriptor true to return objects in descriptor format
   * @return the class name, as it appears in bytecode constant pools
   * @see #getClassForEncoding(String)
   */
  public static String getEncodingOfClass(String type, boolean descriptor)
  {
    if (! descriptor || type.charAt(0) == '[')
      return type.replace('.', '/');
    if (type.equals("boolean"))
      return "Z";
    if (type.equals("byte"))
      return "B";
    if (type.equals("short"))
      return "S";
    if (type.equals("char"))
      return "C";
    if (type.equals("int"))
      return "I";
    if (type.equals("long"))
      return "J";
    if (type.equals("float"))
      return "F";
    if (type.equals("double"))
      return "D";
    if (type.equals("void"))
      return "V";
    return 'L' + type.replace('.', '/') + ';';
  }

  /**
   * Gets the descriptor encoding for a class.
   *
   * @param clazz the class to encode
   * @param descriptor true to return objects in descriptor format
   * @return the class name, as it appears in bytecode constant pools
   * @see #getEncodingOfClass(String, boolean)
   */
  public static String getEncodingOfClass(Class clazz, boolean descriptor)
  {
    return getEncodingOfClass(clazz.getName(), descriptor);
  }

  /**
   * Gets the descriptor encoding for a class.
   *
   * @param clazz the class to encode
   * @return the class name, as it appears in bytecode constant pools
   * @see #getEncodingOfClass(String, boolean)
   */
  public static String getEncodingOfClass(Class clazz)
  {
    return getEncodingOfClass(clazz.getName(), true);
  }


  /**
   * This function is the inverse of <code>getEncodingOfClass</code>. This
   * accepts both object and descriptor formats, but must know which style
   * of string is being passed in (usually, descriptor should be true). In
   * descriptor format, "I" is treated as int.class, in object format, it
   * is treated as a class named I in the unnamed package. This method is
   * strictly equivalent to {@link #getClassForEncoding(java.lang.String, boolean, java.lang.ClassLoader)}
   * with a class loader equal to <code>null</code>. In that case, it
   * uses the default class loader on the calling stack.
   *
   * @param type_code the class name to decode
   * @param descriptor if the string is in descriptor format
   * @return the corresponding Class object
   * @throws ClassNotFoundException if the class cannot be located
   * @see #getEncodingOfClass(Class, boolean)
   */
  public static Class getClassForEncoding(String type_code, boolean descriptor)
    throws ClassNotFoundException
  {
    return getClassForEncoding(type_code, descriptor, null);
  }

  /**
   * This function is the inverse of <code>getEncodingOfClass</code>. This
   * accepts both object and descriptor formats, but must know which style
   * of string is being passed in (usually, descriptor should be true). In
   * descriptor format, "I" is treated as int.class, in object format, it
   * is treated as a class named I in the unnamed package.
   *
   * @param type_code The class name to decode.
   * @param descriptor If the string is in descriptor format.
   * @param loader The class loader when resolving generic object name. If
   * <code>loader</code> is null then it uses the default class loader on the
   * calling stack.
   * @return the corresponding Class object.
   * @throws ClassNotFoundException if the class cannot be located.
   * @see #getEncodingOfClass(Class, boolean)
   * @see #getClassForEncoding(String, boolean)
   */
  public static Class getClassForEncoding(String type_code, boolean descriptor,
		 			  ClassLoader loader)
    throws ClassNotFoundException
  {
    if (descriptor)
      {
        switch (type_code.charAt(0))
          {
          case 'B':
            return byte.class;
          case 'C':
            return char.class;
          case 'D':
            return double.class;
          case 'F':
            return float.class;
          case 'I':
            return int.class;
          case 'J':
            return long.class;
          case 'S':
            return short.class;
          case 'V':
            return void.class;
          case 'Z':
            return boolean.class;
          default:
            throw new ClassNotFoundException("Invalid class name: "
                                             + type_code);
          case 'L':
            type_code = type_code.substring(1, type_code.length() - 1);
            // Fallthrough.
          case '[':
          }
      }
    return Class.forName(type_code.replace('/', '.'), true, loader);
  }

  /**
   * Gets the Class object for a type name.
   *
   * @param type_code the class name to decode
   * @return the corresponding Class object
   * @throws ClassNotFoundException if the class cannot be located
   * @see #getClassForEncoding(String, boolean)
   */
  public static Class getClassForEncoding(String type_code)
    throws ClassNotFoundException
  {
    return getClassForEncoding(type_code, true);
  }

  /**
   * Returns a <code>String</code> representing the type-encoding of a
   * method.  The type-encoding of a method is:
   *
   * "(" + parameter type descriptors + ")" + return type descriptor
   *
   * XXX This could be faster if it were implemented natively.
   *
   * @param m the method to encode
   * @return the encoding
   */
  public static String getEncodingOfMethod(Method m)
  {
    Class[] paramTypes = m.getParameterTypes();
    StringBuffer buf = new StringBuffer().append('(');
    for (int i = 0; i < paramTypes.length; i++)
      buf.append(getEncodingOfClass(paramTypes[i].getName(), true));
    buf.append(')').append(getEncodingOfClass(m.getReturnType().getName(),
                                              true));
    return buf.toString();
  }

  /**
   * Returns a <code>String</code> representing the type-encoding of a
   * constructor. The type-encoding of a method is:
   *
   * "(" + parameter type descriptors + ")V"
   *
   * XXX This could be faster if it were implemented natively.
   *
   * @param c the constructor to encode
   * @return the encoding
   */
  public static String getEncodingOfConstructor(Constructor c)
  {
    Class[] paramTypes = c.getParameterTypes();
    StringBuffer buf = new StringBuffer().append('(');
    for (int i = 0; i < paramTypes.length; i++)
      buf.append(getEncodingOfClass(paramTypes[i].getName(), true));
    buf.append(")V");
    return buf.toString();
  }

  /**
   * Returns a <code>String</code> representing the type-encoding of a
   * class member. This appropriately handles Constructors, Methods, and
   * Fields.
   *
   * @param mem the member to encode
   * @return the encoding
   */
  public static String getEncodingOfMember(Member mem)
  {
    if (mem instanceof Constructor)
      return getEncodingOfConstructor((Constructor) mem);
    if (mem instanceof Method)
      return getEncodingOfMethod((Method) mem);
    else // Field
      return getEncodingOfClass(((Field) mem).getType().getName(), true);
  }
} // class TypeSignature
