1dee6aa63d1a598538f377ed64f90cb85f7064d2
[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
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    */
57   private static void createMarkers(final String output, final IFile file)
58     throws CoreException {
59     // delete all markers
60     file.deleteMarkers(IMarker.PROBLEM, false, 0);
61
62     int indx = 0;
63     int brIndx;
64     boolean flag = true;
65     while ((brIndx = output.indexOf("<br />", indx)) != -1) {
66       // newer php error output (tested with 4.2.3)
67       scanLine(output, file, indx, brIndx);
68       indx = brIndx + 6;
69       flag = false;
70     }
71     if (flag) {
72       while ((brIndx = output.indexOf("<br>", indx)) != -1) {
73         // older php error output (tested with 4.2.3)
74         scanLine(output, file, indx, brIndx);
75         indx = brIndx + 4;
76       }
77     }
78   }
79
80   private static void scanLine(final String output, final IFile file, final int indx, final int brIndx)
81     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
89       || 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 = current.replaceAll("\n", "");
105         current = current.replaceAll("<b>", "");
106         current = current.replaceAll("</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(
113             IMarker.SEVERITY,
114             new Integer(IMarker.SEVERITY_WARNING));
115         else
116           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
117         MarkerUtilities.setLineNumber(attributes, lineNumber);
118         MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM);
119       }
120     }
121   }
122
123   /**
124    * This will parse the file and generate the outline info
125    * @param parent the parent object
126    * @param s the string that should be parsed
127    * @return the outline info
128    */
129   public abstract PHPOutlineInfo parseInfo(Object parent, String s);
130
131   /**
132    * This will change the file to parse.
133    * @param fileToParse the file that should be parsed
134    */
135   public abstract void setFileToParse(IFile fileToParse);
136
137   /**
138    * This will parse the given string
139    * @param s the string to parse
140    * @throws CoreException an exception that can be launched
141    */
142   public abstract void parse(String s) throws CoreException;
143
144   /**
145    * This will set a marker.
146    * @param file the file that generated the marker
147    * @param message the message
148    * @param charStart the starting character
149    * @param charEnd the end character
150    * @param errorLevel the error level ({@link PHPParserSuperclass#ERROR},
151    *        {@link PHPParserSuperclass#INFO},{@link PHPParserSuperclass#WARNING})
152    * @throws CoreException an exception throwed by the MarkerUtilities
153    */
154   public static void setMarker(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 Parser.ERROR :
165           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
166           break;
167         case Parser.WARNING :
168           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING));
169           break;
170         case Parser.INFO :
171           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
172           break;
173       }
174       MarkerUtilities.setCharStart(attributes, charStart);
175       MarkerUtilities.setCharEnd(attributes, charEnd);
176       MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM);
177     }
178   }
179
180   /**
181    * This will set a marker.
182    * @param file the file that generated the marker
183    * @param message the message
184    * @param line the line number
185    * @param errorLevel the error level ({@link PHPParserSuperclass#ERROR},
186    *        {@link PHPParserSuperclass#INFO},{@link PHPParserSuperclass#WARNING})
187    * @throws CoreException an exception throwed by the MarkerUtilities
188    */
189   public static void setMarker(final IFile file,
190                                final String message,
191                                final int line,
192                                final int errorLevel,
193                                final String location)
194     throws CoreException {
195     if (file != null) {
196       final Hashtable attributes = new Hashtable();
197       MarkerUtilities.setMessage(attributes, message);
198       switch (errorLevel) {
199         case Parser.ERROR :
200           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
201           break;
202         case Parser.WARNING :
203           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING));
204           break;
205         case Parser.INFO :
206           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
207           break;
208       }
209       attributes.put(IMarker.LOCATION,location);
210       MarkerUtilities.setLineNumber(attributes, line);
211       MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM);
212     }
213   }
214   /**
215    * This will set a marker.
216    * @param file the file that generated the marker
217    * @param message the message
218    * @param charStart the starting character
219    * @param charEnd the end character
220    * @param errorLevel the error level ({@link PHPParserSuperclass#ERROR},
221    *        {@link PHPParserSuperclass#INFO},{@link PHPParserSuperclass#WARNING})
222    * @param location the location of the error
223    * @throws CoreException an exception throwed by the MarkerUtilities
224    */
225   public static void setMarker(final IFile file,
226                                final String message,
227                                final int charStart,
228                                final int charEnd,
229                                final int errorLevel,
230                                final String location)
231     throws CoreException {
232     if (file != null) {
233       final Hashtable attributes = new Hashtable();
234       MarkerUtilities.setMessage(attributes, message);
235       switch (errorLevel) {
236         case Parser.ERROR :
237           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
238           break;
239         case Parser.WARNING :
240           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING));
241           break;
242         case Parser.INFO :
243           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
244           break;
245       }
246       attributes.put(IMarker.LOCATION,location);
247       MarkerUtilities.setCharStart(attributes, charStart);
248       MarkerUtilities.setCharEnd(attributes, charEnd);
249       MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM);
250     }
251   }
252 }