/*
* 08/11/2009
*
* TaskTagParser.java - Parser that scans code comments for task tags.
* Copyright (C) 2009 Robert Futrell
* robert_futrell at users.sourceforge.net
* http://fifesoft.com/rsyntaxtextarea
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
package org.fife.ui.rsyntaxtextarea.parser;
import java.awt.Color;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import javax.swing.text.Element;
import org.fife.ui.rsyntaxtextarea.RSyntaxDocument;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
import org.fife.ui.rsyntaxtextarea.Token;
/**
* Parser that identifies "task tags," such as "<code>TODO</code>", "<code>FIXME</code>", etc. in source code comments.
*
* @author Robert Futrell
* @version 1.0
*/
public class TaskTagParser extends AbstractParser {
private DefaultParseResult result;
private String DEFAULT_TASK_PATTERN = "TODO|FIXME|HACK";
private Pattern taskPattern;
private static final Color COLOR = new Color(48, 150, 252);
/**
* Creates a new task parser. The default parser treats the following identifiers in comments as task definitions: "
* <code>TODO</code>", "<code>FIXME</code>", and "<code>HACK</code>".
*/
public TaskTagParser() {
result = new DefaultParseResult(this);
setTaskPattern(DEFAULT_TASK_PATTERN);
}
/**
* Returns the regular expression used to search for tasks.
*
* @return The regular expression. This may be <code>null</code> if no regular expression was specified (or an empty
* string was specified).
* @see #setTaskPattern(String)
*/
public String getTaskPattern() {
return taskPattern == null ? null : taskPattern.pattern();
}
public ParseResult parse(RSyntaxDocument doc, String style) {
Element root = doc.getDefaultRootElement();
int lineCount = root.getElementCount();
if (taskPattern == null ||
style == null || SyntaxConstants.SYNTAX_STYLE_NONE.equals(style)) {
result.clearNotices();
result.setParsedLines(0, lineCount - 1);
return result;
}
// TODO: Pass in parsed line range and just do that
result.clearNotices();
result.setParsedLines(0, lineCount - 1);
for (int line = 0; line < lineCount; line++) {
Token t = doc.getTokenListForLine(line);
int offs = -1;
int start = -1;
String text = null;
while (t != null && t.isPaintable()) {
if (t.isComment()) {
offs = t.offset;
text = t.getLexeme();
Matcher m = taskPattern.matcher(text);
if (m.find()) {
start = m.start();
offs += start;
break;
}
}
t = t.getNextToken();
}
if (start > -1) {
text = text.substring(start);
// TODO: Strip off end of MLC's if they're there.
int len = text.length();
TaskNotice pn = new TaskNotice(this, text, line, offs, len);
pn.setLevel(ParserNotice.INFO);
pn.setShowInEditor(false);
pn.setColor(COLOR);
result.addNotice(pn);
}
}
return result;
}
/**
* Sets the pattern of task identifiers. You will usually want this to be a list of words "or'ed" together, such as
* "<code>TODO|FIXME|HACK|REMIND</code>".
*
* @param pattern
* The pattern. A value of <code>null</code> or an empty string effectively disables task parsing.
* @throws PatternSyntaxException
* If <code>pattern</code> is an invalid regular expression.
* @see #getTaskPattern()
*/
public void setTaskPattern(String pattern) throws PatternSyntaxException {
if (pattern == null || pattern.length() == 0) {
taskPattern = null;
}
else {
taskPattern = Pattern.compile(pattern);
}
}
/**
* A parser notice that signifies a task.
*/
public static class TaskNotice extends DefaultParserNotice {
public TaskNotice(Parser parser, String message, int line, int offs,
int length) {
super(parser, message, line, offs, length);
}
}
}