ContextHelp now in new module net.sourceforge.phpeclipse.phphelp
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpeclipse / phpeditor / PHPContentOutlinePage.java
index 86b9977..43e72ef 100644 (file)
@@ -16,13 +16,19 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
-
-import org.eclipse.jface.text.BadLocationException;
+import java.util.TreeSet;
+
+import net.sourceforge.phpdt.internal.ui.viewsupport.ImageDescriptorRegistry;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.phpparser.PHPClassDeclaration;
+import net.sourceforge.phpeclipse.phpeditor.phpparser.PHPOutlineInfo;
+import net.sourceforge.phpeclipse.phpeditor.phpparser.PHPParser;
+import net.sourceforge.phpeclipse.phpeditor.phpparser.PHPSegment;
+import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.jface.text.BadPositionCategoryException;
 import org.eclipse.jface.text.DefaultPositionUpdater;
 import org.eclipse.jface.text.IDocument;
 import org.eclipse.jface.text.IPositionUpdater;
-import org.eclipse.jface.text.Position;
 import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jface.viewers.ITreeContentProvider;
@@ -30,6 +36,7 @@ import org.eclipse.jface.viewers.LabelProvider;
 import org.eclipse.jface.viewers.SelectionChangedEvent;
 import org.eclipse.jface.viewers.TreeViewer;
 import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.ui.texteditor.IDocumentProvider;
@@ -43,26 +50,16 @@ import org.eclipse.ui.views.contentoutline.ContentOutlinePage;
 public class PHPContentOutlinePage extends ContentOutlinePage {
   private static final String ERROR = "error"; //$NON-NLS-1$
   private static final String WARNING = "warning"; //$NON-NLS-1$
-  /**
-   * A segment element.
-   */
-  protected static class Segment {
-    public String name;
-    public Position position;
-
-    public Segment(String name, Position position) {
-      this.name = name;
-      this.position = position;
-    }
-
-    public String toString() {
-      return name;
-    }
-  };
 
   protected static class SegmentComparator implements Comparator {
     public int compare(Object o1, Object o2) {
-      return ((Segment) o1).name.compareToIgnoreCase(((Segment) o2).name);
+      if (o1 instanceof PHPClassDeclaration && !(o2 instanceof PHPClassDeclaration)) {
+        return 1;
+      }
+      if (o2 instanceof PHPClassDeclaration && !(o1 instanceof PHPClassDeclaration)) {
+        return -1;
+      }
+      return ((PHPSegment) o1).toString().compareToIgnoreCase(((PHPSegment) o2).toString());
     }
   }
 
@@ -74,159 +71,47 @@ public class PHPContentOutlinePage extends ContentOutlinePage {
     protected final static String SEGMENTS = "__php_segments"; //$NON-NLS-1$
     protected IPositionUpdater fPositionUpdater = new DefaultPositionUpdater(SEGMENTS);
     protected List fContent = new ArrayList(10);
-    protected List fVariables = new ArrayList(100);
-
-    private String getIdentifier(String text, int firstIndex) {
-      int i = firstIndex;
-      char c;
-      int textLength = text.length();
-      StringBuffer identifier = new StringBuffer();
-      while (i < textLength) {
-        c = text.charAt(i++);
-        if (Character.isJavaIdentifierPart(c) || (c == '$')) {
-          identifier.append(c);
-        } else if ((i == firstIndex + 1) && (c == '$')) {
-          identifier.append(c);
-        } else {
-          return identifier.toString();
-        }
-      }
-      return null;
-    }
+    protected TreeSet fVariables = new TreeSet();
+
+    //    private String getIdentifier(String text, int firstIndex) {
+    //      int i = firstIndex;
+    //      char c;
+    //      int textLength = text.length();
+    //      StringBuffer identifier = new StringBuffer();
+    //      while (i < textLength) {
+    //        c = text.charAt(i++);
+    //        if (Character.isJavaIdentifierPart(c) || (c == '$')) {
+    //          identifier.append(c);
+    //        } else if ((i == firstIndex + 1) && (c == '$')) {
+    //          identifier.append(c);
+    //        } else {
+    //          return identifier.toString();
+    //        }
+    //      }
+    //      return null;
+    //    }
 
     protected void parse(IDocument document) {
 
-      int lines = document.getNumberOfLines();
-      int increment = Math.max(Math.round((float) (lines / 10)), 10);
+      //      int lines = document.getNumberOfLines();
+      //      int increment = Math.max(Math.round((float) (lines / 10)), 10);
 
+      String name;
+      int index;
       String text = document.get();
-      int lastIndex = 0;
-      int i = 0;
-      //      lastIndex = text.indexOf("function ", lastIndex);
-      //      while (lastIndex > 0) {
-      //
-      //        try {
-      //          i = lastIndex + 9;
-      //          while ((i < text.length()) && Character.isJavaIdentifierPart(text.charAt(i))) {
-      //            i++;
-      //          }
-      //          Position p = new Position(lastIndex, i - lastIndex);
-      //          document.addPosition(SEGMENTS, p);
-      //          fContent.add(new Segment(text.substring(lastIndex, i), p));
-      //          //     MessageFormat.format("function", new Object[] { new Integer(lastIndex)}), p)); //$NON-NLS-1$
-      //          lastIndex = text.indexOf("function", lastIndex + 1);
-      //        } catch (BadLocationException e) {
-      //        } catch (BadPositionCategoryException e) {
-      //        }
-      //
-      //      }
-
-      boolean lineCommentMode = false;
-      boolean multiLineCommentMode = false;
-      boolean stringMode = false;
-      boolean functionMode = false;
-      String identifier;
-      int c;
-      int c2;
-
-      int textLength = text.length() - 10;
-      while (i < textLength) {
-        c = text.charAt(i++);
-        if (c == '\n') {
-          lineCommentMode = false;
-          // read until end of line
-        } else if (c == '#') {
-          // read until end of line
-          lineCommentMode = true;
-          continue;
-        } else if (c == '/') {
-          c2 = text.charAt(i++);
-          if (c2 == '/') {
-            lineCommentMode = true;
-            continue;
-          } else if (c2 == '*') {
-            multiLineCommentMode = true;
-            continue;
-          } else {
-            i--;
-          }
-        } else if (c == '*' && multiLineCommentMode) {
-          c2 = text.charAt(i++);
-          if (c2 == '/') {
-            multiLineCommentMode = false;
-            continue;
-          } else {
-            i--;
-          }
-        } else if (c == '\\' && stringMode) {
-          c2 = text.charAt(i++);
-          if (c2 == '"') {
-            continue;
-          } else {
-            i--;
-          }
-        } else if (c == '"') {
-          if (stringMode) {
-            stringMode = false;
-          } else {
-            stringMode = true;
-          }
-          continue;
-        }
-        if (lineCommentMode || multiLineCommentMode || stringMode) {
-          continue;
-        }
+      PHPParser parser = new PHPParser(null);
 
-        if (functionMode && Character.isJavaIdentifierPart((char) c)) {
-          functionMode = false;
-          lastIndex = i - 1;
-          identifier = getIdentifier(text, lastIndex);
-          try {
-            i += identifier.length() - 1;
-            Position p = new Position(lastIndex, i - lastIndex);
-            document.addPosition(SEGMENTS, p);
-            fContent.add(new Segment(text.substring(lastIndex, i), p));
-            //     MessageFormat.format("function", new Object[] { new Integer(lastIndex)}), p)); //$NON-NLS-1$
-            //    lastIndex = text.indexOf("function", lastIndex + 1);
-          } catch (BadLocationException e) {
-          } catch (BadPositionCategoryException e) {
-          }
-
-        } else if (c == 'f') {
-          identifier = getIdentifier(text, i - 1);
-          if (identifier.equals("function")) {
-            functionMode = true;
-            i += 8;
-          }
-        } else if (c == '$') {
-          // get the variable name
-          identifier = getIdentifier(text, i - 1);
-          fVariables.add(identifier);
-        }
+      PHPOutlineInfo outlineInfo = parser.parseInfo(fInput, text);
+      fVariables = outlineInfo.getVariables();
 
+      PHPClassDeclaration declarations = outlineInfo.getDeclarations();
+      PHPSegment temp;
+      for (int i = 0; i < declarations.size(); i++) {
+        temp = declarations.get(i);
+        fContent.add(temp);
       }
       Collections.sort(fContent, new SegmentComparator());
-      Collections.sort(fVariables);
-
-      //                       for (int line = 0; line < lines; line += increment) {
-      //
-      //                               int length = increment;
-      //                               if (line + increment > lines)
-      //                                       length = lines - line;
-      //
-      //                               try {
-      //
-      //                                       int offset = document.getLineOffset(line);
-      //                                       int end = document.getLineOffset(line + length);
-      //                                       length = end - offset;
-      //                                       Position p = new Position(offset, length);
-      //                                       document.addPosition(SEGMENTS, p);
-      //                                       fContent.add(new Segment(MessageFormat.format(PHPEditorMessages.getString("OutlinePage.segment.title_pattern"), new Object[] { new Integer(offset)}), p)); //$NON-NLS-1$
-      //
-      //                               } catch (BadPositionCategoryException x) {
-      //                               } catch (BadLocationException x) {
-      //                               }
-      //                       }
+
     }
 
     /*
@@ -279,6 +164,13 @@ public class PHPContentOutlinePage extends ContentOutlinePage {
       return false;
     }
 
+    /**
+     * returns all PHP variables
+     */
+    public Object[] getVariables() {
+      return fVariables.toArray();
+    }
+
     /*
      * @see IStructuredContentProvider#getElements(Object)
      */
@@ -286,16 +178,13 @@ public class PHPContentOutlinePage extends ContentOutlinePage {
       return fContent.toArray();
     }
 
-    /**
-     * returns all PHP variables
-     */
-    public Object[] getVariables() {
-      return fVariables.toArray();
-    }
     /*
      * @see ITreeContentProvider#hasChildren(Object)
      */
     public boolean hasChildren(Object element) {
+      if (element instanceof PHPClassDeclaration) {
+        return !((PHPClassDeclaration) element).getList().isEmpty();
+      }
       return element == fInput;
     }
 
@@ -303,8 +192,9 @@ public class PHPContentOutlinePage extends ContentOutlinePage {
      * @see ITreeContentProvider#getParent(Object)
      */
     public Object getParent(Object element) {
-      if (element instanceof Segment)
-        return fInput;
+      if (element instanceof PHPSegment) {
+        return ((PHPSegment) element).getParent();
+      }
       return null;
     }
 
@@ -314,21 +204,49 @@ public class PHPContentOutlinePage extends ContentOutlinePage {
     public Object[] getChildren(Object element) {
       if (element == fInput)
         return fContent.toArray();
+      if (element instanceof PHPClassDeclaration)
+        return ((PHPClassDeclaration) element).getList().toArray();
       return new Object[0];
     }
   };
 
+  protected class OutlineLabelProvider extends LabelProvider {
+    private ImageDescriptorRegistry fRegistry;
+
+    public OutlineLabelProvider() {
+      fRegistry = PHPeclipsePlugin.getImageDescriptorRegistry();
+      ;
+    }
+    /**
+    * The <code>LabelProvider</code> implementation of this 
+    * <code>ILabelProvider</code> method returns <code>null</code>. Subclasses may 
+    * override.
+    */
+    public Image getImage(Object element) {
+      if (element instanceof PHPSegment) {
+        ImageDescriptor descriptor = ((PHPSegment) element).getImage();
+        return fRegistry.get(descriptor);
+      }
+      return null;
+    }
+  }
+
   protected Object fInput;
   protected IDocumentProvider fDocumentProvider;
   protected ITextEditor fTextEditor;
+  protected PHPEditor fEditor;
+  protected ContentProvider contentProvider;
 
   /**
    * Creates a content outline page using the given provider and the given editor.
    */
   public PHPContentOutlinePage(IDocumentProvider provider, ITextEditor editor) {
     super();
+    contentProvider = null;
     fDocumentProvider = provider;
     fTextEditor = editor;
+    if (editor instanceof PHPEditor)
+      fEditor = (PHPEditor) editor;
   }
 
   /* (non-Javadoc)
@@ -339,8 +257,11 @@ public class PHPContentOutlinePage extends ContentOutlinePage {
     super.createControl(parent);
 
     TreeViewer viewer = getTreeViewer();
-    viewer.setContentProvider(new ContentProvider());
-    viewer.setLabelProvider(new LabelProvider());
+
+    contentProvider = new ContentProvider();
+    viewer.setContentProvider(contentProvider);
+    viewer.setLabelProvider(new OutlineLabelProvider());
+
     viewer.addSelectionChangedListener(this);
 
     if (fInput != null)
@@ -358,9 +279,9 @@ public class PHPContentOutlinePage extends ContentOutlinePage {
     if (selection.isEmpty())
       fTextEditor.resetHighlightRange();
     else {
-      Segment segment = (Segment) ((IStructuredSelection) selection).getFirstElement();
-      int start = segment.position.getOffset();
-      int length = segment.position.getLength();
+      PHPSegment segment = (PHPSegment) ((IStructuredSelection) selection).getFirstElement();
+      int start = segment.getPosition().getOffset();
+      int length = segment.getPosition().getLength();
       try {
         fTextEditor.setHighlightRange(start, length, true);
       } catch (IllegalArgumentException x) {
@@ -393,4 +314,15 @@ public class PHPContentOutlinePage extends ContentOutlinePage {
       }
     }
   }
+  
+  public Object[] getVariables() {
+    if (contentProvider != null) {
+      return contentProvider.getVariables();
+    }
+    return null;
+  }
+  //  public ContentProvider getContentProvider() {
+  //    return contentProvider;
+  //  }
+
 }