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