/* 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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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
