package test; import java.text.MessageFormat; import java.util.Hashtable; import net.sourceforge.phpdt.core.IJavaModelMarker; import net.sourceforge.phpdt.internal.compiler.parser.PHPOutlineInfo; import net.sourceforge.phpdt.internal.ui.util.StringUtil; import net.sourceforge.phpeclipse.PHPeclipsePlugin; import net.sourceforge.phpeclipse.actions.PHPStartApacheAction; import net.sourceforge.phpeclipse.builder.PHPBuilder; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.ui.texteditor.MarkerUtilities; /** * The superclass for our PHP parsers. * @author Matthieu Casanova */ public abstract class PHPParserSuperclass { // strings for external parser call private static final String PARSE_ERROR_STRING = "Parse error"; //$NON-NLS-1$ private static final String PARSE_WARNING_STRING = "Warning"; //$NON-NLS-1$ public static final int ERROR = 2; public static final int WARNING = 1; public static final int INFO = 0; public static final int TASK = 3; // TODO design error? Analyze why fileToParse must be static ??? protected static IFile fileToParse; /** * Call the php parse command ( php -l -f <filename> ) * and create markers according to the external parser output. * @param file the file that will be parsed */ public static void phpExternalParse(final IFile file) { //IFile file = (IFile) resource; // final IPath path = file.getFullPath(); final IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore(); final String filename = file.getLocation().toString(); final String[] arguments = {filename}; final MessageFormat form = new MessageFormat(store.getString(PHPeclipsePlugin.EXTERNAL_PARSER_PREF)); final String command = form.format(arguments); final String parserResult = PHPStartApacheAction.getParserOutput(command, "External parser: "); try { // parse the buffer to find the errors and warnings createMarkers(parserResult, file); } catch (CoreException e) { } } /** * Create markers according to the external parser output. * @param output the external parser output * @param file the file that was parsed. */ protected static void createMarkers(final String output, final IFile file) throws CoreException { // delete all markers // file.deleteMarkers(IMarker.PROBLEM, false, 0); PHPBuilder.removeProblemsAndTasksFor(file); int indx = 0; int brIndx; boolean flag = true; while ((brIndx = output.indexOf("
", indx)) != -1) { // newer php error output (tested with 4.2.3) scanLine(output, file, indx, brIndx); indx = brIndx + 6; flag = false; } if (flag) { while ((brIndx = output.indexOf("
", indx)) != -1) { // older php error output (tested with 4.2.3) scanLine(output, file, indx, brIndx); indx = brIndx + 4; } } } private static void scanLine(final String output, final IFile file, final int indx, final int brIndx) throws CoreException { String current; // String outLineNumberString; never used final StringBuffer lineNumberBuffer = new StringBuffer(10); char ch; current = output.substring(indx, brIndx); if (current.indexOf(PARSE_WARNING_STRING) != -1 || current.indexOf(PARSE_ERROR_STRING) != -1) { final int onLine = current.indexOf("on line "); if (onLine != -1) { lineNumberBuffer.delete(0, lineNumberBuffer.length()); for (int i = onLine; i < current.length(); i++) { ch = current.charAt(i); if ('0' <= ch && '9' >= ch) { lineNumberBuffer.append(ch); } } final int lineNumber = Integer.parseInt(lineNumberBuffer.toString()); final Hashtable attributes = new Hashtable(); current = StringUtil.replaceAll(current, "\n", ""); current = StringUtil.replaceAll(current, "", ""); current = StringUtil.replaceAll(current, "", ""); MarkerUtilities.setMessage(attributes, current); if (current.indexOf(PARSE_ERROR_STRING) != -1) attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR)); else if (current.indexOf(PARSE_WARNING_STRING) != -1) attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING)); else attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO)); MarkerUtilities.setLineNumber(attributes, lineNumber); // MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM); MarkerUtilities.createMarker(file, attributes, IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER); } } } /** * This will parse the file and generate the outline info * @param parent the parent object * @param s the string that should be parsed * @return the outline info */ public abstract PHPOutlineInfo parseInfo(Object parent, String s); /** * This will change the file to parse. * @param fileToParse the file that should be parsed */ public abstract void setFileToParse(IFile fileToParse); /** * This will parse the given string * @param s the string to parse * @throws CoreException an exception that can be launched */ public abstract void parse(String s) throws CoreException; /** * This will set a marker. * @param file the file that generated the marker * @param message the message * @param charStart the starting character * @param charEnd the end character * @param errorLevel the error level ({@link PHPParserSuperclass#ERROR}, * {@link PHPParserSuperclass#INFO},{@link PHPParserSuperclass#WARNING}),{@link PHPParserSuperclass#TASK}) * @throws CoreException an exception throwed by the MarkerUtilities */ public static void setMarker( final IFile file, final String message, final int charStart, final int charEnd, final int errorLevel) throws CoreException { if (file != null) { final Hashtable attributes = new Hashtable(); MarkerUtilities.setMessage(attributes, message); switch (errorLevel) { case ERROR: attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR)); break; case WARNING: attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING)); break; case INFO: attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO)); break; case TASK: attributes.put(IMarker.SEVERITY, new Integer(IMarker.TASK)); break; } MarkerUtilities.setCharStart(attributes, charStart); MarkerUtilities.setCharEnd(attributes, charEnd); // MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM); MarkerUtilities.createMarker(file, attributes, IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER); } } /** * This will set a marker. * @param file the file that generated the marker * @param message the message * @param line the line number * @param errorLevel the error level ({@link PHPParserSuperclass#ERROR}, * {@link PHPParserSuperclass#INFO},{@link PHPParserSuperclass#WARNING}) * @throws CoreException an exception throwed by the MarkerUtilities */ public static void setMarker(final IFile file, final String message, final int line, final int errorLevel, final String location) throws CoreException { if (file != null) { // String markerKind = IMarker.PROBLEM; String markerKind = IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER; final Hashtable attributes = new Hashtable(); MarkerUtilities.setMessage(attributes, message); switch (errorLevel) { case ERROR: attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR)); break; case WARNING: attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING)); break; case INFO: attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO)); break; case TASK: attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO)); // markerKind = IMarker.TASK; markerKind = IJavaModelMarker.TASK_MARKER; break; } attributes.put(IMarker.LOCATION, location); MarkerUtilities.setLineNumber(attributes, line); MarkerUtilities.createMarker(file, attributes, markerKind); } } /** * This will set a marker. * @param message the message * @param charStart the starting character * @param charEnd the end character * @param errorLevel the error level ({@link PHPParserSuperclass#ERROR}, * {@link PHPParserSuperclass#INFO},{@link PHPParserSuperclass#WARNING}) * @throws CoreException an exception throwed by the MarkerUtilities */ public static void setMarker(final String message, final int charStart, final int charEnd, final int errorLevel, final String location) throws CoreException { if (fileToParse != null) { setMarker(fileToParse, message, charStart, charEnd, errorLevel, location); } } /** * This will set a marker. * @param file the file that generated the marker * @param message the message * @param charStart the starting character * @param charEnd the end character * @param errorLevel the error level ({@link PHPParserSuperclass#ERROR}, * {@link PHPParserSuperclass#INFO},{@link PHPParserSuperclass#WARNING}) * @param location the location of the error * @throws CoreException an exception throwed by the MarkerUtilities */ public static void setMarker(final IFile file, final String message, final int charStart, final int charEnd, final int errorLevel, final String location) throws CoreException { if (file != null) { final Hashtable attributes = new Hashtable(); MarkerUtilities.setMessage(attributes, message); switch (errorLevel) { case ERROR: attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR)); break; case WARNING: attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING)); break; case INFO: attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO)); break; case TASK: attributes.put(IMarker.SEVERITY, new Integer(IMarker.TASK)); break; } attributes.put(IMarker.LOCATION, location); MarkerUtilities.setCharStart(attributes, charStart); MarkerUtilities.setCharEnd(attributes, charEnd); // MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM); MarkerUtilities.createMarker(file, attributes, IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER); } } }