package org.eclipse.jdt.core;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */
 
import org.eclipse.jdt.core.compiler.*;
import org.eclipse.jdt.core.compiler.ITerminalSymbols;
import org.eclipse.jdt.core.compiler.InvalidInputException;
import org.eclipse.jdt.internal.compiler.parser.Scanner;
import org.eclipse.jdt.internal.compiler.util.CharOperation;

/**
 * Provides methods for encoding and decoding type and method signature strings.
 * <p>
 * The syntax for a type signature is:
 * <pre>
 * typeSignature ::=
 *     "B"  // byte
 *   | "C"  // char
 *   | "D"  // double
 *   | "F"  // float
 *   | "I"  // int
 *   | "J"  // long
 *   | "S"  // short
 *   | "V"  // void
 *   | "Z"  // boolean
 *   | "L" + binaryTypeName + ";"  // resolved named type (i.e., in compiled code)
 *   | "Q" + sourceTypeName + ";"  // unresolved named type (i.e., in source code)
 *   | "[" + typeSignature  // array of type denoted by typeSignature
 * </pre>
 * </p>
 * <p>
 * Examples:
 * <ul>
 *   <li><code>"[[I"</code> denotes <code>int[][]</code></li>
 *   <li><code>"Ljava.lang.String;"</code> denotes <code>java.lang.String</code> in compiled code</li>
 *   <li><code>"QString"</code> denotes <code>String</code> in source code</li>
 *   <li><code>"Qjava.lang.String"</code> denotes <code>java.lang.String</code> in source code</li>
 *   <li><code>"[QString"</code> denotes <code>String[]</code> in source code</li>
 * </ul>
 * </p>
 * <p>
 * The syntax for a method signature is:
 * <pre>
 * methodSignature ::= "(" + paramTypeSignature* + ")" + returnTypeSignature
 * paramTypeSignature ::= typeSignature
 * returnTypeSignature ::= typeSignature
 * </pre>
 * <p>
 * Examples:
 * <ul>
 *   <li><code>"()I"</code> denotes <code>int foo()</code></li>
 *   <li><code>"([Ljava.lang.String;)V"</code> denotes <code>void foo(java.lang.String[])</code> in compiled code</li>
 *   <li><code>"(QString;)QObject;"</code> denotes <code>Object foo(String)</code> in source code</li>
 * </ul>
 * </p>
 * <p>
 * This class provides static methods and constants only; it is not intended to be
 * instantiated or subclassed by clients.
 * </p>
 */
public final class Signature {

	/**
	 * Character constant indicating the primitive type boolean in a signature.
	 * Value is <code>'Z'</code>.
	 */
	public static final char C_BOOLEAN 		= 'Z';

	/**
	 * Character constant indicating the primitive type byte in a signature.
	 * Value is <code>'B'</code>.
	 */
	public static final char C_BYTE 		= 'B';

	/**
	 * Character constant indicating the primitive type char in a signature.
	 * Value is <code>'C'</code>.
	 */
	public static final char C_CHAR 		= 'C';

	/**
	 * Character constant indicating the primitive type double in a signature.
	 * Value is <code>'D'</code>.
	 */
	public static final char C_DOUBLE 		= 'D';

	/**
	 * Character constant indicating the primitive type float in a signature.
	 * Value is <code>'F'</code>.
	 */
	public static final char C_FLOAT 		= 'F';

	/**
	 * Character constant indicating the primitive type int in a signature.
	 * Value is <code>'I'</code>.
	 */
	public static final char C_INT 			= 'I';
	
	/**
	 * Character constant indicating the semicolon in a signature.
	 * Value is <code>';'</code>.
	 */
	public static final char C_SEMICOLON 			= ';';

	/**
	 * Character constant indicating the primitive type long in a signature.
	 * Value is <code>'J'</code>.
	 */
	public static final char C_LONG			= 'J';
	
	/**
	 * Character constant indicating the primitive type short in a signature.
	 * Value is <code>'S'</code>.
	 */
	public static final char C_SHORT		= 'S';
	
	/**
	 * Character constant indicating result type void in a signature.
	 * Value is <code>'V'</code>.
	 */
	public static final char C_VOID			= 'V';
	
	/** 
	 * Character constant indicating the dot in a signature. 
	 * Value is <code>'.'</code>.
	 */
	public static final char C_DOT			= '.';
	
	/** 
	 * Character constant indicating the dollar in a signature.
	 * Value is <code>'$'</code>.
	 */
	public static final char C_DOLLAR			= '$';

	/** 
	 * Character constant indicating an array type in a signature.
	 * Value is <code>'['</code>.
	 */
	public static final char C_ARRAY		= '[';

	/** 
	 * Character constant indicating the start of a resolved, named type in a 
	 * signature. Value is <code>'L'</code>.
	 */
	public static final char C_RESOLVED		= 'L';

	/** 
	 * Character constant indicating the start of an unresolved, named type in a
	 * signature. Value is <code>'Q'</code>.
	 */
	public static final char C_UNRESOLVED	= 'Q';

	/**
	 * Character constant indicating the end of a named type in a signature. 
	 * Value is <code>';'</code>.
	 */
	public static final char C_NAME_END		= ';';

	/**
	 * Character constant indicating the start of a parameter type list in a
	 * signature. Value is <code>'('</code>.
	 */
	public static final char C_PARAM_START	= '(';

	/**
	 * Character constant indicating the end of a parameter type list in a 
	 * signature. Value is <code>')'</code>.
	 */
	public static final char C_PARAM_END	= ')';

	/**
	 * String constant for the signature of the primitive type boolean.
	 * Value is <code>"Z"</code>.
	 */
	public static final String SIG_BOOLEAN 		= "Z"; //$NON-NLS-1$

	/**
	 * String constant for the signature of the primitive type byte. 
	 * Value is <code>"B"</code>.
	 */
	public static final String SIG_BYTE 		= "B"; //$NON-NLS-1$

	/**
	 * String constant for the signature of the primitive type char.
	 * Value is <code>"C"</code>.
	 */
	public static final String SIG_CHAR 		= "C"; //$NON-NLS-1$

	/**
	 * String constant for the signature of the primitive type double.
	 * Value is <code>"D"</code>.
	 */
	public static final String SIG_DOUBLE 		= "D"; //$NON-NLS-1$

	/**
	 * String constant for the signature of the primitive type float.
	 * Value is <code>"F"</code>.
	 */
	public static final String SIG_FLOAT 		= "F"; //$NON-NLS-1$

	/**
	 * String constant for the signature of the primitive type int.
	 * Value is <code>"I"</code>.
	 */
	public static final String SIG_INT 			= "I"; //$NON-NLS-1$

	/**
	 * String constant for the signature of the primitive type long.
	 * Value is <code>"J"</code>.
	 */
	public static final String SIG_LONG			= "J"; //$NON-NLS-1$

	/**
	 * String constant for the signature of the primitive type short.
	 * Value is <code>"S"</code>.
	 */
	public static final String SIG_SHORT		= "S"; //$NON-NLS-1$

	/** String constant for the signature of result type void.
	 * Value is <code>"V"</code>.
	 */
	public static final String SIG_VOID			= "V"; //$NON-NLS-1$
	
	private static final char[] NO_CHAR = new char[0];
	private static final char[][] NO_CHAR_CHAR = new char[0][];
	private static final char[] BOOLEAN = {'b', 'o', 'o', 'l', 'e', 'a', 'n'};
	private static final char[] BYTE = {'b', 'y', 't', 'e'};
	private static final char[] CHAR = {'c', 'h', 'a', 'r'};
	private static final char[] DOUBLE = {'d', 'o', 'u', 'b', 'l', 'e'};
	private static final char[] FLOAT = {'f', 'l', 'o', 'a', 't'};
	private static final char[] INT = {'i', 'n', 't'};
	private static final char[] LONG = {'l', 'o', 'n', 'g'};
	private static final char[] SHORT = {'s', 'h', 'o', 'r', 't'};
	private static final char[] VOID = {'v', 'o', 'i', 'd'};
	
	
/**
 * Not instantiable.
 */
private Signature() {}

private static long copyType(char[] signature, int sigPos, char[] dest, int index, boolean fullyQualifyTypeNames) {
	int arrayCount = 0;
	loop: while (true) {
		switch (signature[sigPos++]) {
			case C_ARRAY :
				arrayCount++;
				break;
			case C_BOOLEAN :
				int length = BOOLEAN.length;
				System.arraycopy(BOOLEAN, 0, dest, index, length);
				index += length;
				break loop;
			case C_BYTE :
				length = BYTE.length;
				System.arraycopy(BYTE, 0, dest, index, length);
				index += length;
				break loop;
			case C_CHAR :
				length = CHAR.length;
				System.arraycopy(CHAR, 0, dest, index, length);
				index += length;
				break loop;
			case C_DOUBLE :
				length = DOUBLE.length;
				System.arraycopy(DOUBLE, 0, dest, index, length);
				index += length;
				break loop;
			case C_FLOAT :
				length = FLOAT.length;
				System.arraycopy(FLOAT, 0, dest, index, length);
				index += length;
				break loop;
			case C_INT :
				length = INT.length;
				System.arraycopy(INT, 0, dest, index, length);
				index += length;
				break loop;
			case C_LONG :
				length = LONG.length;
				System.arraycopy(LONG, 0, dest, index, length);
				index += length;
				break loop;
			case C_SHORT :
				length = SHORT.length;
				System.arraycopy(SHORT, 0, dest, index, length);
				index += length;
				break loop;
			case C_VOID :
				length = VOID.length;
				System.arraycopy(VOID, 0, dest, index, length);
				index += length;
				break loop;
			case C_RESOLVED :
			case C_UNRESOLVED :
				int end = CharOperation.indexOf(C_SEMICOLON, signature, sigPos);
				if (end == -1) throw new IllegalArgumentException();
				int start;
				if (fullyQualifyTypeNames) {
					start = sigPos;
				} else {
					start = CharOperation.lastIndexOf(C_DOT, signature, sigPos, end)+1;
					if (start == 0) start = sigPos;
				} 
				length = end-start;
				System.arraycopy(signature, start, dest, index, length);
				sigPos = end+1;
				index += length;
				break loop;
		}
	}
	while (arrayCount-- > 0) {
		dest[index++] = '[';
		dest[index++] = ']';
	}
	return (((long) index) << 32) + sigPos;
}
/**
 * Creates a new type signature with the given amount of array nesting added 
 * to the given type signature.
 *
 * @param typeSignature the type signature
 * @param arrayCount the desired number of levels of array nesting
 * @return the encoded array type signature
 * 
 * @since 2.0
 */
public static char[] createArraySignature(char[] typeSignature, int arrayCount) {
	if (arrayCount == 0) return typeSignature;
	int sigLength = typeSignature.length;
	char[] result = new char[arrayCount + sigLength];
	for (int i = 0; i < arrayCount; i++) {
		result[i] = C_ARRAY;
	}
	System.arraycopy(typeSignature, 0, result, arrayCount, sigLength);
	return result;
}
/**
 * Creates a new type signature with the given amount of array nesting added 
 * to the given type signature.
 *
 * @param typeSignature the type signature
 * @param arrayCount the desired number of levels of array nesting
 * @return the encoded array type signature
 */
public static String createArraySignature(String typeSignature, int arrayCount) {
	return new String(createArraySignature(typeSignature.toCharArray(), arrayCount));
}
/**
 * Creates a method signature from the given parameter and return type 
 * signatures. The encoded method signature is dot-based.
 *
 * @param parameterTypes the list of parameter type signatures
 * @param returnType the return type signature
 * @return the encoded method signature
 * 
 * @since 2.0
 */
public static char[] createMethodSignature(char[][] parameterTypes, char[] returnType) {
	int parameterTypesLength = parameterTypes.length;
	int parameterLength = 0;
	for (int i = 0; i < parameterTypesLength; i++) {
		parameterLength += parameterTypes[i].length;
		
	}
	int returnTypeLength = returnType.length;
	char[] result = new char[1 + parameterLength + 1 + returnTypeLength];
	result[0] = C_PARAM_START;
	int index = 1;
	for (int i = 0; i < parameterTypesLength; i++) {
		char[] parameterType = parameterTypes[i];
		int length = parameterType.length;
		System.arraycopy(parameterType, 0, result, index, length);
		index += length;
	}
	result[index] = C_PARAM_END;
	System.arraycopy(returnType, 0, result, index+1, returnTypeLength);
	return result;
}
/**
 * Creates a method signature from the given parameter and return type 
 * signatures. The encoded method signature is dot-based.
 *
 * @param parameterTypes the list of parameter type signatures
 * @param returnType the return type signature
 * @return the encoded method signature
 */
public static String createMethodSignature(String[] parameterTypes, String returnType) {
	int parameterTypesLenth = parameterTypes.length;
	char[][] parameters = new char[parameterTypesLenth][];
	for (int i = 0; i < parameterTypesLenth; i++) {
		parameters[i] = parameterTypes[i].toCharArray();
	}
	return new String(createMethodSignature(parameters, returnType.toCharArray()));
}
/**
 * Creates a new type signature from the given type name encoded as a character
 * array. This method is equivalent to
 * <code>createTypeSignature(new String(typeName),isResolved)</code>, although
 * more efficient for callers with character arrays rather than strings. If the 
 * type name is qualified, then it is expected to be dot-based.
 *
 * @param typeName the possibly qualified type name
 * @param isResolved <code>true</code> if the type name is to be considered
 *   resolved (for example, a type name from a binary class file), and 
 *   <code>false</code> if the type name is to be considered unresolved
 *   (for example, a type name found in source code)
 * @return the encoded type signature
 * @see #createTypeSignature(java.lang.String,boolean)
 */
public static String createTypeSignature(char[] typeName, boolean isResolved) {
	return new String(createCharArrayTypeSignature(typeName, isResolved));
}
/**
 * Creates a new type signature from the given type name encoded as a character
 * array. This method is equivalent to
 * <code>createTypeSignature(new String(typeName),isResolved).toCharArray()</code>, although
 * more efficient for callers with character arrays rather than strings. If the 
 * type name is qualified, then it is expected to be dot-based.
 *
 * @param typeName the possibly qualified type name
 * @param isResolved <code>true</code> if the type name is to be considered
 *   resolved (for example, a type name from a binary class file), and 
 *   <code>false</code> if the type name is to be considered unresolved
 *   (for example, a type name found in source code)
 * @return the encoded type signature
 * @see #createTypeSignature(java.lang.String,boolean)
 * 
 * @since 2.0
 */
public static char[] createCharArrayTypeSignature(char[] typeName, boolean isResolved) {
	try {
		Scanner scanner = new Scanner();
		scanner.setSource(typeName);
		int token = scanner.getNextToken();
		boolean primitive = true;
		char primitiveSig = ' ';
		StringBuffer sig = null;
		int arrayCount = 0;
		switch (token) {
			case ITerminalSymbols.TokenNameIdentifier :
				char[] idSource = scanner.getCurrentIdentifierSource();
				sig = new StringBuffer(idSource.length);
				sig.append(idSource);
				primitive = false;
				break;
			case ITerminalSymbols.TokenNameboolean :
				primitiveSig = Signature.C_BOOLEAN;
				break;
			case ITerminalSymbols.TokenNamebyte :
				primitiveSig = Signature.C_BYTE;
				break;
			case ITerminalSymbols.TokenNamechar :
				primitiveSig = Signature.C_CHAR;
				break;
			case ITerminalSymbols.TokenNamedouble :
				primitiveSig = Signature.C_DOUBLE;
				break;
			case ITerminalSymbols.TokenNamefloat :
				primitiveSig = Signature.C_FLOAT;
				break;
			case ITerminalSymbols.TokenNameint :
				primitiveSig = Signature.C_INT;
				break;
			case ITerminalSymbols.TokenNamelong :
				primitiveSig = Signature.C_LONG;
				break;
			case ITerminalSymbols.TokenNameshort :
				primitiveSig = Signature.C_SHORT;
				break;
			case ITerminalSymbols.TokenNamevoid :
				primitiveSig = Signature.C_VOID;
				break;
			default :
				throw new IllegalArgumentException();
		}
		token = scanner.getNextToken();
		while (!primitive && token == ITerminalSymbols.TokenNameDOT) {
			sig.append(scanner.getCurrentIdentifierSource());
			token = scanner.getNextToken();
			if (token == ITerminalSymbols.TokenNameIdentifier) {
				sig.append(scanner.getCurrentIdentifierSource());
				token = scanner.getNextToken();
			} else {
				throw new IllegalArgumentException();
			}
		}
		while (token == ITerminalSymbols.TokenNameLBRACKET) {
			token = scanner.getNextToken();
			if (token != ITerminalSymbols.TokenNameRBRACKET)
				throw new IllegalArgumentException();
			arrayCount++;
			token = scanner.getNextToken();
		}
		if (token != ITerminalSymbols.TokenNameEOF)
			throw new IllegalArgumentException();
		char[] result;
		if (primitive) {
			result = new char[arrayCount+1];
			result[arrayCount] = primitiveSig;
		} else {
			int sigLength = sig.length(); 
			int resultLength = arrayCount + 1 + sigLength + 1; // e.g. '[[[Ljava.lang.String;'
			result = new char[resultLength];
			sig.getChars(0, sigLength, result, arrayCount + 1);
			result[arrayCount] = isResolved ? C_RESOLVED : C_UNRESOLVED;
			result[resultLength-1] = C_NAME_END;
		}
		for (int i = 0; i < arrayCount; i++) {
			result[i] = C_ARRAY;
		}
		return result;
	} catch (InvalidInputException e) {
		throw new IllegalArgumentException();
	}
}
/**
 * Creates a new type signature from the given type name. If the type name is qualified,
 * then it is expected to be dot-based.
 * <p>
 * For example:
 * <pre>
 * <code>
 * createTypeSignature("int", hucairz) -> "I"
 * createTypeSignature("java.lang.String", true) -> "Ljava.lang.String;"
 * createTypeSignature("String", false) -> "QString;"
 * createTypeSignature("java.lang.String", false) -> "Qjava.lang.String;"
 * createTypeSignature("int []", false) -> "[I"
 * </code>
 * </pre>
 * </p>
 *
 * @param typeName the possibly qualified type name
 * @param isResolved <code>true</code> if the type name is to be considered
 *   resolved (for example, a type name from a binary class file), and 
 *   <code>false</code> if the type name is to be considered unresolved
 *   (for example, a type name found in source code)
 * @return the encoded type signature
 */
public static String createTypeSignature(String typeName, boolean isResolved) {
	return createTypeSignature(typeName.toCharArray(), isResolved);
}
/**
 * Returns the array count (array nesting depth) of the given type signature.
 *
 * @param typeSignature the type signature
 * @return the array nesting depth, or 0 if not an array
 * @exception IllegalArgumentException if the signature is not syntactically
 *   correct
 * 
 * @since 2.0
 */
public static int getArrayCount(char[] typeSignature) throws IllegalArgumentException {	
	try {
		int count = 0;
		while (typeSignature[count] == C_ARRAY) {
			++count;
		}
		return count;
	} catch (ArrayIndexOutOfBoundsException e) { // signature is syntactically incorrect if last character is C_ARRAY
		throw new IllegalArgumentException();
	}
}
/**
 * Returns the array count (array nesting depth) of the given type signature.
 *
 * @param typeSignature the type signature
 * @return the array nesting depth, or 0 if not an array
 * @exception IllegalArgumentException if the signature is not syntactically
 *   correct
 */
public static int getArrayCount(String typeSignature) throws IllegalArgumentException {
	return getArrayCount(typeSignature.toCharArray());
}
/**
 * Returns the type signature without any array nesting.
 * <p>
 * For example:
 * <pre>
 * <code>
 * getElementType({'[', '[', 'I'}) --> {'I'}.
 * </code>
 * </pre>
 * </p>
 * 
 * @param typeSignature the type signature
 * @return the type signature without arrays
 * @exception IllegalArgumentException if the signature is not syntactically
 *   correct
 * 
 * @since 2.0
 */
public static char[] getElementType(char[] typeSignature) throws IllegalArgumentException {
	int count = getArrayCount(typeSignature);
	if (count == 0) return typeSignature;
	int length = typeSignature.length;
	char[] result = new char[length-count];
	System.arraycopy(typeSignature, count, result, 0, length-count);
	return result;
}
/**
 * Returns the type signature without any array nesting.
 * <p>
 * For example:
 * <pre>
 * <code>
 * getElementType("[[I") --> "I".
 * </code>
 * </pre>
 * </p>
 * 
 * @param typeSignature the type signature
 * @return the type signature without arrays
 * @exception IllegalArgumentException if the signature is not syntactically
 *   correct
 */
public static String getElementType(String typeSignature) throws IllegalArgumentException {
	return new String(getElementType(typeSignature.toCharArray()));
}
/**
 * Returns the number of parameter types in the given method signature.
 *
 * @param methodSignature the method signature
 * @return the number of parameters
 * @exception IllegalArgumentException if the signature is not syntactically
 *   correct
 * @since 2.0
 */
public static int getParameterCount(char[] methodSignature) throws IllegalArgumentException {
	try {
		int count = 0;
		int i = CharOperation.indexOf(C_PARAM_START, methodSignature) + 1;
		if (i == 0)
			throw new IllegalArgumentException();
		for (;;) {
			char c = methodSignature[i++];
			switch (c) {
				case C_ARRAY :
					break;
				case C_BOOLEAN :
				case C_BYTE :
				case C_CHAR :
				case C_DOUBLE :
				case C_FLOAT :
				case C_INT :
				case C_LONG :
				case C_SHORT :
				case C_VOID :
					++count;
					break;
				case C_RESOLVED :
				case C_UNRESOLVED :
					i = CharOperation.indexOf(C_SEMICOLON, methodSignature, i) + 1;
					if (i == 0)
						throw new IllegalArgumentException();
					++count;
					break;
				case C_PARAM_END :
					return count;
				default :
					throw new IllegalArgumentException();
			}
		}
	} catch (ArrayIndexOutOfBoundsException e) {
		throw new IllegalArgumentException();
	}
}
/**
 * Returns the number of parameter types in the given method signature.
 *
 * @param methodSignature the method signature
 * @return the number of parameters
 * @exception IllegalArgumentException if the signature is not syntactically
 *   correct
 */
public static int getParameterCount(String methodSignature) throws IllegalArgumentException {
	return getParameterCount(methodSignature.toCharArray());
}
/**
 * Extracts the parameter type signatures from the given method signature. 
 * The method signature is expected to be dot-based.
 *
 * @param methodSignature the method signature
 * @return the list of parameter type signatures
 * @exception IllegalArgumentException if the signature is syntactically
 *   incorrect
 * 
 * @since 2.0
 */
public static char[][] getParameterTypes(char[] methodSignature) throws IllegalArgumentException {
	try {
		int count = getParameterCount(methodSignature);
		char[][] result = new char[count][];
		if (count == 0)
			return result;
		int i = CharOperation.indexOf(C_PARAM_START, methodSignature) + 1;
		count = 0;
		int start = i;
		for (;;) {
			char c = methodSignature[i++];
			switch (c) {
				case C_ARRAY :
					// array depth is i - start;
					break;
				case C_BOOLEAN :
				case C_BYTE :
				case C_CHAR :
				case C_DOUBLE :
				case C_FLOAT :
				case C_INT :
				case C_LONG :
				case C_SHORT :
				case C_VOID :
					// common case of base types
					if (i - start == 1) {
						switch (c) {
							case C_BOOLEAN :
								result[count++] = new char[] {C_BOOLEAN};
								break;
							case C_BYTE :
								result[count++] = new char[] {C_BYTE};
								break;
							case C_CHAR :
								result[count++] = new char[] {C_CHAR};
								break;
							case C_DOUBLE :
								result[count++] = new char[] {C_DOUBLE};
								break;
							case C_FLOAT :
								result[count++] = new char[] {C_FLOAT};
								break;
							case C_INT :
								result[count++] = new char[] {C_INT};
								break;
							case C_LONG :
								result[count++] = new char[] {C_LONG};
								break;
							case C_SHORT :
								result[count++] = new char[] {C_SHORT};
								break;
							case C_VOID :
								result[count++] = new char[] {C_VOID};
								break;
						}
					} else {
						result[count++] = CharOperation.subarray(methodSignature, start, i);
					}
					start = i;
					break;
				case C_RESOLVED :
				case C_UNRESOLVED :
					i = CharOperation.indexOf(C_SEMICOLON, methodSignature, i) + 1;
					if (i == 0)
						throw new IllegalArgumentException();
					result[count++] = CharOperation.subarray(methodSignature, start, i);
					start = i;
					break;
				case C_PARAM_END:
					return result;
				default :
					throw new IllegalArgumentException();
			}
		}
	} catch (ArrayIndexOutOfBoundsException e) {
		throw new IllegalArgumentException();
	}
}
/**
 * Extracts the parameter type signatures from the given method signature. 
 * The method signature is expected to be dot-based.
 *
 * @param methodSignature the method signature
 * @return the list of parameter type signatures
 * @exception IllegalArgumentException if the signature is syntactically
 *   incorrect
 */
public static String[] getParameterTypes(String methodSignature) throws IllegalArgumentException {
	char[][] parameterTypes = getParameterTypes(methodSignature.toCharArray());
	int length = parameterTypes.length;
	String[] result = new String[length];
	for (int i = 0; i < length; i++) {
		result[i] = new String(parameterTypes[i]);
	}
	return result;
}
/**
 * Returns a char array containing all but the last segment of the given 
 * dot-separated qualified name. Returns the empty char array if it is not qualified.
 * <p>
 * For example:
 * <pre>
 * <code>
 * getQualifier({'j', 'a', 'v', 'a', '.', 'l', 'a', 'n', 'g', '.', 'O', 'b', 'j', 'e', 'c', 't'}) -> {'j', 'a', 'v', 'a', '.', 'l', 'a', 'n', 'g'}
 * getQualifier({'O', 'u', 't', 'e', 'r', '.', 'I', 'n', 'n', 'e', 'r'}) -> {'O', 'u', 't', 'e', 'r'}
 * </code>
 * </pre>
 * </p>
 *
 * @param name the name
 * @return the qualifier prefix, or the empty char array if the name contains no
 *   dots
 * 
 * @since 2.0
 */
public static char[] getQualifier(char[] name) {
	int lastDot = CharOperation.lastIndexOf(C_DOT, name);
	if (lastDot == -1) {
		return NO_CHAR; //$NON-NLS-1$
	}
	return CharOperation.subarray(name, 0, lastDot);
}
/**
 * Returns a string containing all but the last segment of the given 
 * dot-separated qualified name. Returns the empty string if it is not qualified.
 * <p>
 * For example:
 * <pre>
 * <code>
 * getQualifier("java.lang.Object") -> "java.lang"
 * getQualifier("Outer.Inner") -> "Outer"
 * </code>
 * </pre>
 * </p>
 *
 * @param name the name
 * @return the qualifier prefix, or the empty string if the name contains no
 *   dots
 */
public static String getQualifier(String name) {
	return new String(getQualifier(name.toCharArray()));
}
/**
 * Extracts the return type from the given method signature. The method signature is 
 * expected to be dot-based.
 *
 * @param methodSignature the method signature
 * @return the type signature of the return type
 * @exception IllegalArgumentException if the signature is syntactically
 *   incorrect
 * 
 * @since 2.0
 */
public static char[] getReturnType(char[] methodSignature) throws IllegalArgumentException {
	int i = CharOperation.lastIndexOf(C_PARAM_END, methodSignature);
	if (i == -1) {
		throw new IllegalArgumentException();
	}
	return CharOperation.subarray(methodSignature, i + 1, methodSignature.length);
}
/**
 * Extracts the return type from the given method signature. The method signature is 
 * expected to be dot-based.
 *
 * @param methodSignature the method signature
 * @return the type signature of the return type
 * @exception IllegalArgumentException if the signature is syntactically
 *   incorrect
 */
public static String getReturnType(String methodSignature) throws IllegalArgumentException {
	return new String(getReturnType(methodSignature.toCharArray()));
}
/**
 * Returns the last segment of the given dot-separated qualified name.
 * Returns the given name if it is not qualified.
 * <p>
 * For example:
 * <pre>
 * <code>
 * getSimpleName({'j', 'a', 'v', 'a', '.', 'l', 'a', 'n', 'g', '.', 'O', 'b', 'j', 'e', 'c', 't'}) -> {'O', 'b', 'j', 'e', 'c', 't'}
 * </code>
 * </pre>
 * </p>
 *
 * @param name the name
 * @return the last segment of the qualified name
 * 
 * @since 2.0
 */
public static char[] getSimpleName(char[] name) {
	int lastDot = CharOperation.lastIndexOf(C_DOT, name);
	if (lastDot == -1) {
		return name;
	}
	return CharOperation.subarray(name, lastDot + 1, name.length);
}
/**
 * Returns the last segment of the given dot-separated qualified name.
 * Returns the given name if it is not qualified.
 * <p>
 * For example:
 * <pre>
 * <code>
 * getSimpleName("java.lang.Object") -> "Object"
 * </code>
 * </pre>
 * </p>
 *
 * @param name the name
 * @return the last segment of the qualified name
 */
public static String getSimpleName(String name) {
	return new String(getSimpleName(name.toCharArray()));
}
/**
 * Returns all segments of the given dot-separated qualified name.
 * Returns an array with only the given name if it is not qualified.
 * Returns an empty array if the name is empty.
 * <p>
 * For example:
 * <pre>
 * <code>
 * getSimpleNames({'j', 'a', 'v', 'a', '.', 'l', 'a', 'n', 'g', '.', 'O', 'b', 'j', 'e', 'c', 't'}) -> {{'j', 'a', 'v', 'a'}, {'l', 'a', 'n', 'g'}, {'O', 'b', 'j', 'e', 'c', 't'}}
 * getSimpleNames({'O', 'b', 'j', 'e', 'c', 't'}) -> {{'O', 'b', 'j', 'e', 'c', 't'}}
 * getSimpleNames("") -> {}
 * </code>
 * </pre>
 *
 * @param name the name
 * @return the list of simple names, possibly empty
 * 
 * @since 2.0
 */
public static char[][] getSimpleNames(char[] name) {
	if (name.length == 0) {
		return NO_CHAR_CHAR;
	}
	int dot = CharOperation.indexOf(C_DOT, name);
	if (dot == -1) {
		return new char[][] {name};
	}
	int n = 1;
	while ((dot = CharOperation.indexOf(C_DOT, name, dot + 1)) != -1) {
		++n;
	}
	char[][] result = new char[n + 1][];
	int segStart = 0;
	for (int i = 0; i < n; ++i) {
		dot = CharOperation.indexOf(C_DOT, name, segStart);
		result[i] = CharOperation.subarray(name, segStart, dot);
		segStart = dot + 1;
	}
	result[n] = CharOperation.subarray(name, segStart, name.length);
	return result;
}
/**
 * Returns all segments of the given dot-separated qualified name.
 * Returns an array with only the given name if it is not qualified.
 * Returns an empty array if the name is empty.
 * <p>
 * For example:
 * <pre>
 * <code>
 * getSimpleNames("java.lang.Object") -> {"java", "lang", "Object"}
 * getSimpleNames("Object") -> {"Object"}
 * getSimpleNames("") -> {}
 * </code>
 * </pre>
 *
 * @param name the name
 * @return the list of simple names, possibly empty
 */
public static String[] getSimpleNames(String name) {
	char[][] simpleNames = getSimpleNames(name.toCharArray());
	int length = simpleNames.length;
	String[] result = new String[length];
	for (int i = 0; i < length; i++) {
		result[i] = new String(simpleNames[i]);
	}
	return result;
}
/**
 * Converts the given method signature to a readable form. The method signature is expected to
 * be dot-based.
 * <p>
 * For example:
 * <pre>
 * <code>
 * toString("([Ljava.lang.String;)V", "main", new String[] {"args"}, false, true) -> "void main(String[] args)"
 * </code>
 * </pre>
 * </p>
 * 
 * @param methodSignature the method signature to convert
 * @param methodName the name of the method to insert in the result, or 
 *   <code>null</code> if no method name is to be included
 * @param parameterNames the parameter names to insert in the result, or 
 *   <code>null</code> if no parameter names are to be included; if supplied,
 *   the number of parameter names must match that of the method signature
 * @param fullyQualifyTypeNames <code>true</code> if type names should be fully
 *   qualified, and <code>false</code> to use only simple names
 * @param includeReturnType <code>true</code> if the return type is to be
 *   included
 * @return the char array representation of the method signature
 * 
 * @since 2.0
 */
public static char[] toCharArray(char[] methodSignature, char[] methodName, char[][] parameterNames, boolean fullyQualifyTypeNames, boolean includeReturnType) {
	try {
		int firstParen = CharOperation.indexOf(C_PARAM_START, methodSignature);
		if (firstParen == -1) throw new IllegalArgumentException();
		
		int sigLength = methodSignature.length;
		
		// compute result length
		
		// method signature
		int paramCount = 0;
		int lastParen = -1;
		int resultLength = 0;
		signature: for (int i = firstParen; i < sigLength; i++) {
			switch (methodSignature[i]) {
				case C_ARRAY :
					resultLength += 2; // []
					continue signature;
				case C_BOOLEAN :
					resultLength += BOOLEAN.length;
					break;
				case C_BYTE :
					resultLength += BYTE.length;
					break;
				case C_CHAR :
					resultLength += CHAR.length;
					break;
				case C_DOUBLE :
					resultLength += DOUBLE.length;
					break;
				case C_FLOAT :
					resultLength += FLOAT.length;
					break;
				case C_INT :
					resultLength += INT.length;
					break;
				case C_LONG :
					resultLength += LONG.length;
					break;
				case C_SHORT :
					resultLength += SHORT.length;
					break;
				case C_VOID :
					resultLength += VOID.length;
					break;
				case C_RESOLVED :
				case C_UNRESOLVED :
					int end = CharOperation.indexOf(C_SEMICOLON, methodSignature, i);
					if (end == -1) throw new IllegalArgumentException();
					int start;
					if (fullyQualifyTypeNames) {
						start = i+1;
					} else {
						start = CharOperation.lastIndexOf(C_DOT, methodSignature, i, end) + 1;
						if (start == 0) start = i+1;
					} 
					resultLength += end-start;
					i = end;
					break;
				case C_PARAM_START :
					// add space for "("
					resultLength++;
					continue signature;
				case C_PARAM_END :
					lastParen = i;
					if (includeReturnType) {
						if (paramCount > 0) {
							// remove space for ", " that was added with last parameter and remove space that is going to be added for ", " after return type 
							// and add space for ") "
							resultLength -= 2;
						} //else
							// remove space that is going to be added for ", " after return type 
							// and add space for ") "
							// -> noop
						
						// decrement param count because it is going to be added for return type
						paramCount--;
						continue signature;
					} else {
						if (paramCount > 0) {
							// remove space for ", " that was added with last parameter and add space for ")"
							resultLength--;
						} else {
							// add space for ")"
							resultLength++;
						}
						break signature;
					}
				default :
					throw new IllegalArgumentException();
			}
			resultLength += 2; // add space for ", "
			paramCount++;
		}
		
		// parameter names
		int parameterNamesLength = parameterNames == null ? 0 : parameterNames.length;
		for (int i = 0; i <parameterNamesLength; i++) {
			resultLength += parameterNames[i].length + 1; // parameter name + space
		}
		
		// selector
		int selectorLength = methodName == null ? 0 : methodName.length;
		resultLength += selectorLength;
		
		// create resulting char array
		char[] result = new char[resultLength];
		
		// returned type
		int index = 0;
		if (includeReturnType) {
			long pos = copyType(methodSignature, lastParen+1, result, index, fullyQualifyTypeNames);
			index = (int) (pos >>> 32);
			result[index++] = ' ';
		}
		
		// selector
		if (methodName != null) {
			System.arraycopy(methodName, 0, result, index, selectorLength);
			index += selectorLength;
		}
		
		// parameters
		result[index++] = C_PARAM_START;
		int sigPos = firstParen+1;
		for (int i = 0; i < paramCount; i++) {
			long pos = copyType(methodSignature, sigPos, result, index, fullyQualifyTypeNames);
			index = (int) (pos >>> 32);
			sigPos = (int)pos;
			if (parameterNames != null) {
				result[index++] = ' ';
				char[] parameterName = parameterNames[i];
				int paramLength = parameterName.length;
				System.arraycopy(parameterName, 0, result, index, paramLength);
				index += paramLength;
			}
			if (i != paramCount-1) {
				result[index++] = ',';
				result[index++] = ' ';
			}
		}
		if (sigPos >= sigLength) {
			throw new IllegalArgumentException(); // should be on last paren
		}
		result[index++] = C_PARAM_END;
		
		return result;
	} catch (ArrayIndexOutOfBoundsException e) {
		throw new IllegalArgumentException();
	}		
}
/**
 * Converts the given type signature to a readable string. The signature is expected to
 * be dot-based.
 * 
 * <p>
 * For example:
 * <pre>
 * <code>
 * toString({'[', 'L', 'j', 'a', 'v', 'a', '.', 'l', 'a', 'n', 'g', '.', 'S', 't', 'r', 'i', 'n', 'g', ';'}) -> {'j', 'a', 'v', 'a', '.', 'l', 'a', 'n', 'g', '.', 'S', 't', 'r', 'i', 'n', 'g', '[', ']'}
 * toString({'I'}) -> {'i', 'n', 't'}
 * </code>
 * </pre>
 * </p>
 * <p>
 * Note: This method assumes that a type signature containing a <code>'$'</code>
 * is an inner type signature. While this is correct in most cases, someone could 
 * define a non-inner type name containing a <code>'$'</code>. Handling this 
 * correctly in all cases would have required resolving the signature, which 
 * generally not feasible.
 * </p>
 *
 * @param signature the type signature
 * @return the string representation of the type
 * @exception IllegalArgumentException if the signature is not syntactically
 *   correct
 * 
 * @since 2.0
 */
public static char[] toCharArray(char[] signature) throws IllegalArgumentException {
	try {
		int sigLength = signature.length;

		if (sigLength == 0 || signature[0] == C_PARAM_START) {
			return toCharArray(signature, NO_CHAR, null, true, true);
		}
		
		// compute result length
		int resultLength = 0;
		int index = -1;
		while (signature[++index] == C_ARRAY) {
			resultLength += 2; // []
		}
		switch (signature[index]) {
			case C_BOOLEAN :
				resultLength += BOOLEAN.length;
				break;
			case C_BYTE :
				resultLength += BYTE.length;
				break;
			case C_CHAR :
				resultLength += CHAR.length;
				break;
			case C_DOUBLE :
				resultLength += DOUBLE.length;
				break;
			case C_FLOAT :
				resultLength += FLOAT.length;
				break;
			case C_INT :
				resultLength += INT.length;
				break;
			case C_LONG :
				resultLength += LONG.length;
				break;
			case C_SHORT :
				resultLength += SHORT.length;
				break;
			case C_VOID :
				resultLength += VOID.length;
				break;
			case C_RESOLVED :
			case C_UNRESOLVED :
				int end = CharOperation.indexOf(C_SEMICOLON, signature, index);
				if (end == -1) throw new IllegalArgumentException();
				int start = index + 1;
				resultLength += end-start;
				break;
			default :
				throw new IllegalArgumentException();
		}
		
		char[] result = new char[resultLength];
		copyType(signature, 0, result, 0, true);

		/**
		 * Converts '$' separated type signatures into '.' separated type signature.
		 * NOTE: This assumes that the type signature is an inner type signature.
		 *       This is true in most cases, but someone can define a non-inner type 
		 *       name containing a '$'. However to tell the difference, we would have
		 *       to resolve the signature, which cannot be done at this point.
		 */
		CharOperation.replace(result, C_DOLLAR, C_DOT);

		return result;
	} catch (ArrayIndexOutOfBoundsException e) {
		throw new IllegalArgumentException();
	}	
}
/**
 * Converts the given array of qualified name segments to a qualified name.
 * <p>
 * For example:
 * <pre>
 * <code>
 * toQualifiedName({{'j', 'a', 'v', 'a'}, {'l', 'a', 'n', 'g'}, {'O', 'b', 'j', 'e', 'c', 't'}}) -> {'j', 'a', 'v', 'a', '.', 'l', 'a', 'n', 'g', '.', 'O', 'b', 'j', 'e', 'c', 't'}
 * toQualifiedName({{'O', 'b', 'j', 'e', 'c', 't'}}) -> {'O', 'b', 'j', 'e', 'c', 't'}
 * toQualifiedName({{}}) -> {}
 * </code>
 * </pre>
 * </p>
 *
 * @param segments the list of name segments, possibly empty
 * @return the dot-separated qualified name, or the empty string
 * 
 * @since 2.0
 */
public static char[] toQualifiedName(char[][] segments) {
	int length = segments.length;
	if (length == 0) return NO_CHAR;
	if (length == 1) return segments[0];
	
	int resultLength = 0;
	for (int i = 0; i < length; i++) {
		resultLength += segments[i].length+1;
	}
	resultLength--;
	char[] result = new char[resultLength];
	int index = 0;
	for (int i = 0; i < length; i++) {
		char[] segment = segments[i];
		int segmentLength = segment.length;
		System.arraycopy(segment, 0, result, index, segmentLength);
		index += segmentLength;
		if (i != length-1) {
			result[index++] = C_DOT;
		}
	}
	return result;
}
/**
 * Converts the given array of qualified name segments to a qualified name.
 * <p>
 * For example:
 * <pre>
 * <code>
 * toQualifiedName(new String[] {"java", "lang", "Object"}) -> "java.lang.Object"
 * toQualifiedName(new String[] {"Object"}) -> "Object"
 * toQualifiedName(new String[0]) -> ""
 * </code>
 * </pre>
 * </p>
 *
 * @param segments the list of name segments, possibly empty
 * @return the dot-separated qualified name, or the empty string
 */
public static String toQualifiedName(String[] segments) {
	int length = segments.length;
	char[][] charArrays = new char[length][];
	for (int i = 0; i < length; i++) {
		charArrays[i] = segments[i].toCharArray();
	}
	return new String(toQualifiedName(charArrays));
}
/**
 * Converts the given type signature to a readable string. The signature is expected to
 * be dot-based.
 * 
 * <p>
 * For example:
 * <pre>
 * <code>
 * toString("[Ljava.lang.String;") -> "java.lang.String[]"
 * toString("I") -> "int"
 * </code>
 * </pre>
 * </p>
 * <p>
 * Note: This method assumes that a type signature containing a <code>'$'</code>
 * is an inner type signature. While this is correct in most cases, someone could 
 * define a non-inner type name containing a <code>'$'</code>. Handling this 
 * correctly in all cases would have required resolving the signature, which 
 * generally not feasible.
 * </p>
 *
 * @param signature the type signature
 * @return the string representation of the type
 * @exception IllegalArgumentException if the signature is not syntactically
 *   correct
 */
public static String toString(String signature) throws IllegalArgumentException {
	return new String(toCharArray(signature.toCharArray()));
}
/**
 * Converts the given method signature to a readable string. The method signature is expected to
 * be dot-based.
 * <p>
 * For example:
 * <pre>
 * <code>
 * toString("([Ljava.lang.String;)V", "main", new String[] {"args"}, false, true) -> "void main(String[] args)"
 * </code>
 * </pre>
 * </p>
 * 
 * @param methodSignature the method signature to convert
 * @param methodName the name of the method to insert in the result, or 
 *   <code>null</code> if no method name is to be included
 * @param parameterNames the parameter names to insert in the result, or 
 *   <code>null</code> if no parameter names are to be included; if supplied,
 *   the number of parameter names must match that of the method signature
 * @param fullyQualifyTypeNames <code>true</code> if type names should be fully
 *   qualified, and <code>false</code> to use only simple names
 * @param includeReturnType <code>true</code> if the return type is to be
 *   included
 * @return the string representation of the method signature
 */
public static String toString(String methodSignature, String methodName, String[] parameterNames, boolean fullyQualifyTypeNames, boolean includeReturnType) {
	char[][] params;
	if (parameterNames == null) {
		params = null;
	} else {
		int paramLength = parameterNames.length;
		params = new char[paramLength][];
		for (int i = 0; i < paramLength; i++) {
			params[i] = parameterNames[i].toCharArray();
		}
	}
	return new String(toCharArray(methodSignature.toCharArray(), methodName == null ? null : methodName.toCharArray(), params, fullyQualifyTypeNames, includeReturnType));
}
}
