package bluej.parser;
import java.io.Reader;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import bluej.parser.lexer.JavaTokenTypes;
import bluej.parser.lexer.LocatableToken;
| A parser which extracts certain information needed for BlueJ's unit test
| (junit) functionality.
|
| @author Davin McCall
|
public class UnitTestParser
extends JavaParser{
private int classLevel = 0;
private boolean inMethod = false;
private String methodName;
private LocatableToken methodBegin;
private boolean isPublic = false;
private boolean haveClassInfo = false;
private List<SourceSpan> fieldSpans = new LinkedList<SourceSpan>();
private SourceLocation methodInsertLocation;
private SourceLocation fixtureInsertLocation;
private Map<String,SourceSpan> methodSpans = new HashMap<String,SourceSpan>();
private Stack<SourceLocation> fieldStarts = new Stack<SourceLocation>();
public UnitTestParser(Reader r)
{
super(r);
try {
parseCU();
}
catch (Exception e) {
}
}
public List getFieldSpans()
{
return fieldSpans;
}
public SourceLocation getNewMethodInsertLocation()
{
return methodInsertLocation;
}
public SourceLocation getFixtureInsertLocation()
{
return fixtureInsertLocation;
}
public SourceSpan getMethodBlockSpan(String name)
{
return methodSpans.get(name);
}
@Override
protected void error(String msg, int beginLine, int beginColumn, int endLine, int endColumn)
{
throw new RuntimeException("Parse error: " + msg);
}
@Override
protected void gotModifier(LocatableToken token)
{
if (token.getType() == JavaTokenTypes.LITERAL_public) {
isPublic = true;
}
}
@Override
protected void modifiersConsumed()
{
isPublic = false;
}
@Override
protected void gotField(LocatableToken first, LocatableToken idToken, boolean initExpressionFollows)
{
if (classLevel == 1 && !haveClassInfo) {
fieldStarts.push(new SourceLocation(first.getLine(), first.getColumn()));
}
}
@Override
protected void endFieldDeclarations(LocatableToken token, boolean included)
{
if (classLevel == 1 && !haveClassInfo) {
SourceLocation start = fieldStarts.pop();
SourceLocation end = new SourceLocation(token.getEndLine(), token.getEndColumn());
SourceSpan ss = new SourceSpan(start, end);
fieldSpans.add(ss);
}
}
@Override
protected void gotTypeDef(LocatableToken firstToken, int tdType)
{
classLevel++;
if (haveClassInfo && isPublic) {
haveClassInfo = false;
fieldSpans = new LinkedList<SourceSpan>();
methodSpans = new HashMap<String,SourceSpan>();
}
}
@Override
protected void beginTypeBody(LocatableToken leftCurlyToken)
{
if (classLevel == 1) {
fixtureInsertLocation = new SourceLocation(leftCurlyToken.getLine(),
leftCurlyToken.getColumn());
}
}
@Override
protected void gotTypeDefEnd(LocatableToken token, boolean included)
{
classLevel--;
endElement(token, included);
if (classLevel == 0) {
haveClassInfo = true;
methodInsertLocation = new SourceLocation(token.getLine(), token.getColumn());
}
}
@Override
protected void gotMethodDeclaration(LocatableToken token,
LocatableToken hiddenToken)
{
if (classLevel == 1 && ! haveClassInfo) {
inMethod = true;
methodName = token.getText();
}
}
@Override
protected void gotMethodParameter(LocatableToken token, LocatableToken ellipsisToken)
{
inMethod = false;
}
@Override
protected void beginMethodBody(LocatableToken token)
{
if (inMethod) {
methodBegin = token;
}
}
@Override
protected void endMethodBody(LocatableToken token, boolean included)
{
if (classLevel == 1 && !haveClassInfo && methodBegin != null) {
SourceLocation start = new SourceLocation(methodBegin.getLine(), methodBegin.getColumn());
SourceLocation end = new SourceLocation(token.getEndLine(), token.getEndColumn());
SourceSpan ss = new SourceSpan(start, end);
methodSpans.put(methodName, ss);
}
}
}
top,
use,
map,
class UnitTestParser
. UnitTestParser
. getFieldSpans
. getNewMethodInsertLocation
. getFixtureInsertLocation
. getMethodBlockSpan
. error
. gotModifier
. modifiersConsumed
. gotField
. endFieldDeclarations
. gotTypeDef
. beginTypeBody
. gotTypeDefEnd
. gotMethodDeclaration
. gotMethodParameter
. beginMethodBody
. endMethodBody
235 neLoCode
+ 3 LoComm