eatIdentifier("declare");
String kind = parseIdentifier();
- eat(":");
Declare ret;
if (kind.equals("error")) {
+ eat(":");
ret = parseErrorOrWarning(true);
} else if (kind.equals("warning")) {
+ eat(":");
ret = parseErrorOrWarning(false);
} else if (kind.equals("precedence")) {
+ eat(":");
ret = parseDominates();
} else if (kind.equals("dominates")) {
throw new ParserException("name changed to declare precedence", tokenSource.peek(-2));
} else if (kind.equals("parents")) {
ret = parseParents();
} else if (kind.equals("soft")) {
+ eat(":");
ret = parseSoft();
} else {
throw new ParserException("expected one of error, warning, parents, soft, dominates",
private Declare parseParents() {
TypeVariablePatternList typeParameters = maybeParseTypeVariableList();
+ eat(":");
TypePattern p = parseTypePattern(false,false);
IToken t = tokenSource.next();
if (!(t.getString().equals("extends") || t.getString().equals("implements"))) {
String kind = parseIdentifier();
IToken possibleTypeVariableToken = tokenSource.peek();
TypeVariablePatternList typeVariables = maybeParseSimpleTypeVariableList();
- tokenSource.setIndex(start);
if (kind.equals("execution") || kind.equals("call") ||
kind.equals("get") || kind.equals("set")) {
- p = parseKindedPointcut();
+ p = parseKindedPointcut(kind);
} else if (kind.equals("args")) {
+ assertNoTypeVariables(typeVariables,
+ "( - type variables not allowed with args pointcut designator"
+ , possibleTypeVariableToken);
p = parseArgsPointcut();
- } else if (kind.equals("this") || kind.equals("target")) {
- p = parseThisOrTargetPointcut();
+ } else if (kind.equals("this")) {
+ assertNoTypeVariables(typeVariables,
+ "( - type variables not allowed with 'this' pointcut designator"
+ , possibleTypeVariableToken);
+ p = parseThisOrTargetPointcut(kind);
+ } else if (kind.equals("target")) {
+ assertNoTypeVariables(typeVariables,
+ "( - type variables not allowed with target pointcut designator"
+ , possibleTypeVariableToken);
+ p = parseThisOrTargetPointcut(kind);
} else if (kind.equals("within")) {
p = parseWithinPointcut();
} else if (kind.equals("withincode")) {
p = parseWithinCodePointcut();
} else if (kind.equals("cflow")) {
+ assertNoTypeVariables(typeVariables,
+ "( - type variables not allowed with cflow pointcut designator"
+ , possibleTypeVariableToken);
p = parseCflowPointcut(false);
} else if (kind.equals("cflowbelow")) {
+ assertNoTypeVariables(typeVariables,
+ "( - type variables not allowed with cflowbelow pointcut designator"
+ , possibleTypeVariableToken);
p = parseCflowPointcut(true);
} else if (kind.equals("adviceexecution")) {
- parseIdentifier(); eat("(");
+ assertNoTypeVariables(typeVariables,
+ "( - type variables not allowed with adviceexecution pointcut designator"
+ , possibleTypeVariableToken);
+ eat("(");
eat(")");
p = new KindedPointcut(Shadow.AdviceExecution,
new SignaturePattern(Member.ADVICE, ModifiersPattern.ANY,
ThrowsPattern.ANY,
AnnotationTypePattern.ANY));
} else if (kind.equals("handler")) {
- parseIdentifier(); eat("(");
+ assertNoTypeVariables(typeVariables,"( - type variables not allowed with handler pointcut designator",possibleTypeVariableToken);
+ eat("(");
TypePattern typePat = parseTypePattern(false,true);
eat(")");
p = new HandlerPointcut(typePat);
} else if (kind.equals("initialization")) {
- parseIdentifier(); eat("(");
+ eat("(");
SignaturePattern sig = parseConstructorSignaturePattern();
eat(")");
p = new KindedPointcut(Shadow.Initialization, sig);
} else if (kind.equals("staticinitialization")) {
- parseIdentifier(); eat("(");
+ eat("(");
TypePattern typePat = parseTypePattern(false,true);
eat(")");
p = new KindedPointcut(Shadow.StaticInitialization,
TypePattern.ANY, typePat, NamePattern.ANY, TypePatternList.EMPTY,
ThrowsPattern.ANY,AnnotationTypePattern.ANY));
} else if (kind.equals("preinitialization")) {
- parseIdentifier(); eat("(");
+ eat("(");
SignaturePattern sig = parseConstructorSignaturePattern();
eat(")");
p = new KindedPointcut(Shadow.PreInitialization, sig);
} else if (kind.equals("if")) {
- // @style support allows if(), if(true), if(false)
- parseIdentifier();
+ // @style support allows if(), if(true), if(false)
+ assertNoTypeVariables(typeVariables,
+ "( - type variables not allowed with if pointcut designator"
+ , possibleTypeVariableToken);
eat("(");
if (maybeEatIdentifier("true")) {
eat(")");
}
}
else {
+ tokenSource.setIndex(start);
p = parseReferencePointcut();
if (typeVariables != null)
throw new ParserException("type variable specification not allowed for reference pointcuts",possibleTypeVariableToken);
return p;
}
+ private void assertNoTypeVariables(TypeVariablePatternList tvs, String errorMessage,IToken token) {
+ if ( tvs != null ) throw new ParserException(errorMessage,token);
+ }
+
public Pointcut parseAnnotationPointcut() {
int start = tokenSource.getIndex();
IToken t = tokenSource.peek();
String kind = parseIdentifier();
+ IToken possibleTypeVariableToken = tokenSource.peek();
+ TypeVariablePatternList typeVariables = maybeParseSimpleTypeVariableList();
+ if (typeVariables != null) {
+ String message = "( - type variables not allowed with @" +
+ kind + " pointcut designator";
+ assertNoTypeVariables(typeVariables, message, possibleTypeVariableToken);
+ }
tokenSource.setIndex(start);
if (kind.equals("annotation")) {
return parseAtAnnotationPointcut();
private Pointcut parseWithinCodePointcut() {
- parseIdentifier();
+ //parseIdentifier();
eat("(");
SignaturePattern sig = parseMethodOrConstructorSignaturePattern();
eat(")");
}
private Pointcut parseCflowPointcut(boolean isBelow) {
- parseIdentifier();
+ //parseIdentifier();
eat("(");
Pointcut entry = parsePointcut();
eat(")");
* @return Pointcut
*/
private Pointcut parseWithinPointcut() {
- parseIdentifier();
+ //parseIdentifier();
eat("(");
TypePattern type = parseTypePattern();
eat(")");
* Method parseThisOrTargetPointcut.
* @return Pointcut
*/
- private Pointcut parseThisOrTargetPointcut() {
- String kind = parseIdentifier();
+ private Pointcut parseThisOrTargetPointcut(String kind) {
eat("(");
TypePattern type = parseTypePattern();
eat(")");
* @return Pointcut
*/
private Pointcut parseArgsPointcut() {
- parseIdentifier();
+ //parseIdentifier();
TypePatternList arguments = parseArgumentsPattern();
return new ArgsPointcut(arguments);
}
- private KindedPointcut parseKindedPointcut() {
- String kind = parseIdentifier();
+ private KindedPointcut parseKindedPointcut(String kind) {
eat("(");
SignaturePattern sig;
int startPos = tokenSource.peek().getStart();
AnnotationTypePattern annotationPattern = maybeParseAnnotationPattern();
ModifiersPattern modifiers = parseModifiersPattern();
- TypePattern returnType = parseTypePattern();
+ TypePattern returnType = parseTypePattern(false,true);
TypePattern declaringType;
NamePattern name = null;
} else {
kind = Member.METHOD;
IToken nameToken = tokenSource.peek();
- declaringType = parseTypePattern();
+ declaringType = parseTypePattern(false,true);
if (maybeEat(".")) {
nameToken = tokenSource.peek();
name = parseNamePattern();
TypeVariable tv = new TypeVariable(typeVarName);
typeVars.add(tv);
} while (maybeEat(","));
- eat(">");
+ eat(">","',' or '>'");
TypeVariable[] tvs = new TypeVariable[typeVars.size()];
typeVars.toArray(tvs);
return new TypeVariablePatternList(tvs);
}
public void eat(String expectedValue) {
+ eat(expectedValue,expectedValue);
+ }
+
+ private void eat(String expectedValue,String expectedMessage) {
IToken next = tokenSource.next();
if (next.getString() != expectedValue) {
- throw new ParserException(expectedValue, next);
+ throw new ParserException(expectedMessage, next);
}
}
}
public void testParseDeclareParentsWithTypeParameterList() {
- PatternParser parser = new PatternParser("declare parents : <T> Foo<T> implements IveGoneMad");
+ PatternParser parser = new PatternParser("declare parents<T> : Foo<T> implements IveGoneMad");
DeclareParents decp = (DeclareParents) parser.parseDeclare();
TypeVariablePatternList tvp = decp.getTypeParameters();
assertEquals("one type parameter",1,tvp.getTypeVariablePatterns().length);
try {
TypeVariablePatternList tl = parser.maybeParseSimpleTypeVariableList();
} catch (ParserException ex) {
- assertEquals("Expecting >",">",ex.getMessage());
+ assertEquals("Expecting ',' or '>'","',' or '>'",ex.getMessage());
}
}
+
+ // test cases for pointcuts involving type variable specification.
+ public void testParseCallPCDWithTypeVariables() {
+ PatternParser parser = new PatternParser("call<T>(* Foo<T>.*(T))");
+ Pointcut pc = parser.parsePointcut();
+ TypeVariable[] tvps = pc.getTypeVariables().getTypeVariablePatterns();
+ assertEquals("1 type variable",1,tvps.length);
+ assertEquals("T",tvps[0].getName());
+ }
+
+ public void testParseCallPCDWithIllegalBounds() {
+ PatternParser parser = new PatternParser("call<T extends Number>(* Foo<T>.*(T))");
+ try {
+ parser.parsePointcut();
+ fail("Expecting parse exception");
+ } catch (ParserException pEx) {
+ assertEquals("',' or '>'",pEx.getMessage());
+ }
+ }
+
+ public void testNoTypeVarsForHandler() {
+ PatternParser parser = new PatternParser("handler<T>(Exception<T>)");
+ try {
+ parser.parsePointcut();
+ fail("Expecting parse exception");
+ } catch (ParserException pEx) {
+ assertEquals("( - type variables not allowed with handler pointcut designator",pEx.getMessage());
+ }
+ }
+
+ public void testNoTypeVarsForThis() {
+ PatternParser parser = new PatternParser("this<T>(Exception<T>)");
+ try {
+ parser.parsePointcut();
+ fail("Expecting parse exception");
+ } catch (ParserException pEx) {
+ assertEquals("( - type variables not allowed with 'this' pointcut designator",pEx.getMessage());
+ }
+ }
+
+ public void testNoTypeVarsForTarget() {
+ PatternParser parser = new PatternParser("target<T>(Exception<T>)");
+ try {
+ parser.parsePointcut();
+ fail("Expecting parse exception");
+ } catch (ParserException pEx) {
+ assertEquals("( - type variables not allowed with target pointcut designator",pEx.getMessage());
+ }
+ }
+
+ public void testNoTypeVarsForArgs() {
+ PatternParser parser = new PatternParser("args<T>(Exception<T>)");
+ try {
+ parser.parsePointcut();
+ fail("Expecting parse exception");
+ } catch (ParserException pEx) {
+ assertEquals("( - type variables not allowed with args pointcut designator",pEx.getMessage());
+ }
+ }
+
+ public void testNoTypeVarsForIf() {
+ PatternParser parser = new PatternParser("if<T>(true)");
+ try {
+ parser.parsePointcut();
+ fail("Expecting parse exception");
+ } catch (ParserException pEx) {
+ assertEquals("( - type variables not allowed with if pointcut designator",pEx.getMessage());
+ }
+ }
+
+ public void testNoTypeVarsForCflow() {
+ PatternParser parser = new PatternParser("cflow<T>(call(* *(..)))");
+ try {
+ parser.parsePointcut();
+ fail("Expecting parse exception");
+ } catch (ParserException pEx) {
+ assertEquals("( - type variables not allowed with cflow pointcut designator",pEx.getMessage());
+ }
+ }
+
+ public void testNoTypeVarsForCflowbelow() {
+ PatternParser parser = new PatternParser("cflowbelow<T>(call(* *(..)))");
+ try {
+ parser.parsePointcut();
+ fail("Expecting parse exception");
+ } catch (ParserException pEx) {
+ assertEquals("( - type variables not allowed with cflowbelow pointcut designator",pEx.getMessage());
+ }
+ }
+
+ public void testNoTypeVarsForAtWithin() {
+ PatternParser parser = new PatternParser("@within<T>(Foo<T>)");
+ try {
+ parser.parsePointcut();
+ fail("Expecting parse exception");
+ } catch (ParserException pEx) {
+ assertEquals("( - type variables not allowed with @within pointcut designator",pEx.getMessage());
+ }
+ }
+
+ public void testNoTypeVarsForAtAnnotation() {
+ PatternParser parser = new PatternParser("@annotation<T>(Foo<T>)");
+ try {
+ parser.parsePointcut();
+ fail("Expecting parse exception");
+ } catch (ParserException pEx) {
+ assertEquals("( - type variables not allowed with @annotation pointcut designator",pEx.getMessage());
+ }
+ }
+
+ public void testNoTypeVarsForAtWithinCode() {
+ PatternParser parser = new PatternParser("@withincode<T>(* Foo<T>.*(..))");
+ try {
+ parser.parsePointcut();
+ fail("Expecting parse exception");
+ } catch (ParserException pEx) {
+ assertEquals("( - type variables not allowed with @withincode pointcut designator",pEx.getMessage());
+ }
+ }
+
+ public void testNoTypeVarsForAtThis() {
+ PatternParser parser = new PatternParser("@this<T>(Exception<T>)");
+ try {
+ parser.parsePointcut();
+ fail("Expecting parse exception");
+ } catch (ParserException pEx) {
+ assertEquals("( - type variables not allowed with @this pointcut designator",pEx.getMessage());
+ }
+ }
+
+ public void testNoTypeVarsForAtTarget() {
+ PatternParser parser = new PatternParser("@target<T>(Exception<T>)");
+ try {
+ parser.parsePointcut();
+ fail("Expecting parse exception");
+ } catch (ParserException pEx) {
+ assertEquals("( - type variables not allowed with @target pointcut designator",pEx.getMessage());
+ }
+ }
+
+ public void testNoTypeVarsForAtArgs() {
+ PatternParser parser = new PatternParser("@args<T>(Exception<T>)");
+ try {
+ parser.parsePointcut();
+ fail("Expecting parse exception");
+ } catch (ParserException pEx) {
+ assertEquals("( - type variables not allowed with @args pointcut designator",pEx.getMessage());
+ }
+ }
+
+ public void testExecutionWithTypeVariables() {
+ PatternParser parser = new PatternParser("execution<T>(T Bar<T>.doSomething())");
+ Pointcut pc = parser.parsePointcut();
+ TypeVariable[] tvs = pc.getTypeVariables().getTypeVariablePatterns();
+ assertEquals("1 type pattern",1,tvs.length);
+ assertEquals("T",tvs[0].getName());
+ }
+
+ public void testInitializationWithTypeVariables() {
+ PatternParser parser = new PatternParser("initialization<T>(Bar<T>.new())");
+ Pointcut pc = parser.parsePointcut();
+ TypeVariable[] tvs = pc.getTypeVariables().getTypeVariablePatterns();
+ assertEquals("1 type pattern",1,tvs.length);
+ assertEquals("T",tvs[0].getName());
+ }
+
+ public void testPreInitializationWithTypeVariables() {
+ PatternParser parser = new PatternParser("preinitialization<T>(Bar<T>.new())");
+ Pointcut pc = parser.parsePointcut();
+ TypeVariable[] tvs = pc.getTypeVariables().getTypeVariablePatterns();
+ assertEquals("1 type pattern",1,tvs.length);
+ assertEquals("T",tvs[0].getName());
+ }
+
+ public void testStaticInitializationWithTypeVariables() {
+ PatternParser parser = new PatternParser("staticinitialization<T>(Bar<T>)");
+ Pointcut pc = parser.parsePointcut();
+ TypeVariable[] tvs = pc.getTypeVariables().getTypeVariablePatterns();
+ assertEquals("1 type pattern",1,tvs.length);
+ assertEquals("T",tvs[0].getName());
+ }
+
+ public void testWithinWithTypeVariables() {
+ PatternParser parser = new PatternParser("within<T>(Bar<T>)");
+ Pointcut pc = parser.parsePointcut();
+ TypeVariable[] tvs = pc.getTypeVariables().getTypeVariablePatterns();
+ assertEquals("1 type pattern",1,tvs.length);
+ assertEquals("T",tvs[0].getName());
+ }
+
+ public void testTypeParamList() {
+ PatternParser parser = new PatternParser("Bar<T,S extends T, R extends S>");
+ TypePattern tp = parser.parseTypePattern(false,true);
+ TypePattern[] tps = tp.getTypeParameters().getTypePatterns();
+ assertEquals("3 type patterns",3,tps.length);
+ assertEquals("T",tps[0].toString());
+ assertEquals("S",tps[1].toString());
+ assertEquals("R",tps[2].toString());
+ }
+
+ public void testWithinCodeWithTypeVariables() {
+ PatternParser parser = new PatternParser("withincode<T,S,R>(Bar<T,S extends T, R extends S>.new())");
+ Pointcut pc = parser.parsePointcut();
+ TypeVariable[] tvs = pc.getTypeVariables().getTypeVariablePatterns();
+ assertEquals("3 type patterns",3,tvs.length);
+ assertEquals("T",tvs[0].getName());
+ assertEquals("S",tvs[1].getName());
+ assertEquals("R",tvs[2].getName());
+ }
+
+ public void testCallWithTypeVariables() {
+ PatternParser parser = new PatternParser("call<T>(* Bar<T>.*(..))");
+ Pointcut pc = parser.parsePointcut();
+ TypeVariable[] tvs = pc.getTypeVariables().getTypeVariablePatterns();
+ assertEquals("1 type pattern",1,tvs.length);
+ assertEquals("T",tvs[0].getName());
+ }
+
+ public void testGetWithTypeVariables() {
+ PatternParser parser = new PatternParser("get<T>(* Bar<T>.*)");
+ Pointcut pc = parser.parsePointcut();
+ TypeVariable[] tvs = pc.getTypeVariables().getTypeVariablePatterns();
+ assertEquals("1 type pattern",1,tvs.length);
+ assertEquals("T",tvs[0].getName());
+ }
+
+ public void testSetWithTypeVariables() {
+ PatternParser parser = new PatternParser("set<T>(* Bar<T>.*)");
+ Pointcut pc = parser.parsePointcut();
+ TypeVariable[] tvs = pc.getTypeVariables().getTypeVariablePatterns();
+ assertEquals("1 type pattern",1,tvs.length);
+ assertEquals("T",tvs[0].getName());
+ }
+
public TestScope makeSimpleScope() {
TestScope s = new TestScope(new String[] {"int", "java.lang.String"}, new String[] {"a", "b"}, world);