some refactoring in the code analysis
[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   protected static IFile fileToParse;
30
31   /**
32    * Call the php parse command ( php -l -f <filename> )
33    * and create markers according to the external parser output.
34    * @param file the file that will be parsed
35    */
36   public static void phpExternalParse(final IFile file) {
37     //IFile file = (IFile) resource;
38     //  final IPath path = file.getFullPath();
39     final IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore();
40     final String filename = file.getLocation().toString();
41
42     final String[] arguments = {filename};
43     final MessageFormat form = new MessageFormat(store.getString(PHPeclipsePlugin.EXTERNAL_PARSER_PREF));
44     final String command = form.format(arguments);
45
46     final String parserResult = 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) throws CoreException {
61     // delete all markers
62     file.deleteMarkers(IMarker.PROBLEM, false, 0);
63
64     int indx = 0;
65     int brIndx;
66     boolean flag = true;
67     while ((brIndx = output.indexOf("<br />", indx)) != -1) {
68       // newer php error output (tested with 4.2.3)
69       scanLine(output, file, indx, brIndx);
70       indx = brIndx + 6;
71       flag = false;
72     }
73     if (flag) {
74       while ((brIndx = output.indexOf("<br>", indx)) != -1) {
75         // older php error output (tested with 4.2.3)
76         scanLine(output, file, indx, brIndx);
77         indx = brIndx + 4;
78       }
79     }
80   }
81
82   private static void scanLine(final String output, final IFile file, final int indx, final int brIndx) throws CoreException {
83     String current;
84     //  String outLineNumberString; never used
85     final StringBuffer lineNumberBuffer = new StringBuffer(10);
86     char ch;
87     current = output.substring(indx, brIndx);
88
89     if (current.indexOf(PARSE_WARNING_STRING) != -1 || current.indexOf(PARSE_ERROR_STRING) != -1) {
90       final int onLine = current.indexOf("on line <b>");
91       if (onLine != -1) {
92         lineNumberBuffer.delete(0, lineNumberBuffer.length());
93         for (int i = onLine; i < current.length(); i++) {
94           ch = current.charAt(i);
95           if ('0' <= ch && '9' >= ch) {
96             lineNumberBuffer.append(ch);
97           }
98         }
99
100         final int lineNumber = Integer.parseInt(lineNumberBuffer.toString());
101
102         final Hashtable attributes = new Hashtable();
103
104         current = StringUtil.replaceAll(current, "\n", "");
105         current = StringUtil.replaceAll(current, "<b>", "");
106         current = StringUtil.replaceAll(current, "</b>", "");
107         MarkerUtilities.setMessage(attributes, current);
108
109         if (current.indexOf(PARSE_ERROR_STRING) != -1)
110           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
111         else if (current.indexOf(PARSE_WARNING_STRING) != -1)
112           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING));
113         else
114           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
115         MarkerUtilities.setLineNumber(attributes, lineNumber);
116         MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM);
117       }
118     }
119   }
120
121   /**
122    * This will parse the file and generate the outline info
123    * @param parent the parent object
124    * @param s the string that should be parsed
125    * @return the outline info
126    */
127   public abstract PHPOutlineInfo parseInfo(Object parent, String s);
128
129   /**
130    * This will change the file to parse.
131    * @param fileToParse the file that should be parsed
132    */
133   public abstract void setFileToParse(IFile fileToParse);
134
135   /**
136    * This will parse the given string
137    * @param s the string to parse
138    * @throws CoreException an exception that can be launched
139    */
140   public abstract void parse(String s) throws CoreException;
141
142   /**
143    * This will set a marker.
144    * @param file the file that generated the marker
145    * @param message the message
146    * @param charStart the starting character
147    * @param charEnd the end character
148    * @param errorLevel the error level ({@link PHPParserSuperclass#ERROR},
149    *        {@link PHPParserSuperclass#INFO},{@link PHPParserSuperclass#WARNING}),{@link PHPParserSuperclass#TASK})
150    * @throws CoreException an exception throwed by the MarkerUtilities
151    */
152   public static void setMarker(
153       final IFile file,
154       final String message,
155       final int charStart,
156       final int charEnd,
157       final int errorLevel)
158       throws CoreException {
159     if (file != null) {
160       final Hashtable attributes = new Hashtable();
161       MarkerUtilities.setMessage(attributes, message);
162       switch (errorLevel) {
163         case ERROR:
164           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
165           break;
166         case WARNING:
167           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING));
168           break;
169         case INFO:
170           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
171           break;
172         case TASK:
173           attributes.put(IMarker.SEVERITY, new Integer(IMarker.TASK));
174           break;
175       }
176       MarkerUtilities.setCharStart(attributes, charStart);
177       MarkerUtilities.setCharEnd(attributes, charEnd);
178       MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM);
179     }
180   }
181
182   /**
183    * This will set a marker.
184    * @param file the file that generated the marker
185    * @param message the message
186    * @param line the line number
187    * @param errorLevel the error level ({@link PHPParserSuperclass#ERROR},
188    *        {@link PHPParserSuperclass#INFO},{@link PHPParserSuperclass#WARNING})
189    * @throws CoreException an exception throwed by the MarkerUtilities
190    */
191   public static void setMarker(final IFile file,
192                                final String message,
193                                final int line,
194                                final int errorLevel,
195                                final String location)
196       throws CoreException {
197     if (file != null) {
198       String markerKind = IMarker.PROBLEM;
199       final Hashtable attributes = new Hashtable();
200       MarkerUtilities.setMessage(attributes, message);
201       switch (errorLevel) {
202         case ERROR:
203           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
204           break;
205         case WARNING:
206           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING));
207           break;
208         case INFO:
209           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
210           break;
211         case TASK:
212           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
213           markerKind = IMarker.TASK;
214           break;
215       }
216       attributes.put(IMarker.LOCATION, location);
217       MarkerUtilities.setLineNumber(attributes, line);
218       MarkerUtilities.createMarker(file, attributes, markerKind);
219     }
220   }
221
222   /**
223    * This will set a marker.
224    * @param message the message
225    * @param charStart the starting character
226    * @param charEnd the end character
227    * @param errorLevel the error level ({@link PHPParserSuperclass#ERROR},
228    *        {@link PHPParserSuperclass#INFO},{@link PHPParserSuperclass#WARNING})
229    * @throws CoreException an exception throwed by the MarkerUtilities
230    */
231   public static void setMarker(final String message,
232                                final int charStart,
233                                final int charEnd,
234                                final int errorLevel,
235                                final String location)
236       throws CoreException {
237     if (fileToParse != null) {
238       setMarker(fileToParse, message, charStart, charEnd, errorLevel, location);
239     }
240   }
241
242   /**
243    * This will set a marker.
244    * @param file the file that generated the marker
245    * @param message the message
246    * @param charStart the starting character
247    * @param charEnd the end character
248    * @param errorLevel the error level ({@link PHPParserSuperclass#ERROR},
249    *        {@link PHPParserSuperclass#INFO},{@link PHPParserSuperclass#WARNING})
250    * @param location the location of the error
251    * @throws CoreException an exception throwed by the MarkerUtilities
252    */
253   public static void setMarker(final IFile file,
254                                final String message,
255                                final int charStart,
256                                final int charEnd,
257                                final int errorLevel,
258                                final String location)
259       throws CoreException {
260     if (file != null) {
261       final Hashtable attributes = new Hashtable();
262       MarkerUtilities.setMessage(attributes, message);
263       switch (errorLevel) {
264         case ERROR:
265           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
266           break;
267         case WARNING:
268           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING));
269           break;
270         case INFO:
271           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
272           break;
273         case TASK:
274           attributes.put(IMarker.SEVERITY, new Integer(IMarker.TASK));
275           break;
276       }
277       attributes.put(IMarker.LOCATION, location);
278       MarkerUtilities.setCharStart(attributes, charStart);
279       MarkerUtilities.setCharEnd(attributes, charEnd);
280       MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM);
281     }
282   }
283 }