/*******************************************************************************
- * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others.
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v0.5
+ * are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v05.html
+ * http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
- ******************************************************************************/
+ *******************************************************************************/
package net.sourceforge.phpdt.core;
-import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
-import net.sourceforge.phpdt.core.compiler.InvalidInputException;
-import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
-import net.sourceforge.phpdt.internal.compiler.util.CharOperation;
+import net.sourceforge.phpdt.core.compiler.CharOperation;
/**
* Provides methods for encoding and decoding type and method signature strings.
* | "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)
+ * | "L" + binaryTypeName + ";" // resolved named type (in compiled code)
+ * | "Q" + sourceTypeName + ";" // unresolved named type (in source code)
* | "[" + typeSignature // array of type denoted by typeSignature
* </pre>
* </p>
*/
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[] SHORT = {'s', 'h', 'o', 'r', 't'};
private static final char[] VOID = {'v', 'o', 'i', 'd'};
+ private static final String EMPTY = new String(CharOperation.NO_CHAR);
/**
* Not instantiable.
* @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;
+
+ if (typeName == null) throw new IllegalArgumentException("null"); //$NON-NLS-1$
+ int length = typeName.length;
+ if (length == 0) throw new IllegalArgumentException(new String(typeName));
+
+ int arrayCount = CharOperation.occurencesOf('[', typeName);
+ char[] sig;
+
+ switch (typeName[0]) {
+ // primitive type?
+ case 'b' :
+ if (CharOperation.fragmentEquals(BOOLEAN, typeName, 0, true)) {
+ sig = new char[arrayCount+1];
+ sig[arrayCount] = C_BOOLEAN;
+ break;
+ } else if (CharOperation.fragmentEquals(BYTE, typeName, 0, true)) {
+ sig = new char[arrayCount+1];
+ sig[arrayCount] = C_BYTE;
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();
+ case 'c':
+ if (CharOperation.fragmentEquals(CHAR, typeName, 0, true)) {
+ sig = new char[arrayCount+1];
+ sig[arrayCount] = C_CHAR;
+ break;
+ }
+ case 'd':
+ if (CharOperation.fragmentEquals(DOUBLE, typeName, 0, true)) {
+ sig = new char[arrayCount+1];
+ sig[arrayCount] = C_DOUBLE;
+ break;
+ }
+ case 'f':
+ if (CharOperation.fragmentEquals(FLOAT, typeName, 0, true)) {
+ sig = new char[arrayCount+1];
+ sig[arrayCount] = C_FLOAT;
+ break;
+ }
+ case 'i':
+ if (CharOperation.fragmentEquals(INT, typeName, 0, true)) {
+ sig = new char[arrayCount+1];
+ sig[arrayCount] = C_INT;
+ break;
+ }
+ case 'l':
+ if (CharOperation.fragmentEquals(LONG, typeName, 0, true)) {
+ sig = new char[arrayCount+1];
+ sig[arrayCount] = C_LONG;
+ break;
+ }
+ case 's':
+ if (CharOperation.fragmentEquals(SHORT, typeName, 0, true)) {
+ sig = new char[arrayCount+1];
+ sig[arrayCount] = C_SHORT;
+ break;
+ }
+ case 'v':
+ if (CharOperation.fragmentEquals(VOID, typeName, 0, true)) {
+ sig = new char[arrayCount+1];
+ sig[arrayCount] = C_VOID;
+ break;
+ }
+ default:
+ // non primitive type
+ int sigLength = arrayCount + 1 + length + 1; // for example '[[[Ljava.lang.String;'
+ sig = new char[sigLength];
+ int sigIndex = arrayCount+1; // index in sig
+ int startID = 0; // start of current ID in typeName
+ int index = 0; // index in typeName
+ while (index < length) {
+ char currentChar = typeName[index];
+ switch (currentChar) {
+ case '.':
+ if (startID == -1) throw new IllegalArgumentException(new String(typeName));
+ if (startID < index) {
+ sig = CharOperation.append(sig, sigIndex, typeName, startID, index);
+ sigIndex += index-startID;
+ }
+ sig[sigIndex++] = C_DOT;
+ index++;
+ startID = index;
+ break;
+ case '[':
+ if (startID != -1) {
+ if (startID < index) {
+ sig = CharOperation.append(sig, sigIndex, typeName, startID, index);
+ sigIndex += index-startID;
+ }
+ startID = -1; // no more id after []
+ }
+ index++;
+ break;
+ default :
+ if (startID != -1 && CharOperation.isWhitespace(currentChar)) {
+ if (startID < index) {
+ sig = CharOperation.append(sig, sigIndex, typeName, startID, index);
+ sigIndex += index-startID;
+ }
+ startID = index+1;
+ }
+ index++;
+ break;
+ }
+ }
+ // last id
+ if (startID != -1 && startID < index) {
+ sig = CharOperation.append(sig, sigIndex, typeName, startID, index);
+ sigIndex += index-startID;
+ }
+
+ // add L (or Q) at the beigininig and ; at the end
+ sig[arrayCount] = isResolved ? C_RESOLVED : C_UNRESOLVED;
+ sig[sigIndex++] = C_NAME_END;
+
+ // resize if needed
+ if (sigLength > sigIndex) {
+ System.arraycopy(sig, 0, sig = new char[sigIndex], 0, sigIndex);
+ }
}
+
+ // add array info
+ for (int i = 0; i < arrayCount; i++) {
+ sig[i] = C_ARRAY;
+ }
+
+ return sig;
}
/**
* Creates a new type signature from the given type name. If the type name is qualified,
* @return the encoded type signature
*/
public static String createTypeSignature(String typeName, boolean isResolved) {
- return createTypeSignature(typeName.toCharArray(), isResolved);
+ return createTypeSignature(typeName == null ? null : typeName.toCharArray(), isResolved);
}
/**
* Returns the array count (array nesting depth) of the given type signature.
* @param name the name
* @return the qualifier prefix, or the empty char array if the name contains no
* dots
- *
+ * @exception NullPointerException if name is null
* @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.NO_CHAR;
}
return CharOperation.subarray(name, 0, lastDot);
}
* @param name the name
* @return the qualifier prefix, or the empty string if the name contains no
* dots
+ * @exception NullPointerException if name is null
*/
public static String getQualifier(String name) {
- return new String(getQualifier(name.toCharArray()));
+ int lastDot = name.lastIndexOf(C_DOT);
+ if (lastDot == -1) {
+ return EMPTY;
+ }
+ return name.substring(0, lastDot);
}
/**
* Extracts the return type from the given method signature. The method signature is
*
* @param name the name
* @return the last segment of the qualified name
- *
+ * @exception NullPointerException if name is null
* @since 2.0
*/
public static char[] getSimpleName(char[] name) {
*
* @param name the name
* @return the last segment of the qualified name
+ * @exception NullPointerException if name is null
*/
public static String getSimpleName(String name) {
- return new String(getSimpleName(name.toCharArray()));
+ int lastDot = name.lastIndexOf(C_DOT);
+ if (lastDot == -1) {
+ return name;
+ }
+ return name.substring(lastDot + 1, name.length());
}
/**
* Returns all segments of the given dot-separated qualified name.
*
* @param name the name
* @return the list of simple names, possibly empty
- *
+ * @exception NullPointerException if name is null
* @since 2.0
*/
public static char[][] getSimpleNames(char[] name) {
if (name.length == 0) {
- return NO_CHAR_CHAR;
+ return CharOperation.NO_CHAR_CHAR;
}
int dot = CharOperation.indexOf(C_DOT, name);
if (dot == -1) {
*
* @param name the name
* @return the list of simple names, possibly empty
+ * @exception NullPointerException if name is null
*/
public static String[] getSimpleNames(String name) {
char[][] simpleNames = getSimpleNames(name.toCharArray());
int sigLength = signature.length;
if (sigLength == 0 || signature[0] == C_PARAM_START) {
- return toCharArray(signature, NO_CHAR, null, true, true);
+ return toCharArray(signature, CharOperation.NO_CHAR, null, true, true);
}
// compute result length
*/
public static char[] toQualifiedName(char[][] segments) {
int length = segments.length;
- if (length == 0) return NO_CHAR;
+ if (length == 0) return CharOperation.NO_CHAR;
if (length == 1) return segments[0];
int resultLength = 0;
* correct
*/
public static String toString(String signature) throws IllegalArgumentException {
- return new String(toCharArray(signature.toCharArray()));
+// return new String(toCharArray(signature.toCharArray()));
+ return "";
}
/**
* Converts the given method signature to a readable string. The method signature is expected to