c1bf44674aa9fbdfb24cf89ae82fb8953490a30b
[phpeclipse.git] / net.sourceforge.phpeclipse / src / test / PHPParserSuperclass.java
1 package test;
2
3 import org.eclipse.core.resources.IFile;
4 import org.eclipse.core.resources.IMarker;
5 import org.eclipse.core.runtime.CoreException;
6 import org.eclipse.jface.preference.IPreferenceStore;
7 import org.eclipse.ui.texteditor.MarkerUtilities;
8 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
9 import net.sourceforge.phpeclipse.actions.PHPStartApacheAction;
10 import net.sourceforge.phpdt.internal.compiler.parser.PHPOutlineInfo;
11 import net.sourceforge.phpdt.internal.compiler.parser.Parser;
12
13 import java.text.MessageFormat;
14 import java.util.Hashtable;
15
16 /**
17  * The superclass for our PHP parsers.
18  * @author Matthieu Casanova
19  */
20 public abstract class PHPParserSuperclass {
21   // strings for external parser call
22   private static final String PARSE_ERROR_STRING = "Parse error"; //$NON-NLS-1$
23   private static final String PARSE_WARNING_STRING = "Warning"; //$NON-NLS-1$
24   public static final int ERROR = 2;
25   public static final int WARNING = 1;
26   public static final int INFO = 0;
27   public static final int TASK = 3;
28
29   /**
30    * Call the php parse command ( php -l -f <filename> )
31    * and create markers according to the external parser output.
32    * @param file the file that will be parsed
33    */
34   public static void phpExternalParse(final IFile file) {
35     //IFile file = (IFile) resource;
36     //  final IPath path = file.getFullPath();
37     final IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore();
38     final String filename = file.getLocation().toString();
39
40     final String[] arguments = {filename};
41     final MessageFormat form =
42         new MessageFormat(store.getString(PHPeclipsePlugin.EXTERNAL_PARSER_PREF));
43     final String command = form.format(arguments);
44
45     final String parserResult =
46         PHPStartApacheAction.getParserOutput(command, "External parser: ");
47
48     try {
49       // parse the buffer to find the errors and warnings
50       createMarkers(parserResult, file);
51     } catch (CoreException e) {
52     }
53   }
54
55   /**
56    * Create markers according to the external parser output.
57    * @param output the external parser output
58    * @param file the file that was parsed.
59    */
60   protected static void createMarkers(final String output, final IFile file)
61       throws CoreException {
62     // delete all markers
63     file.deleteMarkers(IMarker.PROBLEM, false, 0);
64
65     int indx = 0;
66     int brIndx;
67     boolean flag = true;
68     while ((brIndx = output.indexOf("<br />", indx)) != -1) {
69       // newer php error output (tested with 4.2.3)
70       scanLine(output, file, indx, brIndx);
71       indx = brIndx + 6;
72       flag = false;
73     }
74     if (flag) {
75       while ((brIndx = output.indexOf("<br>", indx)) != -1) {
76         // older php error output (tested with 4.2.3)
77         scanLine(output, file, indx, brIndx);
78         indx = brIndx + 4;
79       }
80     }
81   }
82
83   private static void scanLine(final String output, final IFile file, final int indx, final int brIndx)
84       throws CoreException {
85     String current;
86     //  String outLineNumberString; never used
87     final StringBuffer lineNumberBuffer = new StringBuffer(10);
88     char ch;
89     current = output.substring(indx, brIndx);
90
91     if (current.indexOf(PARSE_WARNING_STRING) != -1
92         || current.indexOf(PARSE_ERROR_STRING) != -1) {
93       final int onLine = current.indexOf("on line <b>");
94       if (onLine != -1) {
95         lineNumberBuffer.delete(0, lineNumberBuffer.length());
96         for (int i = onLine; i < current.length(); i++) {
97           ch = current.charAt(i);
98           if ('0' <= ch && '9' >= ch) {
99             lineNumberBuffer.append(ch);
100           }
101         }
102
103         final int lineNumber = Integer.parseInt(lineNumberBuffer.toString());
104
105         final Hashtable attributes = new Hashtable();
106
107         current = current.replaceAll("\n", "");
108         current = current.replaceAll("<b>", "");
109         current = current.replaceAll("</b>", "");
110         MarkerUtilities.setMessage(attributes, current);
111
112         if (current.indexOf(PARSE_ERROR_STRING) != -1)
113           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
114         else if (current.indexOf(PARSE_WARNING_STRING) != -1)
115           attributes.put(
116               IMarker.SEVERITY,
117               new Integer(IMarker.SEVERITY_WARNING));
118         else
119           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
120         MarkerUtilities.setLineNumber(attributes, lineNumber);
121         MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM);
122       }
123     }
124   }
125
126   /**
127    * This will parse the file and generate the outline info
128    * @param parent the parent object
129    * @param s the string that should be parsed
130    * @return the outline info
131    */
132   public abstract PHPOutlineInfo parseInfo(Object parent, String s);
133
134   /**
135    * This will change the file to parse.
136    * @param fileToParse the file that should be parsed
137    */
138   public abstract void setFileToParse(IFile fileToParse);
139
140   /**
141    * This will parse the given string
142    * @param s the string to parse
143    * @throws CoreException an exception that can be launched
144    */
145   public abstract void parse(String s) throws CoreException;
146
147   /**
148    * This will set a marker.
149    * @param file the file that generated the marker
150    * @param message the message
151    * @param charStart the starting character
152    * @param charEnd the end character
153    * @param errorLevel the error level ({@link PHPParserSuperclass#ERROR},
154    *        {@link PHPParserSuperclass#INFO},{@link PHPParserSuperclass#WARNING}),{@link PHPParserSuperclass#TASK})
155    * @throws CoreException an exception throwed by the MarkerUtilities
156    */
157   public static void setMarker(final IFile file,
158                                final String message,
159                                final int charStart,
160                                final int charEnd,
161                                final int errorLevel)
162       throws CoreException {
163     if (file != null) {
164       final Hashtable attributes = new Hashtable();
165       MarkerUtilities.setMessage(attributes, message);
166       switch (errorLevel) {
167         case ERROR:
168           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
169           break;
170         case WARNING:
171           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING));
172           break;
173         case INFO:
174           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
175           break;
176         case TASK:
177           attributes.put(IMarker.SEVERITY, new Integer(IMarker.TASK));
178           break;
179       }
180       MarkerUtilities.setCharStart(attributes, charStart);
181       MarkerUtilities.setCharEnd(attributes, charEnd);
182       MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM);
183     }
184   }
185
186   /**
187    * This will set a marker.
188    * @param file the file that generated the marker
189    * @param message the message
190    * @param line the line number
191    * @param errorLevel the error level ({@link PHPParserSuperclass#ERROR},
192    *        {@link PHPParserSuperclass#INFO},{@link PHPParserSuperclass#WARNING})
193    * @throws CoreException an exception throwed by the MarkerUtilities
194    */
195   public static void setMarker(final IFile file,
196                                final String message,
197                                final int line,
198                                final int errorLevel,
199                                final String location)
200       throws CoreException {
201     if (file != null) {
202       String markerKind = IMarker.PROBLEM;
203       final Hashtable attributes = new Hashtable();
204       MarkerUtilities.setMessage(attributes, message);
205       switch (errorLevel) {
206         case ERROR:
207           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
208           break;
209         case WARNING:
210           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING));
211           break;
212         case INFO:
213           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
214           break;
215         case TASK:
216           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
217           markerKind = IMarker.TASK;
218           break;
219       }
220       attributes.put(IMarker.LOCATION, location);
221       MarkerUtilities.setLineNumber(attributes, line);
222       MarkerUtilities.createMarker(file, attributes, markerKind);
223     }
224   }
225
226   /**
227    * This will set a marker.
228    * @param file the file that generated the marker
229    * @param message the message
230    * @param charStart the starting character
231    * @param charEnd the end character
232    * @param errorLevel the error level ({@link PHPParserSuperclass#ERROR},
233    *        {@link PHPParserSuperclass#INFO},{@link PHPParserSuperclass#WARNING})
234    * @param location the location of the error
235    * @throws CoreException an exception throwed by the MarkerUtilities
236    */
237   public static void setMarker(final IFile file,
238                                final String message,
239                                final int charStart,
240                                final int charEnd,
241                                final int errorLevel,
242                                final String location)
243       throws CoreException {
244     if (file != null) {
245       final Hashtable attributes = new Hashtable();
246       MarkerUtilities.setMessage(attributes, message);
247       switch (errorLevel) {
248         case ERROR:
249           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
250           break;
251         case WARNING:
252           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING));
253           break;
254         case INFO:
255           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
256           break;
257         case TASK:
258           attributes.put(IMarker.SEVERITY, new Integer(IMarker.TASK));
259           break;
260       }
261       attributes.put(IMarker.LOCATION, location);
262       MarkerUtilities.setCharStart(attributes, charStart);
263       MarkerUtilities.setCharEnd(attributes, charEnd);
264       MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM);
265     }
266   }
267 }