From c951bf5943413f8cead4888053ca5f77bef0e0ca Mon Sep 17 00:00:00 2001 From: acolyer Date: Mon, 6 Dec 2004 22:36:58 +0000 Subject: [PATCH] annotation pattern and type pattern parsing and test cases --- .../patterns/AndAnnotationTypePattern.java | 3 + .../weaver/patterns/AndTypePattern.java | 19 +- .../weaver/patterns/BindingTypePattern.java | 2 +- .../patterns/ExactAnnotationTypePattern.java | 18 +- .../weaver/patterns/ExactTypePattern.java | 17 +- .../patterns/NotAnnotationTypePattern.java | 6 +- .../weaver/patterns/NotTypePattern.java | 16 +- .../patterns/OrAnnotationTypePattern.java | 3 + .../weaver/patterns/OrTypePattern.java | 20 +- .../weaver/patterns/PatternParser.java | 252 +++++++++--------- .../weaver/patterns/SignaturePattern.java | 18 +- .../weaver/patterns/WildTypePattern.java | 4 + .../patterns/AnnotationPatternTestCase.java | 250 +++++++++++++++++ .../KindedAnnotationPointcutTestCase.java | 27 -- .../weaver/patterns/PatternsTests.java | 2 + 15 files changed, 495 insertions(+), 162 deletions(-) create mode 100644 weaver/testsrc/org/aspectj/weaver/patterns/AnnotationPatternTestCase.java delete mode 100644 weaver/testsrc/org/aspectj/weaver/patterns/KindedAnnotationPointcutTestCase.java 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); } + } -- 2.39.5