Improved calculation of function/methods sourceEnd for code folding
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpeclipse / builder / IdentifierIndexManager.java
index 7b7954c..8e859cf 100644 (file)
@@ -11,6 +11,7 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Comparator;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
@@ -53,6 +54,24 @@ public class IdentifierIndexManager {
      *          current identifier
      * @param line
      *          Buffer for the current index line
+     */
+    private void addIdentifierInformation(char typeOfIdentifier, char[] identifier, StringBuffer line) {
+      line.append('\t');
+      line.append(typeOfIdentifier);
+      line.append(identifier);
+      //      line.append("\to"); // Offset
+      //      line.append(fScanner.getCurrentTokenStartPosition());
+    }
+
+    /**
+     * Add the information of the current identifier to the line
+     * 
+     * @param typeOfIdentifier
+     *          the type of the identifier ('c'lass, 'd'efine, 'f'unction, 'm'ethod(class), 'v'ariable(class) 'g'lobal variable)
+     * @param identifier
+     *          current identifier
+     * @param line
+     *          Buffer for the current index line
      * @param phpdocOffset
      *          the offset of the PHPdoc comment if available
      * @param phpdocLength
@@ -161,6 +180,30 @@ public class IdentifierIndexManager {
               ident = fScanner.getCurrentIdentifierSource();
               addIdentifierInformation('c', ident, buf, phpdocOffset, phpdocLength);
               getNextToken();
+              if (fToken == TokenNameextends) {
+                getNextToken();
+                while (fToken == TokenNameIdentifier) {
+                  ident = fScanner.getCurrentIdentifierSource();
+                  // extends ident
+                  addIdentifierInformation('e', ident, buf);
+                  getNextToken();
+                  if (fToken == TokenNameCOMMA) {
+                    getNextToken();
+                  }
+                }
+              }
+              if (fToken == TokenNameimplements) {
+                getNextToken();
+                while (fToken == TokenNameIdentifier) {
+                  ident = fScanner.getCurrentIdentifierSource();
+                  // implements ident
+                  addIdentifierInformation('e', ident, buf);
+                  getNextToken();
+                  if (fToken == TokenNameCOMMA) {
+                    getNextToken();
+                  }
+                }
+              }
               //skip tokens for classname, extends and others until we have
               // the opening '{'
               while (fToken != TokenNameLBRACE && fToken != TokenNameEOF && fToken != TokenNameERROR) {
@@ -276,6 +319,30 @@ public class IdentifierIndexManager {
               ident = fScanner.getCurrentIdentifierSource();
               addIdentifierInformation('c', ident, buf, phpdocOffset, phpdocLength);
               getNextToken();
+              if (fToken == TokenNameextends) {
+                getNextToken();
+                while (fToken == TokenNameIdentifier) {
+                  ident = fScanner.getCurrentIdentifierSource();
+                  // extends ident
+                  addIdentifierInformation('e', ident, buf);
+                  getNextToken();
+                  if (fToken == TokenNameCOMMA) {
+                    getNextToken();
+                  }
+                }
+              }
+              if (fToken == TokenNameimplements) {
+                getNextToken();
+                while (fToken == TokenNameIdentifier) {
+                  ident = fScanner.getCurrentIdentifierSource();
+                  // implements ident
+                  addIdentifierInformation('e', ident, buf);
+                  getNextToken();
+                  if (fToken == TokenNameCOMMA) {
+                    getNextToken();
+                  }
+                }
+              }
               //skip fTokens for classname, extends and others until we have
               // the opening '{'
               while (fToken != TokenNameLBRACE && fToken != TokenNameEOF && fToken != TokenNameERROR) {
@@ -415,6 +482,75 @@ public class IdentifierIndexManager {
    * @param line
    */
   private void addLine(String line) {
+    addLine(fIndentifierMap, fFileMap, line, null);
+  }
+
+  public TreeMap getIdentifiers(IFile file) {
+    TreeMap treeMap = new TreeMap(new StringComparator());
+    addIdentifiers(treeMap, file);
+    return treeMap;
+  }
+  public TreeMap getIdentifiers(String startClazz) {
+    TreeMap treeMap = new TreeMap(new StringComparator());
+    addIdentifiers(treeMap, startClazz);
+    return treeMap;
+  }
+  
+  public void addIdentifiers(TreeMap treeMap, IFile file) {
+    String line = (String) fFileMap.get(file.getProjectRelativePath().toString());
+    if (line != null) {
+      PHPIdentifierLocation ident;
+      ArrayList allClassNames = new ArrayList();
+      addLine(treeMap, null, line, allClassNames);
+      int i=0;
+      while (i<allClassNames.size()) {
+        String clazz = (String) allClassNames.get(i++);
+        addClassName(treeMap, clazz, allClassNames);
+      }
+    }
+  }
+
+  public void addIdentifiers(TreeMap treeMap, String startClazz) {
+    PHPIdentifierLocation ident;
+    ArrayList allClassNames = new ArrayList();
+    addClassName(treeMap, startClazz, allClassNames);
+    int i=0;
+    while (i<allClassNames.size()) {
+      String clazz = (String) allClassNames.get(i++);
+      addClassName(treeMap, clazz, allClassNames);
+    }
+  }
+
+  /**
+   * @param treeMap
+   * @param clazz
+   * @param allClassNames
+   */
+  private boolean addClassName(TreeMap treeMap, String clazz, List allClassNames) {
+    String line;
+    PHPIdentifierLocation ident;
+    List list = getLocations(clazz);
+    if (list==null) {
+      return false;
+    }
+    boolean result = false;
+    for (int i = 0; i < list.size(); i++) {
+      ident = (PHPIdentifierLocation) list.get(i);
+      if (ident.isClass()) {
+        line = (String) fFileMap.get(ident.getFilename());
+        addLine(treeMap, null, line, allClassNames);
+        result = true;
+      }
+    }
+    return result;
+  }
+
+  /**
+   * Adds a line of the index file for function, class, class-method and class-variable names
+   * 
+   * @param line
+   */
+  public void addLine(TreeMap treeMap, HashMap fileMap, String line, List allClassNames) {
     StringTokenizer tokenizer;
     String phpFileName = null;
     String token;
@@ -448,6 +584,18 @@ public class IdentifierIndexManager {
           identifier = token.substring(1);
           phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.DEFINE, phpFileName);
           break;
+        case 'e':
+          // extends <class name>
+          // not in map
+          identifier = null;
+          phpIdentifier = null;
+          if (allClassNames != null) {
+            String extName = token.substring(1);
+            if (!allClassNames.contains(extName)) {
+              allClassNames.add(extName);
+            }
+          }
+          break;
         case 'f':
           // function name
           identifier = token.substring(1);
@@ -458,6 +606,18 @@ public class IdentifierIndexManager {
           identifier = token.substring(1);
           phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.GLOBAL_VARIABLE, phpFileName);
           break;
+        case 'i':
+          // implements <class name>
+          // not in map
+          identifier = null;
+          phpIdentifier = null;
+          if (allClassNames != null) {
+            String implName = token.substring(1);
+            if (!allClassNames.contains(implName)) {
+              allClassNames.add(implName);
+            }
+          }
+          break;
         case 'k':
           // constructor function name
           identifier = token.substring(1);
@@ -505,11 +665,11 @@ public class IdentifierIndexManager {
         }
         if (identifier != null && phpIdentifier != null) {
           tokenExists = true;
-          ArrayList list = (ArrayList) fIndentifierMap.get(identifier);
+          ArrayList list = (ArrayList) treeMap.get(identifier);
           if (list == null) {
             list = new ArrayList();
             list.add(phpIdentifier);
-            fIndentifierMap.put(identifier, list);
+            treeMap.put(identifier, list);
           } else {
             boolean flag = false;
             for (int i = 0; i < list.size(); i++) {
@@ -524,13 +684,15 @@ public class IdentifierIndexManager {
           }
         }
       }
-      fFileMap.put(phpFileName, line);
+      if (fileMap != null) {
+        fileMap.put(phpFileName, line);
+      }
     } catch (Throwable e) {
       // write to workspace/.metadata/.log file
       PHPeclipsePlugin.log(e);
     }
     //    if (tokenExists) {
-    
+
     //    }
   }
 
@@ -635,6 +797,11 @@ public class IdentifierIndexManager {
         identifier = token.substring(1);
         phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.DEFINE, phpFileName);
         break;
+      case 'e':
+        // extends <class name>
+        identifier = null;
+        phpIdentifier = null;
+        break;
       case 'f':
         // function name
         identifier = token.substring(1);
@@ -645,6 +812,11 @@ public class IdentifierIndexManager {
         identifier = token.substring(1);
         phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.GLOBAL_VARIABLE, phpFileName);
         break;
+      case 'i':
+        // implements <class name>
+        identifier = null;
+        phpIdentifier = null;
+        break;
       case 'k':
         // constructor function name
         identifier = token.substring(1);