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