]> source.dussan.org Git - aspectj.git/commitdiff
updates to annotation parsing...
authoracolyer <acolyer>
Wed, 8 Dec 2004 10:00:01 +0000 (10:00 +0000)
committeracolyer <acolyer>
Wed, 8 Dec 2004 10:00:01 +0000 (10:00 +0000)
weaver/src/org/aspectj/weaver/AnnotatedElement.java
weaver/src/org/aspectj/weaver/Member.java
weaver/src/org/aspectj/weaver/TypeX.java
weaver/src/org/aspectj/weaver/patterns/AnnotationTypePattern.java
weaver/src/org/aspectj/weaver/patterns/ExactAnnotationTypePattern.java
weaver/src/org/aspectj/weaver/patterns/PatternParser.java
weaver/src/org/aspectj/weaver/patterns/WildAnnotationTypePattern.java [new file with mode: 0644]
weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java
weaver/testsrc/org/aspectj/weaver/patterns/AnnotationPatternTestCase.java

index e2a6c7de48a20f540126aa8eedf7a26b344717ae..f83e551d0c41bdd16c9ded139269699d9e6d8073 100644 (file)
@@ -15,5 +15,6 @@ package org.aspectj.weaver;
 public interface AnnotatedElement {
        boolean hasAnnotation(ResolvedTypeX ofType);
        
+       ResolvedTypeX[] getAnnotationTypes();
        // SomeType getAnnotation(TypeX ofType);
 }
index d6b63e275d5dd7debe072a5c408cd97f3a9997db..9bd4fa7d4b078fb83db80dcf0cd767239b509ffe 100644 (file)
@@ -471,6 +471,13 @@ public class Member implements Comparable, AnnotatedElement {
        public boolean hasAnnotation(ResolvedTypeX ofType) {
                throw new UnsupportedOperationException("You should resolve this member and call hasAnnotation() on the result...");
        }
+       
+       /* (non-Javadoc)
+        * @see org.aspectj.weaver.AnnotatedElement#getAnnotationTypes()
+        */
+       public ResolvedTypeX[] getAnnotationTypes() {
+               throw new UnsupportedOperationException("You should resolve this member and call hasAnnotation() on the result...");
+       }
 
        // ---- fields 'n' stuff
 
index a10561c48093f60ef82132f800922b8277432460..020682322bb0e7eca02e95372ed45daf77c6d1f5 100644 (file)
@@ -555,6 +555,13 @@ public class TypeX implements AnnotatedElement {
        public boolean hasAnnotation(ResolvedTypeX ofType) {
                throw new UnsupportedOperationException("You should resolve this member and call hasAnnotation() on the result...");
        }
+
+       /* (non-Javadoc)
+        * @see org.aspectj.weaver.AnnotatedElement#getAnnotationTypes()
+        */
+       public ResolvedTypeX[] getAnnotationTypes() {
+               throw new UnsupportedOperationException("You should resolve this member and call hasAnnotation() on the result...");
+       }
        
     // ---- fields
 
index 5b2560cbefe56640fc6d2f8bcc5682f6c09ac759..ad8eab5c8e942313f321aeffc4a5b300f75b0580 100644 (file)
@@ -55,6 +55,7 @@ public abstract class AnnotationTypePattern extends PatternNode {
        public static final byte AND = 5;
        public static final byte ELLIPSIS_KEY = 6;
        public static final byte ANY_KEY = 7;
+       public static final byte WILD = 8;
 
        public static AnnotationTypePattern read(DataInputStream s, ISourceContext context) throws IOException {
                byte key = s.readByte();
@@ -64,6 +65,7 @@ public abstract class AnnotationTypePattern extends PatternNode {
                        case NOT: return NotAnnotationTypePattern.read(s, context);
                        case OR: return OrAnnotationTypePattern.read(s, context);
                        case AND: return AndAnnotationTypePattern.read(s, context);
+                       case WILD: return WildAnnotationTypePattern.read(s,context);
                        case ELLIPSIS_KEY: return ELLIPSIS;
                        case ANY_KEY: return ANY;
                }
index 0539d6af19282cb5c3e104e0f79a527079fee6c4..8d7bc8d5a28a25456623f9d2cf05b1704663a53d 100644 (file)
@@ -38,7 +38,7 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern {
         */
        public ExactAnnotationTypePattern(TypeX annotationType) {
                this.annotationType = annotationType;
-               this.resolved = false;
+               this.resolved = (annotationType instanceof ResolvedTypeX);
        }
 
        public ExactAnnotationTypePattern(String formalName) {
index 08ff3a1df8b8946082be2561eca9263efb904782..a91a44b6f49afecfabaad8284ea27e6f6042df34 100644 (file)
@@ -23,11 +23,8 @@ import org.aspectj.weaver.TypeX;
 
 //XXX doesn't handle errors for extra tokens very well (sometimes ignores)
 public class PatternParser {
-       
-       private static final String AT = "@";
-       
-       private ITokenSource tokenSource;
-       
+               
+       private ITokenSource tokenSource;       
        private ISourceContext sourceContext;
 
        /**
@@ -189,7 +186,7 @@ public class PatternParser {
                        eat(")");
                        return p;
                }
-               if (maybeEat(AT)) {
+               if (maybeEat("@")) {
                        int startPos = tokenSource.peek().getStart();
                        Pointcut p = parseAnnotationPointcut();
                    int endPos = tokenSource.peek(-1).getEnd();
@@ -502,6 +499,7 @@ public class PatternParser {
        }
        
        private TypePattern parseAtomicTypePattern() {
+               AnnotationTypePattern ap = maybeParseAnnotationPattern();
                if (maybeEat("!")) {
                        //int startPos = tokenSource.peek(-1).getStart();
                        //??? we lose source location for true start of !type
@@ -513,33 +511,82 @@ public class PatternParser {
                        eat(")");
                        return p;
                }
-               if (maybeEat("@")) {
-                       AnnotationTypePattern ap = null;
-                       if (maybeEat("(")) {
-                               ap = parseAnnotationTypePattern();
-                               eat(")");
-                       } else {
-                               ap = parseSimpleAnnotationName();
-                       }
-                       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;
-               }
+//             if (maybeEat("@")) {
+//                     AnnotationTypePattern ap = null;
+//                     if (maybeEat("(")) {
+//                             ap = parseAnnotationTypePattern();
+//                             eat(")");
+//                     } else {
+//                             ap = parseSimpleAnnotationName();
+//                     }
+//                     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();
            int endPos = tokenSource.peek(-1).getEnd();
            p.setLocation(sourceContext, startPos, endPos);
            return p;
        }
+       
+       public AnnotationTypePattern maybeParseAnnotationPattern() {
+               AnnotationTypePattern ret = AnnotationTypePattern.ANY;
+               AnnotationTypePattern nextPattern = null;
+               while ((nextPattern = maybeParseSingleAnnotationPattern()) != null) {
+                       if (ret == AnnotationTypePattern.ANY) {
+                               ret = nextPattern;
+                       } else {
+                               ret = new AndAnnotationTypePattern(ret,nextPattern);
+                       }
+               }
+               return ret;
+       }
 
+       public AnnotationTypePattern maybeParseSingleAnnotationPattern() {
+               AnnotationTypePattern ret = null;
+               // LALR(2) - fix by making "!@" a single token
+               int startIndex = tokenSource.getIndex();
+               if (maybeEat("!")) {
+                       if (maybeEat("@")) {
+                               if (maybeEat("(")) {
+                                       TypePattern p = parseTypePattern();
+                                       ret = new NotAnnotationTypePattern(new WildAnnotationTypePattern(p));
+                                       return ret;
+                               } else {
+                                       TypePattern p = parseSingleTypePattern();
+                                       ret = new NotAnnotationTypePattern(new WildAnnotationTypePattern(p));
+                                       return ret;
+                               }
+                       } else {
+                               tokenSource.setIndex(startIndex); // not for us!
+                               return ret;
+                       }
+               }
+               if (maybeEat("@")) {
+                       if (maybeEat("(")) {
+                               TypePattern p = parseTypePattern();
+                               ret = new WildAnnotationTypePattern(p);
+                               return ret;
+                       } else {
+                               TypePattern p = parseSingleTypePattern();
+                               ret = new WildAnnotationTypePattern(p);
+                               return ret;
+                       }
+               } else {
+                       tokenSource.setIndex(startIndex); // not for us!
+                       return ret;
+               }               
+       }
+       
        public TypePattern parseSingleTypePattern() {
                List names = parseDottedNamePattern(); 
 //             new ArrayList();
@@ -557,15 +604,15 @@ public class PatternParser {
                        eat("]");
                        dim++;
                }
-                       
-               
+               boolean isVarArgs = maybeEat("...");
+                                       
                boolean includeSubtypes = maybeEat("+");
                int endPos = tokenSource.peek(-1).getEnd();
                
                //??? what about the source location of any's????
                if (names.size() == 1 && ((NamePattern)names.get(0)).isAny() && dim == 0) return TypePattern.ANY;
                
-               return new WildTypePattern(names, includeSubtypes, dim, endPos);
+               return new WildTypePattern(names, includeSubtypes, dim, endPos,isVarArgs);
        }
        
 
@@ -604,7 +651,7 @@ public class PatternParser {
        protected AnnotationTypePattern parseAnnotationNameOrVarTypePattern() {
                AnnotationTypePattern p = null;
                int startPos = tokenSource.peek().getStart();
-               if (maybeEat(AT)) {
+               if (maybeEat("@")) {
                        p = parseSimpleAnnotationName();
                } else {
                        String formal = parseIdentifier();
@@ -1066,26 +1113,7 @@ public class PatternParser {
                        return null;
                }
        }
-       
-       public AnnotationTypePattern maybeParseAnnotationPattern() {
-               AnnotationTypePattern ret = null;
-               int start = tokenSource.getIndex();
-               if (maybeEat("@")) {
-                       if (maybeEat("(")) {
-                               ret = parseAnnotationTypePattern();
-                               eat(")");
-                       } else {
-                               ret = parseSimpleAnnotationName();
-                       }
-               }
-               if (ret == null) {
-                       // failed to find one...
-                       tokenSource.setIndex(start);
-                       ret = AnnotationTypePattern.ANY;
-               }
-               return ret;
-       }
-       
+               
        public boolean peek(String token) {
                IToken next = tokenSource.peek();
                return next.getString() == token;
diff --git a/weaver/src/org/aspectj/weaver/patterns/WildAnnotationTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/WildAnnotationTypePattern.java
new file mode 100644 (file)
index 0000000..f76a4e6
--- /dev/null
@@ -0,0 +1,95 @@
+/* *******************************************************************
+ * 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 java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.util.FuzzyBoolean;
+import org.aspectj.weaver.AnnotatedElement;
+import org.aspectj.weaver.BCException;
+import org.aspectj.weaver.ISourceContext;
+import org.aspectj.weaver.ResolvedTypeX;
+import org.aspectj.weaver.TypeX;
+
+/**
+ * @author colyer
+ *
+ * TODO To change the template for this generated type comment go to
+ * Window - Preferences - Java - Code Style - Code Templates
+ */
+public class WildAnnotationTypePattern extends AnnotationTypePattern {
+
+       private TypePattern typePattern;
+       
+       /**
+        * 
+        */
+       public WildAnnotationTypePattern(TypePattern typePattern) {
+               super();
+               this.typePattern = typePattern;
+       }
+
+
+       /* (non-Javadoc)
+        * @see org.aspectj.weaver.patterns.AnnotationTypePattern#matches(org.aspectj.weaver.AnnotatedElement)
+        */
+       public FuzzyBoolean matches(AnnotatedElement annotated) {
+               // matches if the type of any of the annotations on the AnnotatedElement is
+               // matched by the typePattern.
+               ResolvedTypeX[] annTypes = annotated.getAnnotationTypes();
+               for (int i = 0; i < annTypes.length; i++) {
+                       if (typePattern.matches(annTypes[i],TypePattern.STATIC).alwaysTrue()) {
+                               return FuzzyBoolean.YES;
+                       }
+               }
+               return FuzzyBoolean.NO;
+       }
+
+       /**
+        * This can modify in place, or return a new TypePattern if the type changes.
+        */
+    public AnnotationTypePattern resolveBindings(IScope scope, Bindings bindings, 
+                                                                            boolean allowBinding)
+    { 
+       this.typePattern = typePattern.resolveBindings(scope,bindings,false,false);
+       if (typePattern instanceof ExactTypePattern) {
+               ExactTypePattern et = (ExactTypePattern)typePattern;
+               return new ExactAnnotationTypePattern(et.getExactType());
+       } else {
+               return this;
+       }
+    }
+
+       private static final byte VERSION = 1; // rev if ser. form changes
+       /* (non-Javadoc)
+        * @see org.aspectj.weaver.patterns.PatternNode#write(java.io.DataOutputStream)
+        */
+       public void write(DataOutputStream s) throws IOException {
+               s.writeByte(AnnotationTypePattern.WILD);
+               s.writeByte(VERSION);
+               typePattern.write(s);
+               writeLocation(s);
+       }
+
+       public static AnnotationTypePattern read(DataInputStream s,ISourceContext context) throws IOException {
+               AnnotationTypePattern ret;
+               byte version = s.readByte();
+               if (version > VERSION) {
+                       throw new BCException("ExactAnnotationTypePattern was written by a newer version of AspectJ");
+               }
+               TypePattern t = TypePattern.read(s,context);
+               ret = new WildAnnotationTypePattern(t);
+               ret.readLocation(context,s);
+               return ret;             
+       }
+       
+}
index 09bf402ea68484c728de174f152f017dc16a6559..2cef3745c9c7f15191d12cdc4fdbabfb694b66cf 100644 (file)
@@ -38,8 +38,8 @@ public class WildTypePattern extends TypePattern {
        String[] knownMatches;
        int dim;
 
-       WildTypePattern(NamePattern[] namePatterns, boolean includeSubtypes, int dim) {
-               super(includeSubtypes,false);
+       WildTypePattern(NamePattern[] namePatterns, boolean includeSubtypes, int dim, boolean isVarArgs) {
+               super(includeSubtypes,isVarArgs);
                this.namePatterns = namePatterns;
                this.dim = dim;
                ellipsisCount = 0;
@@ -50,7 +50,7 @@ public class WildTypePattern extends TypePattern {
        }
 
        public WildTypePattern(List names, boolean includeSubtypes, int dim) {
-               this((NamePattern[])names.toArray(new NamePattern[names.size()]), includeSubtypes, dim);
+               this((NamePattern[])names.toArray(new NamePattern[names.size()]), includeSubtypes, dim,false);
 
        }
        
@@ -58,7 +58,13 @@ public class WildTypePattern extends TypePattern {
                this(names, includeSubtypes, dim);
                this.end = endPos;
        }
-       
+
+       public WildTypePattern(List names, boolean includeSubtypes, int dim, int endPos, boolean isVarArg) {
+               this(names, includeSubtypes, dim);
+               this.end = endPos;
+               this.isVarArgs = isVarArg;
+       }
+
        //XXX inefficient implementation
        public static char[][] splitNames(String s) {
                List ret = new ArrayList();
@@ -559,6 +565,7 @@ public class WildTypePattern extends TypePattern {
                }
                s.writeBoolean(includeSubtypes);
                s.writeInt(dim);
+               s.writeBoolean(isVarArgs);
                //??? storing this information with every type pattern is wasteful of .class
                //    file size. Storing it on enclosing types would be more efficient
                FileUtil.writeStringArray(knownMatches, s);
@@ -579,7 +586,8 @@ public class WildTypePattern extends TypePattern {
                }
                boolean includeSubtypes = s.readBoolean();
                int dim = s.readInt();
-               WildTypePattern ret = new WildTypePattern(namePatterns, includeSubtypes, dim);
+               boolean varArg = s.readBoolean();
+               WildTypePattern ret = new WildTypePattern(namePatterns, includeSubtypes, dim,varArg);
                ret.knownMatches = FileUtil.readStringArray(s);
                ret.importedPrefixes = FileUtil.readStringArray(s);
                ret.readLocation(context, s);
index 489d2455000f78b0f3b3b7f253c3d8f7e2e8fe01..0ddbc34e2eda93f21bf000c06baea5b1c050a020 100644 (file)
@@ -10,8 +10,8 @@
 package org.aspectj.weaver.patterns;
 
 import org.aspectj.weaver.AnnotatedElement;
-import org.aspectj.weaver.BcweaverTests;
 import org.aspectj.weaver.ResolvedTypeX;
+import org.aspectj.weaver.BcweaverTests;
 import org.aspectj.weaver.TypeX;
 import org.aspectj.weaver.bcel.BcelWorld;
 
@@ -336,5 +336,13 @@ public class AnnotationPatternTestCase extends TestCase {
                        return false;
                }
                
+               /* (non-Javadoc)
+                * @see org.aspectj.weaver.AnnotatedElement#getAnnotationTypes()
+                */
+               public ResolvedTypeX[] getAnnotationTypes() {
+                       // TODO Auto-generated method stub
+                       return null;
+               }
+               
        }
 }