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