]> source.dussan.org Git - aspectj.git/commitdiff
annotation pattern and type pattern parsing and test cases
authoracolyer <acolyer>
Mon, 6 Dec 2004 22:36:58 +0000 (22:36 +0000)
committeracolyer <acolyer>
Mon, 6 Dec 2004 22:36:58 +0000 (22:36 +0000)
15 files changed:
weaver/src/org/aspectj/weaver/patterns/AndAnnotationTypePattern.java
weaver/src/org/aspectj/weaver/patterns/AndTypePattern.java
weaver/src/org/aspectj/weaver/patterns/BindingTypePattern.java
weaver/src/org/aspectj/weaver/patterns/ExactAnnotationTypePattern.java
weaver/src/org/aspectj/weaver/patterns/ExactTypePattern.java
weaver/src/org/aspectj/weaver/patterns/NotAnnotationTypePattern.java
weaver/src/org/aspectj/weaver/patterns/NotTypePattern.java
weaver/src/org/aspectj/weaver/patterns/OrAnnotationTypePattern.java
weaver/src/org/aspectj/weaver/patterns/OrTypePattern.java
weaver/src/org/aspectj/weaver/patterns/PatternParser.java
weaver/src/org/aspectj/weaver/patterns/SignaturePattern.java
weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java
weaver/testsrc/org/aspectj/weaver/patterns/AnnotationPatternTestCase.java [new file with mode: 0644]
weaver/testsrc/org/aspectj/weaver/patterns/KindedAnnotationPointcutTestCase.java [deleted file]
weaver/testsrc/org/aspectj/weaver/patterns/PatternsTests.java

index 3d4eb11e923421944d57bc5590f704391f9a37bf..c6679a98085b12858a31874409f8356f27ebf97b 100644 (file)
@@ -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; }
 
 }
index bb94f602da7cbd6721ae346f15280257bc27a453..0752746fcd8115fe5732e13ed075a3e46f73d1c7 100644 (file)
@@ -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();
        }
 
 }
index 937563c79f27b1adf503bef14b4d0137233f24be..e2633aa3f26c582e24d224a56e36bd6a27547a33 100644 (file)
@@ -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 + ")";
     }
 }
index 3db7d0030bf0b65438bab5119f4e2ff00c72d956..f60c67df3f315e5516eeb1804195a4f40be6c91c 100644 (file)
@@ -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;
        }
index 36917a2973af4678f98e64ef1c419e3b68821bb0..755e025e27204230e93a51be6d8a3c91162486d7 100644 (file)
@@ -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)
index e55df2508708731513b800adf18c7ce3f8af5546..d7869d90a56a32bd97b18b64ffdc89e6dd1b02e9 100644 (file)
@@ -69,6 +69,10 @@ public class NotAnnotationTypePattern extends AnnotationTypePattern {
        }
        
        public String toString() {
-               return "!" + negatedPattern.toString();
+               return "(!" + negatedPattern.toString() + ")";
+       }
+       
+       public AnnotationTypePattern getNegatedPattern() {
+               return negatedPattern;
        }
 }
index 17a402e9146b577ab3093bcca21b683c7d32290a..02adeadd8f711c51522609a61da0960d72f9a68b 100644 (file)
@@ -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();
        }
 }
index bd6414d39e76114784aec5d8050fdf0bcb617f30..0f23f6b2cbe859097c9ea21f14e2ea7b4b4e0edf 100644 (file)
@@ -74,4 +74,7 @@ public class OrAnnotationTypePattern extends AnnotationTypePattern {
                return "(" + left.toString() + " || " + right.toString() + ")";
        }
 
+       public AnnotationTypePattern getLeft() { return left; }
+       public AnnotationTypePattern getRight() { return right; }
+
 }
index 6a423e03c84c75d2f803437d070c1b261eb4ab0c..6d8689eb1da16993282c317d15b0f683457dc700 100644 (file)
@@ -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();
        }
-
 }
index 8a4324bf92127b3a441f9d4b017b7207fc653cca..08ff3a1df8b8946082be2561eca9263efb904782 100644 (file)
@@ -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);
index 3b8c0ec34a1a6516441dadfa3e07a0e1f0de0151..eda12badafca6eeaf02646e8c5ae88c5b8c32f36 100644 (file)
@@ -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;
     }
     
index e9b1b4536e250d41e296489b015aba978a34912e..09bf402ea68484c728de174f152f017dc16a6559 100644 (file)
@@ -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 (file)
index 0000000..73eab7c
--- /dev/null
@@ -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 (file)
index 954746d..0000000
+++ /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);
-       }
-}
index c9f986d071ef046411e763713ca4cc06adbf0153..5ed4c21c023087119e995eadbd0f5910520e1ef1 100644 (file)
@@ -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); }
 
+    
 }