A lot of bug fixed
[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 charStart the starting character
185    * @param charEnd the end character
186    * @param errorLevel the error level ({@link PHPParserSuperclass#ERROR},
187    *        {@link PHPParserSuperclass#INFO},{@link PHPParserSuperclass#WARNING})
188    * @param location the location of the error
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 charStart,
194                                final int charEnd,
195                                final int errorLevel,
196                                final String location)
197     throws CoreException {
198     if (file != null) {
199       final Hashtable attributes = new Hashtable();
200       MarkerUtilities.setMessage(attributes, message);
201       switch (errorLevel) {
202         case Parser.ERROR :
203           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
204           break;
205         case Parser.WARNING :
206           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING));
207           break;
208         case Parser.INFO :
209           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
210           break;
211       }
212       attributes.put(IMarker.LOCATION,location);
213       MarkerUtilities.setCharStart(attributes, charStart);
214       MarkerUtilities.setCharEnd(attributes, charEnd);
215       MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM);
216     }
217   }
218 }