a5ae10a95dd1301c5da7e4bd2b4cc88c8cd2ae81
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpeclipse / phpeditor / PHPParserAction.java
1 package net.sourceforge.phpeclipse.phpeditor;
2
3 /**********************************************************************
4 Copyright (c) 2000, 2002 IBM Corp. and others.
5 All rights reserved. This program and the accompanying materials
6 are made available under the terms of the Common Public License v1.0
7 which accompanies this distribution, and is available at
8 http://www.eclipse.org/legal/cpl-v10.html
9
10 Contributors:
11     IBM Corporation - Initial implementation
12     Klaus Hartlage - www.eclipseproject.de
13 **********************************************************************/
14
15 import java.io.IOException;
16 import java.io.InputStream;
17 import java.util.ArrayList;
18 import java.util.Collections;
19 import java.util.Hashtable;
20 import java.util.List;
21
22 import org.eclipse.core.resources.IFile;
23 import org.eclipse.core.resources.IMarker;
24 import org.eclipse.core.runtime.CoreException;
25 import org.eclipse.jface.text.BadLocationException;
26 import org.eclipse.jface.text.IRegion;
27 import org.eclipse.jface.text.Position;
28 import org.eclipse.ui.IEditorInput;
29 import org.eclipse.ui.IFileEditorInput;
30 import org.eclipse.ui.texteditor.ITextEditor;
31 import org.eclipse.ui.texteditor.MarkerUtilities;
32 import org.eclipse.ui.texteditor.TextEditorAction;
33
34 /**
35  * Class that defines the action for parsing the current PHP file
36  */
37 public class PHPParserAction extends TextEditorAction {
38
39   //    public static final String EXE = "exe"; //$NON-NLS-1$
40   //    public static final String WINEXE = "winexe"; //$NON-NLS-1$
41   //    public static final String LIBRARY = "library"; //$NON-NLS-1$
42   //    public static final String MODULE = "module"; //$NON-NLS-1$
43
44   private static final String ERROR = "error"; //$NON-NLS-1$
45   private static final String WARNING = "warning"; //$NON-NLS-1$
46
47   private static PHPParserAction instance = new PHPParserAction();
48
49   protected IFile fileToParse;
50   protected List fVariables = new ArrayList(100);
51
52   /**
53    * Constructs and updates the action.
54    */
55   private PHPParserAction() {
56     super(PHPEditorMessages.getResourceBundle(), "ParserAction.", null); //$NON-NLS-1$
57     update();
58   }
59
60   public static PHPParserAction getInstance() {
61     return instance;
62   }
63
64   /**
65    * Code called when the action is fired.
66    */
67   public void run() {
68     try {
69       fileToParse = getPHPFile();
70       if (fileToParse == null) {
71         // should never happen
72         System.err.println("Error : no file in the editor");
73         // should throw an exception
74         return;
75       }
76       // first delete all the previous markers
77       fileToParse.deleteMarkers(IMarker.PROBLEM, false, 0);
78       //IDocument document = getTextEditor().getDocumentProvider().getDocument(null);
79       //String text = document.get();
80
81       //  String text = 
82       // parse(document);
83       try {
84         InputStream iStream = fileToParse.getContents();
85         //        int c = iStream.read();
86         parse(iStream);
87         iStream.close();
88       } catch (IOException e) {
89       }
90
91       //      String message = "Test error";
92       //      int lineNumber = 1;
93       //
94       //      // create marker for the error
95       //
96       //      setMarker(message, lineNumber, fileToParse);
97     } catch (CoreException e) {
98     }
99
100   }
101
102   /**
103    * Finds the file that's currently opened in the PHP Text Editor
104    */
105   protected IFile getPHPFile() {
106     ITextEditor editor = getTextEditor();
107
108     IEditorInput editorInput = null;
109     if (editor != null) {
110       editorInput = editor.getEditorInput();
111     }
112
113     if (editorInput instanceof IFileEditorInput)
114       return ((IFileEditorInput) editorInput).getFile();
115
116     // if nothing was found, which should never happen
117     return null;
118   }
119
120   /**
121    * Create marker for the parse error
122    */
123   protected void setMarker(String message, int lineNumber) throws CoreException {
124
125     Hashtable attributes = new Hashtable();
126     MarkerUtilities.setMessage(attributes, message);
127     if (message.startsWith(ERROR))
128       attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
129     else if (message.startsWith(WARNING))
130       attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING));
131     else
132       attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
133     MarkerUtilities.setLineNumber(attributes, lineNumber);
134     MarkerUtilities.createMarker(fileToParse, attributes, IMarker.PROBLEM);
135   }
136
137   //  private String getIdentifier(InputStream iStream, int c) {
138   //    //    int i = 0;
139   //    // char c;
140   //    //  int textLength = text.length();
141   //    StringBuffer identifier = new StringBuffer();
142   //    identifier.append((char) c);
143   //    try {
144   //      while ((c = iStream.read()) != (-1)) {
145   //        if (Character.isJavaIdentifierPart((char) c)) {
146   //          identifier.append((char) c);
147   //          //        } else if ((i == 0) && (c == '$')) {
148   //          //          identifier.append((char)c);
149   //        } else {
150   //          return identifier.toString();
151   //        }
152   //        //        i++;
153   //      }
154   //    } catch (IOException e) {
155   //    }
156   //    return identifier.toString();
157   //  }
158
159   protected void parse(InputStream iStream) {
160     boolean lineCommentMode = false;
161     boolean multiLineCommentMode = false;
162     boolean stringMode = false;
163
164     //   ArrayList phpList = new ArrayList();
165     StringBuffer buf = new StringBuffer();
166     int c0;
167     try {
168       while ((c0 = iStream.read()) != (-1)) {
169         buf.append((char) c0);
170       }
171     } catch (IOException e) {
172       return;
173     }
174     String input = buf.toString();
175     int lineNumber = 1;
176     int startLineNumber = 1;
177     int startIndex = 0;
178     char ch;
179     char ch2;
180     boolean phpMode = false;
181     boolean phpFound = false;
182
183     try {
184       int i = 0;
185       while (i < input.length()) {
186         ch = input.charAt(i++);
187         if (ch == '\n') {
188           lineNumber++;
189         }
190         if ( (! phpMode) && ch == '<') {
191           ch2 = input.charAt(i++);
192           if (ch2 == '?') {
193             ch2 = input.charAt(i++);
194             if (Character.isWhitespace(ch2)) {
195               // php start 
196               phpMode = true;
197               phpFound = true;
198               startIndex = i;
199               startLineNumber = lineNumber;
200               continue;
201             } else if (ch2 == 'p') {
202               ch2 = input.charAt(i++);
203               if (ch2 == 'h') {
204                 ch2 = input.charAt(i++);
205                 if (ch2 == 'p') {
206                   phpMode = true;
207                   phpFound = true;
208                   startIndex = i;
209                   startLineNumber = lineNumber;
210                   continue;
211                 }
212                 i--;
213               }
214               i--;
215             } else if (ch2 == 'P') {
216               ch2 = input.charAt(i++);
217               if (ch2 == 'H') {
218                 ch2 = input.charAt(i++);
219                 if (ch2 == 'P') {
220                   phpMode = true;
221                   phpFound = true;
222                   startIndex = i;
223                   startLineNumber = lineNumber;
224                   continue;
225                 }
226                 i--;
227               }
228               i--;
229             }
230             i--;
231           }
232           i--;
233         }
234
235         if (phpMode) {
236           buf.append(ch);
237           if (lineCommentMode && (ch == '\n')) {
238             lineCommentMode = false;
239             // read until end of line
240           } else if ((!stringMode) && (ch == '#')) {
241             // read until end of line
242             lineCommentMode = true;
243             continue;
244           } else if ((!stringMode) && (!multiLineCommentMode) && (ch == '/')) {
245             ch2 = input.charAt(i++);
246             if (ch2 == '/') {
247               lineCommentMode = true;
248               continue;
249             } else if (ch2 == '*') {
250               multiLineCommentMode = true;
251               continue;
252             } else {
253               i--;
254             }
255           } else if (ch == '*' && multiLineCommentMode) {
256             ch2 = input.charAt(i++);
257             if (ch2 == '/') {
258               multiLineCommentMode = false;
259               continue;
260             } else {
261               i--;
262             }
263           } else if (ch == '\\' && stringMode) {
264             ch2 = input.charAt(i++);
265             if (ch2 == '"') {
266               continue;
267             } else {
268               i--;
269             }
270           } else if ((!lineCommentMode) && (!multiLineCommentMode) && (ch == '"')) {
271             if (stringMode) {
272               stringMode = false;
273             } else {
274               stringMode = true;
275             }
276             continue;
277           }
278           if (lineCommentMode || multiLineCommentMode || stringMode) {
279             continue;
280           }
281
282           if (ch == '?') {
283             ch2 = input.charAt(i++);
284             if (ch2 == '>') {
285               // php end
286               phpMode = false;
287               //             phpList.add(input.substring(startIndex, i-2));
288               try {
289                 PHPParser parser = new PHPParser(input.substring(startIndex, i - 2), startLineNumber);
290                 parser.start();
291               } catch (SyntaxError err) {
292                 setMarker(err.getMessage(), err.getLine());
293               }
294               continue;
295             }
296             i--;
297           }
298         } else {
299         }
300       }
301       if (!phpFound) {
302         setMarker("No PHP source code found.", lineNumber);
303       }
304     } catch (CoreException e) {
305     }
306   }
307 }