summaryrefslogtreecommitdiffstats
path: root/weaver
diff options
context:
space:
mode:
Diffstat (limited to 'weaver')
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/AndAnnotationTypePattern.java3
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/AndTypePattern.java19
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/BindingTypePattern.java2
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/ExactAnnotationTypePattern.java18
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/ExactTypePattern.java17
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/NotAnnotationTypePattern.java6
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/NotTypePattern.java16
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/OrAnnotationTypePattern.java3
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/OrTypePattern.java20
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/PatternParser.java252
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/SignaturePattern.java18
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java4
-rw-r--r--weaver/testsrc/org/aspectj/weaver/patterns/AnnotationPatternTestCase.java250
-rw-r--r--weaver/testsrc/org/aspectj/weaver/patterns/KindedAnnotationPointcutTestCase.java27
-rw-r--r--weaver/testsrc/org/aspectj/weaver/patterns/PatternsTests.java2
15 files changed, 495 insertions, 162 deletions
diff --git a/weaver/src/org/aspectj/weaver/patterns/AndAnnotationTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/AndAnnotationTypePattern.java
index 3d4eb11e9..c6679a980 100644
--- a/weaver/src/org/aspectj/weaver/patterns/AndAnnotationTypePattern.java
+++ b/weaver/src/org/aspectj/weaver/patterns/AndAnnotationTypePattern.java
@@ -79,5 +79,8 @@ public class AndAnnotationTypePattern extends AnnotationTypePattern {
public String toString() {
return "(" + left.toString() + " && " + right.toString() + ")";
}
+
+ public AnnotationTypePattern getLeft() { return left; }
+ public AnnotationTypePattern getRight() { return right; }
}
diff --git a/weaver/src/org/aspectj/weaver/patterns/AndTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/AndTypePattern.java
index bb94f602d..0752746fc 100644
--- a/weaver/src/org/aspectj/weaver/patterns/AndTypePattern.java
+++ b/weaver/src/org/aspectj/weaver/patterns/AndTypePattern.java
@@ -97,7 +97,24 @@ public class AndTypePattern extends TypePattern {
}
public String toString() {
- return "(" + left.toString() + " && " + right.toString() + ")";
+ StringBuffer buff = new StringBuffer();
+ if (annotationPattern != AnnotationTypePattern.ANY) {
+ buff.append('(');
+ if (! (annotationPattern instanceof ExactAnnotationTypePattern )) {
+ buff.append('@');
+ }
+ buff.append(annotationPattern.toString());
+ buff.append(' ');
+ }
+ buff.append('(');
+ buff.append(left.toString());
+ buff.append(" && ");
+ buff.append(right.toString());
+ buff.append(')');
+ if (annotationPattern != AnnotationTypePattern.ANY) {
+ buff.append(')');
+ }
+ return buff.toString();
}
}
diff --git a/weaver/src/org/aspectj/weaver/patterns/BindingTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/BindingTypePattern.java
index 937563c79..e2633aa3f 100644
--- a/weaver/src/org/aspectj/weaver/patterns/BindingTypePattern.java
+++ b/weaver/src/org/aspectj/weaver/patterns/BindingTypePattern.java
@@ -74,6 +74,6 @@ public class BindingTypePattern extends ExactTypePattern implements BindingPatte
public String toString() {
//Thread.currentThread().dumpStack();
- return "BindingTypePattern(" + type.toString() + ", " + formalIndex + ")";
+ return "BindingTypePattern(" + super.toString() + ", " + formalIndex + ")";
}
}
diff --git a/weaver/src/org/aspectj/weaver/patterns/ExactAnnotationTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/ExactAnnotationTypePattern.java
index 3db7d0030..f60c67df3 100644
--- a/weaver/src/org/aspectj/weaver/patterns/ExactAnnotationTypePattern.java
+++ b/weaver/src/org/aspectj/weaver/patterns/ExactAnnotationTypePattern.java
@@ -27,6 +27,7 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern {
protected TypeX annotationType;
protected String formalName;
+ private boolean resolved = true;
/**
*
@@ -37,6 +38,7 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern {
public ExactAnnotationTypePattern(String formalName) {
this.formalName = formalName;
+ this.resolved = false;
// will be turned into BindingAnnotationTypePattern during resolution
}
@@ -51,6 +53,8 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern {
*/
public AnnotationTypePattern resolveBindings(IScope scope,
Bindings bindings, boolean allowBinding) {
+ if (resolved) return this;
+ resolved = true;
if (formalName != null) {
FormalBinding formalBinding = scope.lookupFormal(formalName);
if (formalBinding != null) {
@@ -85,7 +89,12 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern {
public void write(DataOutputStream s) throws IOException {
s.writeByte(AnnotationTypePattern.EXACT);
s.writeByte(VERSION);
- annotationType.write(s);
+ s.writeBoolean(resolved);
+ if (resolved) {
+ annotationType.write(s);
+ } else {
+ s.writeUTF(formalName);
+ }
writeLocation(s);
}
@@ -95,7 +104,12 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern {
if (version > VERSION) {
throw new BCException("ExactAnnotationTypePattern was written by a newer version of AspectJ");
}
- ret = new ExactAnnotationTypePattern(TypeX.read(s));
+ boolean isResolved = s.readBoolean();
+ if (isResolved) {
+ ret = new ExactAnnotationTypePattern(TypeX.read(s));
+ } else {
+ ret = new ExactAnnotationTypePattern(s.readUTF());
+ }
ret.readLocation(context,s);
return ret;
}
diff --git a/weaver/src/org/aspectj/weaver/patterns/ExactTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/ExactTypePattern.java
index 36917a297..755e025e2 100644
--- a/weaver/src/org/aspectj/weaver/patterns/ExactTypePattern.java
+++ b/weaver/src/org/aspectj/weaver/patterns/ExactTypePattern.java
@@ -182,8 +182,21 @@ public class ExactTypePattern extends TypePattern {
}
public String toString() {
- //Thread.currentThread().dumpStack();
- return type.toString() + (includeSubtypes ? "+" : "");
+ StringBuffer buff = new StringBuffer();
+ if (annotationPattern != AnnotationTypePattern.ANY) {
+ buff.append('(');
+ if (! (annotationPattern instanceof ExactAnnotationTypePattern )) {
+ buff.append('@');
+ }
+ buff.append(annotationPattern.toString());
+ buff.append(' ');
+ }
+ buff.append(type.toString());
+ if (includeSubtypes) buff.append('+');
+ if (annotationPattern != AnnotationTypePattern.ANY) {
+ buff.append(')');
+ }
+ return buff.toString();
}
public TypePattern resolveBindings(IScope scope, Bindings bindings,
boolean allowBinding, boolean requireExactType)
diff --git a/weaver/src/org/aspectj/weaver/patterns/NotAnnotationTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/NotAnnotationTypePattern.java
index e55df2508..d7869d90a 100644
--- a/weaver/src/org/aspectj/weaver/patterns/NotAnnotationTypePattern.java
+++ b/weaver/src/org/aspectj/weaver/patterns/NotAnnotationTypePattern.java
@@ -69,6 +69,10 @@ public class NotAnnotationTypePattern extends AnnotationTypePattern {
}
public String toString() {
- return "!" + negatedPattern.toString();
+ return "(!" + negatedPattern.toString() + ")";
+ }
+
+ public AnnotationTypePattern getNegatedPattern() {
+ return negatedPattern;
}
}
diff --git a/weaver/src/org/aspectj/weaver/patterns/NotTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/NotTypePattern.java
index 17a402e91..02adeadd8 100644
--- a/weaver/src/org/aspectj/weaver/patterns/NotTypePattern.java
+++ b/weaver/src/org/aspectj/weaver/patterns/NotTypePattern.java
@@ -92,6 +92,20 @@ public class NotTypePattern extends TypePattern {
}
public String toString() {
- return "!" + pattern;
+ StringBuffer buff = new StringBuffer();
+ if (annotationPattern != AnnotationTypePattern.ANY) {
+ buff.append('(');
+ if (! (annotationPattern instanceof ExactAnnotationTypePattern )) {
+ buff.append('@');
+ }
+ buff.append(annotationPattern.toString());
+ buff.append(' ');
+ }
+ buff.append('!');
+ buff.append(pattern);
+ if (annotationPattern != AnnotationTypePattern.ANY) {
+ buff.append(')');
+ }
+ return buff.toString();
}
}
diff --git a/weaver/src/org/aspectj/weaver/patterns/OrAnnotationTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/OrAnnotationTypePattern.java
index bd6414d39..0f23f6b2c 100644
--- a/weaver/src/org/aspectj/weaver/patterns/OrAnnotationTypePattern.java
+++ b/weaver/src/org/aspectj/weaver/patterns/OrAnnotationTypePattern.java
@@ -74,4 +74,7 @@ public class OrAnnotationTypePattern extends AnnotationTypePattern {
return "(" + left.toString() + " || " + right.toString() + ")";
}
+ public AnnotationTypePattern getLeft() { return left; }
+ public AnnotationTypePattern getRight() { return right; }
+
}
diff --git a/weaver/src/org/aspectj/weaver/patterns/OrTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/OrTypePattern.java
index 6a423e03c..6d8689eb1 100644
--- a/weaver/src/org/aspectj/weaver/patterns/OrTypePattern.java
+++ b/weaver/src/org/aspectj/weaver/patterns/OrTypePattern.java
@@ -97,7 +97,23 @@ public class OrTypePattern extends TypePattern {
}
public String toString() {
- return "(" + left.toString() + " || " + right.toString() + ")";
+ StringBuffer buff = new StringBuffer();
+ if (annotationPattern != AnnotationTypePattern.ANY) {
+ buff.append('(');
+ if (! (annotationPattern instanceof ExactAnnotationTypePattern )) {
+ buff.append('@');
+ }
+ buff.append(annotationPattern.toString());
+ buff.append(' ');
+ }
+ buff.append('(');
+ buff.append(left.toString());
+ buff.append(" || ");
+ buff.append(right.toString());
+ buff.append(')');
+ if (annotationPattern != AnnotationTypePattern.ANY) {
+ buff.append(')');
+ }
+ return buff.toString();
}
-
}
diff --git a/weaver/src/org/aspectj/weaver/patterns/PatternParser.java b/weaver/src/org/aspectj/weaver/patterns/PatternParser.java
index 8a4324bf9..08ff3a1df 100644
--- a/weaver/src/org/aspectj/weaver/patterns/PatternParser.java
+++ b/weaver/src/org/aspectj/weaver/patterns/PatternParser.java
@@ -482,109 +482,23 @@ public class PatternParser {
}
public TypePattern parseTypePattern() {
- AnnotationTypePattern ap = null;
- TypePattern tp = null;
- PatternNode p = parseAtomicPattern();
- if (isAnnotationPattern(p)) {
- ap = completeAnnotationPattern((AnnotationTypePattern)p);
- IToken tok = tokenSource.peek();
- PatternNode typepat = parseTypePattern();
- if (isAnnotationPattern(p)) {
- throw new ParserException("Duplicate annotation pattern",tok);
- } else {
- tp = (TypePattern) typepat;
- tp.setAnnotationTypePattern(ap);
- }
- } else {
- tp = (TypePattern)p;
- }
+ TypePattern p = parseAtomicTypePattern();
if (maybeEat("&&")) {
- tp = new AndTypePattern(tp, parseNotOrTypePattern());
+ p = new AndTypePattern(p, parseNotOrTypePattern());
}
if (maybeEat("||")) {
- tp = new OrTypePattern(tp, parseTypePattern());
+ p = new OrTypePattern(p, parseTypePattern());
}
- return tp;
- }
-
- private AnnotationTypePattern completeAnnotationPattern(AnnotationTypePattern p) {
- if (maybeEat("&&")) {
- return new AndAnnotationTypePattern(p,parseNotOrAnnotationPattern());
- }
- if (maybeEat("||")) {
- return new OrAnnotationTypePattern(p,parseAnnotationTypePattern(false));
- }
- return p;
- }
-
- private AnnotationTypePattern parseNotOrAnnotationPattern() {
- AnnotationTypePattern p = parseAnnotationTypePattern(false);
- if (maybeEat("&&")) {
- p = new AndAnnotationTypePattern(p,parseAnnotationTypePattern(false));
- }
- return p;
- }
-
- private AnnotationTypePattern parseAnnotationTypePattern(boolean isOptional) {
- IToken tok = tokenSource.peek();
- PatternNode p = parseAtomicPattern();
- if (!isAnnotationPattern(p)) {
- if (isOptional) return null;
- throw new ParserException("Expecting annotation pattern",tok);
- }
- AnnotationTypePattern ap = (AnnotationTypePattern) p;
- if (maybeEat("&&")) {
- ap = new AndAnnotationTypePattern(ap, parseNotOrAnnotationPattern());
- }
-
- if (maybeEat("||")) {
- ap = new OrAnnotationTypePattern(ap, parseAnnotationTypePattern(false));
- }
- return ap;
- }
-
- private AnnotationTypePattern parseAnnotationNameOrVarTypePattern() {
- AnnotationTypePattern p = null;
- int startPos = tokenSource.peek().getStart();
- if (maybeEat(AT)) {
- StringBuffer annotationName = new StringBuffer();
- annotationName.append(parseIdentifier());
- while (maybeEat(".")) {
- annotationName.append(parseIdentifier());
- }
- TypeX type = TypeX.forName(annotationName.toString());
- p = new ExactAnnotationTypePattern(type);
- } else {
- String formal = parseIdentifier();
- p = new ExactAnnotationTypePattern(formal); // will get replaced when bindings resolved
- }
- int endPos = tokenSource.peek(-1).getEnd();
- p.setLocation(sourceContext,startPos,endPos);
return p;
}
private TypePattern parseNotOrTypePattern() {
- AnnotationTypePattern ap = null;
- TypePattern tp = null;
- PatternNode p = parseAtomicPattern();
- if (isAnnotationPattern(p)) {
- ap = completeAnnotationPattern((AnnotationTypePattern)p);
- IToken tok = tokenSource.peek();
- PatternNode typepat = parseTypePattern();
- if (isAnnotationPattern(p)) {
- throw new ParserException("Duplicate annotation pattern",tok);
- } else {
- tp = (TypePattern) typepat;
- tp.setAnnotationTypePattern(ap);
- }
- } else {
- tp = (TypePattern) p;
- }
+ TypePattern p = parseAtomicTypePattern();
if (maybeEat("&&")) {
- tp = new AndTypePattern(tp, parseTypePattern());
+ p = new AndTypePattern(p, parseTypePattern());
}
- return tp;
+ return p;
}
private TypePattern parseAtomicTypePattern() {
@@ -599,35 +513,25 @@ public class PatternParser {
eat(")");
return p;
}
- int startPos = tokenSource.peek().getStart();
- TypePattern p = parseSingleTypePattern();
- int endPos = tokenSource.peek(-1).getEnd();
- p.setLocation(sourceContext, startPos, endPos);
- return p;
- }
-
- private PatternNode parseAtomicPattern() {
- if (maybeEat("!")) {
- PatternNode p = parseAtomicPattern();
- if (isAnnotationPattern(p)) {
- return new NotAnnotationTypePattern((AnnotationTypePattern)p);
+ if (maybeEat("@")) {
+ AnnotationTypePattern ap = null;
+ if (maybeEat("(")) {
+ ap = parseAnnotationTypePattern();
+ eat(")");
} else {
- return new NotTypePattern((TypePattern)p);
- }
- }
- if (maybeEat("(")) {
- TypePattern p = parseTypePattern();
- eat(")");
- return p;
- }
- if (maybeEat(AT)) {
- StringBuffer annotationName = new StringBuffer();
- annotationName.append(parseIdentifier());
- while (maybeEat(".")) {
- annotationName.append(parseIdentifier());
+ ap = parseSimpleAnnotationName();
}
- TypeX type = TypeX.forName(annotationName.toString());
- return new ExactAnnotationTypePattern(type);
+ int startPos = tokenSource.peek().getStart();
+ TypePattern p = parseAtomicTypePattern();
+ int endPos = tokenSource.peek(-1).getEnd();
+ p.setLocation(sourceContext, startPos, endPos);
+ if (ap != null) {
+ if (p == TypePattern.ANY) {
+ p = new WildTypePattern(new NamePattern[] {NamePattern.ANY},false,0);
+ }
+ p.setAnnotationTypePattern(ap);
+ }
+ return p;
}
int startPos = tokenSource.peek().getStart();
TypePattern p = parseSingleTypePattern();
@@ -636,10 +540,6 @@ public class PatternParser {
return p;
}
- private boolean isAnnotationPattern(PatternNode p) {
- return (p instanceof AnnotationTypePattern);
- }
-
public TypePattern parseSingleTypePattern() {
List names = parseDottedNamePattern();
// new ArrayList();
@@ -668,6 +568,103 @@ public class PatternParser {
return new WildTypePattern(names, includeSubtypes, dim, endPos);
}
+
+
+ private AnnotationTypePattern completeAnnotationPattern(AnnotationTypePattern p) {
+ if (maybeEat("&&")) {
+ return new AndAnnotationTypePattern(p,parseNotOrAnnotationPattern());
+ }
+ if (maybeEat("||")) {
+ return new OrAnnotationTypePattern(p,parseAnnotationTypePattern());
+ }
+ return p;
+ }
+
+ protected AnnotationTypePattern parseAnnotationTypePattern() {
+ AnnotationTypePattern ap = parseAtomicAnnotationPattern();
+ if (maybeEat("&&")) {
+ ap = new AndAnnotationTypePattern(ap, parseNotOrAnnotationPattern());
+ }
+
+ if (maybeEat("||")) {
+ ap = new OrAnnotationTypePattern(ap, parseAnnotationTypePattern());
+ }
+ return ap;
+ }
+
+ private AnnotationTypePattern parseNotOrAnnotationPattern() {
+ AnnotationTypePattern p = parseAtomicAnnotationPattern();
+ if (maybeEat("&&")) {
+ p = new AndAnnotationTypePattern(p,parseAnnotationTypePattern());
+ }
+ return p;
+ }
+
+
+ protected AnnotationTypePattern parseAnnotationNameOrVarTypePattern() {
+ AnnotationTypePattern p = null;
+ int startPos = tokenSource.peek().getStart();
+ if (maybeEat(AT)) {
+ p = parseSimpleAnnotationName();
+ } else {
+ String formal = parseIdentifier();
+ p = new ExactAnnotationTypePattern(formal); // will get replaced when bindings resolved
+ }
+ int endPos = tokenSource.peek(-1).getEnd();
+ p.setLocation(sourceContext,startPos,endPos);
+ return p;
+ }
+
+
+ /**
+ * @return
+ */
+ private AnnotationTypePattern parseSimpleAnnotationName() {
+ // the @ has already been eaten...
+ AnnotationTypePattern p;
+ StringBuffer annotationName = new StringBuffer();
+ annotationName.append(parseIdentifier());
+ while (maybeEat(".")) {
+ annotationName.append('.');
+ annotationName.append(parseIdentifier());
+ }
+ TypeX type = TypeX.forName(annotationName.toString());
+ p = new ExactAnnotationTypePattern(type);
+ return p;
+ }
+
+ private AnnotationTypePattern parseAtomicAnnotationPattern() {
+ if (maybeEat("!")) {
+ //int startPos = tokenSource.peek(-1).getStart();
+ //??? we lose source location for true start of !type
+ AnnotationTypePattern p = new NotAnnotationTypePattern(parseAtomicAnnotationPattern());
+ return p;
+ }
+ if (maybeEat("(")) {
+ AnnotationTypePattern p = parseAnnotationTypePattern();
+ eat(")");
+ return p;
+ }
+ int startPos = tokenSource.peek().getStart();
+ eat("@");
+ StringBuffer annotationName = new StringBuffer();
+ annotationName.append(parseIdentifier());
+ while (maybeEat(".")) {
+ annotationName.append('.');
+ annotationName.append(parseIdentifier());
+ }
+ TypeX type = TypeX.forName(annotationName.toString());
+ AnnotationTypePattern p = new ExactAnnotationTypePattern(type);
+ int endPos = tokenSource.peek(-1).getEnd();
+ p.setLocation(sourceContext, startPos, endPos);
+ return p;
+ }
+
+
+ private boolean isAnnotationPattern(PatternNode p) {
+ return (p instanceof AnnotationTypePattern);
+ }
+
public List parseDottedNamePattern() {
List names = new ArrayList();
StringBuffer buf = new StringBuffer();
@@ -1073,7 +1070,14 @@ public class PatternParser {
public AnnotationTypePattern maybeParseAnnotationPattern() {
AnnotationTypePattern ret = null;
int start = tokenSource.getIndex();
- ret = parseAnnotationTypePattern(true);
+ if (maybeEat("@")) {
+ if (maybeEat("(")) {
+ ret = parseAnnotationTypePattern();
+ eat(")");
+ } else {
+ ret = parseSimpleAnnotationName();
+ }
+ }
if (ret == null) {
// failed to find one...
tokenSource.setIndex(start);
diff --git a/weaver/src/org/aspectj/weaver/patterns/SignaturePattern.java b/weaver/src/org/aspectj/weaver/patterns/SignaturePattern.java
index 3b8c0ec34..eda12bada 100644
--- a/weaver/src/org/aspectj/weaver/patterns/SignaturePattern.java
+++ b/weaver/src/org/aspectj/weaver/patterns/SignaturePattern.java
@@ -79,6 +79,9 @@ public class SignaturePattern extends PatternNode {
if (throwsPattern != null) {
throwsPattern = throwsPattern.resolveBindings(scope, bindings);
}
+ if (annotationPattern != null) {
+ annotationPattern = annotationPattern.resolveBindings(scope,bindings,false);
+ }
return this;
}
@@ -114,6 +117,11 @@ public class SignaturePattern extends PatternNode {
}
public boolean matches(Member member, World world) {
+ return (matchesIgnoringAnnotations(member,world) &&
+ annotationPattern.matches(member).alwaysTrue());
+ }
+
+ public boolean matchesIgnoringAnnotations(Member member, World world) {
//XXX performance gains would come from matching on name before resolving
// to fail fast. ASC 30th Nov 04 => Not necessarily, it didn't make it faster for me.
// Here is the code I used:
@@ -414,6 +422,12 @@ public class SignaturePattern extends PatternNode {
public String toString() {
StringBuffer buf = new StringBuffer();
+
+ if (annotationPattern != AnnotationTypePattern.ANY) {
+ buf.append(annotationPattern.toString());
+ buf.append(' ');
+ }
+
if (modifiers != ModifiersPattern.ANY) {
buf.append(modifiers.toString());
buf.append(' ');
@@ -455,7 +469,8 @@ public class SignaturePattern extends PatternNode {
&& o.returnType.equals(this.returnType)
&& o.declaringType.equals(this.declaringType)
&& o.name.equals(this.name)
- && o.parameterTypes.equals(this.parameterTypes);
+ && o.parameterTypes.equals(this.parameterTypes)
+ && o.annotationPattern.equals(this.annotationPattern);
}
public int hashCode() {
int result = 17;
@@ -465,6 +480,7 @@ public class SignaturePattern extends PatternNode {
result = 37*result + declaringType.hashCode();
result = 37*result + name.hashCode();
result = 37*result + parameterTypes.hashCode();
+ result = 37*result + annotationPattern.hashCode();
return result;
}
diff --git a/weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java
index e9b1b4536..09bf402ea 100644
--- a/weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java
+++ b/weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java
@@ -500,6 +500,10 @@ public class WildTypePattern extends TypePattern {
public String toString() {
StringBuffer buf = new StringBuffer();
+ if (annotationPattern != AnnotationTypePattern.ANY) {
+ buf.append(annotationPattern.toString());
+ buf.append(' ');
+ }
for (int i=0, len=namePatterns.length; i < len; i++) {
NamePattern name = namePatterns[i];
if (name == null) {
diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/AnnotationPatternTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/AnnotationPatternTestCase.java
new file mode 100644
index 000000000..73eab7c5c
--- /dev/null
+++ b/weaver/testsrc/org/aspectj/weaver/patterns/AnnotationPatternTestCase.java
@@ -0,0 +1,250 @@
+/* *******************************************************************
+ * Copyright (c) 2004 IBM Corporation.
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * ******************************************************************/
+package org.aspectj.weaver.patterns;
+
+import org.aspectj.weaver.AnnotatedElement;
+import org.aspectj.weaver.TypeX;
+
+import junit.framework.TestCase;
+
+public class AnnotationPatternTestCase extends TestCase {
+
+ public void testParseSimpleAnnotationPattern() {
+ PatternParser p = new PatternParser("@Foo");
+ AnnotationTypePattern foo = p.parseAnnotationTypePattern();
+ assertTrue("ExactAnnotationTypePattern",foo instanceof ExactAnnotationTypePattern);
+ assertEquals("Foo",TypeX.forName("Foo"),((ExactAnnotationTypePattern)foo).annotationType);
+ }
+
+ public void testParseAndAnnotationPattern() {
+ PatternParser p = new PatternParser("@Foo && @Goo");
+ AnnotationTypePattern fooAndGoo = p.parseAnnotationTypePattern();
+ assertTrue("AndAnnotationTypePattern",fooAndGoo instanceof AndAnnotationTypePattern);
+ assertEquals("(@Foo && @Goo)",fooAndGoo.toString());
+ AnnotationTypePattern left = ((AndAnnotationTypePattern)fooAndGoo).getLeft();
+ AnnotationTypePattern right = ((AndAnnotationTypePattern)fooAndGoo).getRight();
+ assertEquals("Foo",TypeX.forName("Foo"),((ExactAnnotationTypePattern)left).annotationType);
+ assertEquals("Goo",TypeX.forName("Goo"),((ExactAnnotationTypePattern)right).annotationType);
+ }
+
+ public void testParseOrAnnotationPattern() {
+ PatternParser p = new PatternParser("@Foo || @Goo");
+ AnnotationTypePattern fooOrGoo = p.parseAnnotationTypePattern();
+ assertTrue("OrAnnotationTypePattern",fooOrGoo instanceof OrAnnotationTypePattern);
+ assertEquals("(@Foo || @Goo)",fooOrGoo.toString());
+ AnnotationTypePattern left = ((OrAnnotationTypePattern)fooOrGoo).getLeft();
+ AnnotationTypePattern right = ((OrAnnotationTypePattern)fooOrGoo).getRight();
+ assertEquals("Foo",TypeX.forName("Foo"),((ExactAnnotationTypePattern)left).annotationType);
+ assertEquals("Goo",TypeX.forName("Goo"),((ExactAnnotationTypePattern)right).annotationType);
+ }
+
+ public void testParseNotAnnotationPattern() {
+ PatternParser p = new PatternParser("!@Foo");
+ AnnotationTypePattern notFoo = p.parseAnnotationTypePattern();
+ assertTrue("NotAnnotationTypePattern",notFoo instanceof NotAnnotationTypePattern);
+ assertEquals("(!@Foo)",notFoo.toString());
+ AnnotationTypePattern body = ((NotAnnotationTypePattern)notFoo).getNegatedPattern();
+ assertEquals("Foo",TypeX.forName("Foo"),((ExactAnnotationTypePattern)body).annotationType);
+ }
+
+ public void testParseBracketedAnnotationPattern() {
+ PatternParser p = new PatternParser("(@Foo)");
+ AnnotationTypePattern foo = p.parseAnnotationTypePattern();
+ assertTrue("ExactAnnotationTypePattern",foo instanceof ExactAnnotationTypePattern);
+ assertEquals("Foo",TypeX.forName("Foo"),((ExactAnnotationTypePattern)foo).annotationType);
+ }
+
+ public void testParseFQAnnPattern() {
+ PatternParser p = new PatternParser("@org.aspectj.Foo");
+ AnnotationTypePattern foo = p.parseAnnotationTypePattern();
+ assertTrue("ExactAnnotationTypePattern",foo instanceof ExactAnnotationTypePattern);
+ assertEquals("org.aspectj.Foo",TypeX.forName("org.aspectj.Foo"),((ExactAnnotationTypePattern)foo).annotationType);
+ }
+
+ public void testParseComboPattern() {
+ PatternParser p = new PatternParser("!((@Foo || @Goo) && !@Boo)");
+ AnnotationTypePattern ap = p.parseAnnotationTypePattern();
+ NotAnnotationTypePattern ntp = (NotAnnotationTypePattern) ap;
+ AndAnnotationTypePattern atp = (AndAnnotationTypePattern) ntp.getNegatedPattern();
+ NotAnnotationTypePattern notBoo = (NotAnnotationTypePattern) atp.getRight();
+ ExactAnnotationTypePattern boo = (ExactAnnotationTypePattern) notBoo.getNegatedPattern();
+ OrAnnotationTypePattern fooOrGoo = (OrAnnotationTypePattern) atp.getLeft();
+ ExactAnnotationTypePattern foo = (ExactAnnotationTypePattern) fooOrGoo.getLeft();
+ ExactAnnotationTypePattern goo = (ExactAnnotationTypePattern) fooOrGoo.getRight();
+ assertEquals("(!((@Foo || @Goo) && (!@Boo)))",ap.toString());
+ }
+
+ public void testParseAndOrPattern() {
+ PatternParser p = new PatternParser("@Foo && @Boo || @Goo");
+ AnnotationTypePattern andOr = p.parseAnnotationTypePattern();
+ assertTrue("Should be or pattern",andOr instanceof OrAnnotationTypePattern);
+ }
+
+ public void testParseBadPattern() {
+ PatternParser p = new PatternParser("@@Foo");
+ try {
+ AnnotationTypePattern bad = p.parseAnnotationTypePattern();
+ fail("ParserException expected");
+ } catch(ParserException pEx) {
+ assertEquals("identifier",pEx.getMessage());
+ }
+ }
+
+ public void testParseBadPattern2() {
+ PatternParser p = new PatternParser("Foo");
+ try {
+ AnnotationTypePattern bad = p.parseAnnotationTypePattern();
+ fail("ParserException expected");
+ } catch(ParserException pEx) {
+ assertEquals("@",pEx.getMessage());
+ }
+ }
+ public void testParseNameOrVarAnnotationPattern() {
+ PatternParser p = new PatternParser("@Foo");
+ AnnotationTypePattern foo = p.parseAnnotationNameOrVarTypePattern();
+ assertTrue("ExactAnnotationTypePattern",foo instanceof ExactAnnotationTypePattern);
+ assertEquals("Foo",TypeX.forName("Foo"),((ExactAnnotationTypePattern)foo).annotationType);
+ }
+
+ public void testParseNameOrVarAnnotationPatternWithNot() {
+ PatternParser p = new PatternParser("!@Foo");
+ try {
+ AnnotationTypePattern bad = p.parseAnnotationNameOrVarTypePattern();
+ fail("ParserException expected");
+ } catch(ParserException pEx) {
+ assertEquals("identifier",pEx.getMessage());
+ }
+ }
+
+ public void testParseNameOrVarAnnotationPatternWithOr() {
+ PatternParser p = new PatternParser("@Foo || @Boo");
+ AnnotationTypePattern foo = p.parseAnnotationNameOrVarTypePattern();
+ // rest of pattern not consumed...
+ assertTrue("ExactAnnotationTypePattern",foo instanceof ExactAnnotationTypePattern);
+ assertEquals("Foo",TypeX.forName("Foo"),((ExactAnnotationTypePattern)foo).annotationType);
+ }
+
+ public void testParseNameOrVarAnnotationWithBinding() {
+ PatternParser p = new PatternParser("foo");
+ AnnotationTypePattern foo = p.parseAnnotationNameOrVarTypePattern();
+ assertTrue("ExactAnnotationTypePattern",foo instanceof ExactAnnotationTypePattern);
+ assertNull("no type pattern yet",((ExactAnnotationTypePattern)foo).annotationType);
+ assertEquals("foo",((ExactAnnotationTypePattern)foo).formalName);
+ }
+
+ public void testParseNameOrVarAnnotationPatternWithAnd() {
+ PatternParser p = new PatternParser("@Foo && @Boo");
+ AnnotationTypePattern foo = p.parseAnnotationNameOrVarTypePattern();
+ // rest of pattern not consumed...
+ assertTrue("ExactAnnotationTypePattern",foo instanceof ExactAnnotationTypePattern);
+ assertEquals("Foo",TypeX.forName("Foo"),((ExactAnnotationTypePattern)foo).annotationType);
+ }
+
+ public void testMaybeParseAnnotationPattern() {
+ PatternParser p = new PatternParser("@Foo && @Boo");
+ AnnotationTypePattern a = p.maybeParseAnnotationPattern();
+ assertNotNull("Should find annotation pattern",a);
+ p = new PatternParser("Foo && Boo");
+ a = p.maybeParseAnnotationPattern();
+ assertEquals("Should be ANY pattern for a non-match",AnnotationTypePattern.ANY,a);
+ }
+
+ public void testParseTypePatternsWithAnnotations() {
+ PatternParser p = new PatternParser("@Foo *");
+ TypePattern t = p.parseTypePattern();
+ assertTrue("WildTypePattern",t instanceof WildTypePattern);
+ ExactAnnotationTypePattern etp = (ExactAnnotationTypePattern) t.annotationPattern;
+ assertEquals("@Foo",etp.toString());
+ assertEquals("@Foo *",t.toString());
+ }
+
+ public void testParseTypePatternsWithAnnotationsComplex() {
+ PatternParser p = new PatternParser("(@(@Foo || @Boo) (Foo || Boo))");
+ TypePattern t = p.parseTypePattern();
+ assertTrue("OrTypePattern",t instanceof OrTypePattern);
+ OrAnnotationTypePattern etp = (OrAnnotationTypePattern) t.annotationPattern;
+ assertEquals("(@Foo || @Boo)",etp.toString());
+ assertEquals("(@(@Foo || @Boo) (Foo || Boo))",t.toString());
+ }
+
+ public void testRidiculousNotSyntax() {
+ PatternParser p = new PatternParser("(@(!@Foo) (Foo || Boo))");
+ TypePattern t = p.parseTypePattern();
+ assertTrue("OrTypePattern",t instanceof OrTypePattern);
+ NotAnnotationTypePattern natp = (NotAnnotationTypePattern) t.annotationPattern;
+ assertEquals("(!@Foo)",natp.toString());
+ assertEquals("(@(!@Foo) (Foo || Boo))",t.toString());
+ }
+
+ public void testParseMethodOrConstructorSigNoAP() {
+
+ }
+
+ public void testParseMethodOrConstructorSigSimpleAP() {
+
+ }
+
+ public void testParseMethodOrConstructorSigComplexAP() {
+
+ }
+
+ public void testParseMethodFieldSigNoAP() {
+
+ }
+
+ public void testParseFieldSigSimpleAP() {
+
+ }
+
+ public void testParseFieldSigComplexAP() {
+
+ }
+
+ public void testExactAnnotationPatternMatching() {
+ // matching, non-matching
+ }
+
+ public void testBindingAnnotationPatternMatching() {
+ // matching, non-matching
+ }
+
+ public void testAndAnnotationPatternMatching() {
+
+ }
+
+ public void testOrAnnotationPatternMatching() {
+
+ }
+
+ public void testNotAnnotationPatternMatching() {
+
+ }
+
+ public void testAnyAnnotationPatternMatching() {
+
+ }
+
+ // put test cases for AnnotationPatternList matching in separate test class...
+
+ static class AnnotatedElementImpl implements AnnotatedElement {
+
+ private boolean answer;
+
+ public static final AnnotatedElementImpl YES = new AnnotatedElementImpl(true);
+ public static final AnnotatedElementImpl NO = new AnnotatedElementImpl(false);
+
+ public AnnotatedElementImpl(boolean answer) { this.answer = answer; }
+
+ public boolean hasAnnotation(TypeX ofType) {
+ return answer;
+ }
+
+ }
+}
diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/KindedAnnotationPointcutTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/KindedAnnotationPointcutTestCase.java
deleted file mode 100644
index 954746d47..000000000
--- a/weaver/testsrc/org/aspectj/weaver/patterns/KindedAnnotationPointcutTestCase.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/* *******************************************************************
- * Copyright (c) 2004 IBM Corporation.
- * All rights reserved.
- * This program and the accompanying materials are made available
- * under the terms of the Common Public License v1.0
- * which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- *
- * ******************************************************************/
-package org.aspectj.weaver.patterns;
-
-import junit.framework.TestCase;
-
-/**
- * @author colyer
- *
- * TODO To change the template for this generated type comment go to
- * Window - Preferences - Java - Code Style - Code Templates
- */
-public class KindedAnnotationPointcutTestCase extends TestCase {
-
- public void testParsing() {
- PatternParser p = new PatternParser("@call(@String)");
- Pointcut pc = p.parsePointcut();
- assertTrue(pc instanceof KindedAnnotationPointcut);
- }
-}
diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/PatternsTests.java b/weaver/testsrc/org/aspectj/weaver/patterns/PatternsTests.java
index c9f986d07..5ed4c21c0 100644
--- a/weaver/testsrc/org/aspectj/weaver/patterns/PatternsTests.java
+++ b/weaver/testsrc/org/aspectj/weaver/patterns/PatternsTests.java
@@ -37,10 +37,12 @@ public class PatternsTests extends TestCase {
suite.addTestSuite(HandlerTestCase.class);
suite.addTestSuite(KindedTestCase.class);
suite.addTestSuite(WithinCodeTestCase.class);
+ suite.addTestSuite(AnnotationPatternTestCase.class);
//$JUnit-END$
return suite;
}
public PatternsTests(String name) { super(name); }
+
}