added class fields to outline
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / core / Signature.java
index 18d3336..de4c360 100644 (file)
@@ -1,19 +1,16 @@
 /*******************************************************************************
- * 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.
@@ -30,8 +27,8 @@ import net.sourceforge.phpdt.internal.compiler.util.CharOperation;
  *   | "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>
@@ -228,8 +225,6 @@ public final class Signature {
         */
        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'};
@@ -240,6 +235,7 @@ public final class Signature {
        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.
@@ -436,90 +432,132 @@ public static String createTypeSignature(char[] typeName, boolean isResolved) {
  * @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,
@@ -545,7 +583,7 @@ public static char[] createCharArrayTypeSignature(char[] typeName, boolean isRes
  * @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.
@@ -806,13 +844,13 @@ public static String[] getParameterTypes(String methodSignature) throws IllegalA
  * @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);
 }
@@ -832,9 +870,14 @@ public static char[] getQualifier(char[] name) {
  * @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 
@@ -880,7 +923,7 @@ public static String getReturnType(String methodSignature) throws IllegalArgumen
  *
  * @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) {
@@ -904,9 +947,14 @@ 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.
@@ -924,12 +972,12 @@ public static String getSimpleName(String 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) {
@@ -965,6 +1013,7 @@ public static char[][] getSimpleNames(char[] name) {
  *
  * @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());
@@ -1185,7 +1234,7 @@ public static char[] toCharArray(char[] signature) throws IllegalArgumentExcepti
                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
@@ -1270,7 +1319,7 @@ public static char[] toCharArray(char[] signature) throws IllegalArgumentExcepti
  */
 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;
@@ -1342,7 +1391,8 @@ public static String toQualifiedName(String[] segments) {
  *   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