]> source.dussan.org Git - aspectj.git/commitdiff
@annotation parsing and matching
authoracolyer <acolyer>
Wed, 8 Dec 2004 13:43:57 +0000 (13:43 +0000)
committeracolyer <acolyer>
Wed, 8 Dec 2004 13:43:57 +0000 (13:43 +0000)
weaver/src/org/aspectj/weaver/patterns/AnnotationPointcut.java [new file with mode: 0644]
weaver/src/org/aspectj/weaver/patterns/KindedAnnotationPointcut.java [deleted file]
weaver/src/org/aspectj/weaver/patterns/PatternParser.java
weaver/src/org/aspectj/weaver/patterns/Pointcut.java

diff --git a/weaver/src/org/aspectj/weaver/patterns/AnnotationPointcut.java b/weaver/src/org/aspectj/weaver/patterns/AnnotationPointcut.java
new file mode 100644 (file)
index 0000000..b6c549c
--- /dev/null
@@ -0,0 +1,199 @@
+/* *******************************************************************
+ * 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.bridge.ISourceLocation;
+import org.aspectj.bridge.Message;
+import org.aspectj.util.FuzzyBoolean;
+import org.aspectj.weaver.AnnotatedElement;
+import org.aspectj.weaver.ISourceContext;
+import org.aspectj.weaver.IntMap;
+import org.aspectj.weaver.Member;
+import org.aspectj.weaver.NameMangler;
+import org.aspectj.weaver.ResolvedMember;
+import org.aspectj.weaver.ResolvedTypeX;
+import org.aspectj.weaver.Shadow;
+import org.aspectj.weaver.ShadowMunger;
+import org.aspectj.weaver.TypeX;
+import org.aspectj.weaver.ast.Literal;
+import org.aspectj.weaver.ast.Test;
+import org.aspectj.weaver.ast.Var;
+
+/**
+ * @annotation(@Foo) or @annotation(foo)
+ * 
+ * Matches any join point where the subject of the join point has an
+ * annotation matching the annotationTypePattern:
+ * 
+ * Join Point Kind          Subject
+ * ================================
+ * method call              the target method
+ * method execution         the method
+ * constructor call         the constructor
+ * constructor execution    the constructor
+ * get                      the target field
+ * set                      the target field
+ * adviceexecution          the advice
+ * initialization           the constructor
+ * preinitialization        the constructor
+ * staticinitialization     the type being initialized
+ * handler                  the declared type of the handled exception
+ */
+public class AnnotationPointcut extends NameBindingPointcut {
+
+       private ExactAnnotationTypePattern annotationTypePattern;
+    private ShadowMunger munger = null; // only set after concretization
+       
+       public AnnotationPointcut(ExactAnnotationTypePattern type) {
+               super();
+               this.annotationTypePattern =  type;
+               this.pointcutKind = Pointcut.ANNOTATION;
+       }
+
+       public AnnotationPointcut(ExactAnnotationTypePattern type, ShadowMunger munger) {
+               this(type);
+               this.munger = munger;
+       }
+
+       /* (non-Javadoc)
+        * @see org.aspectj.weaver.patterns.Pointcut#fastMatch(org.aspectj.weaver.patterns.FastMatchInfo)
+        */
+       public FuzzyBoolean fastMatch(FastMatchInfo info) {
+               if (info.getKind() == Shadow.StaticInitialization) {
+                       return annotationTypePattern.matches(info.getType());
+               } else {
+                       return FuzzyBoolean.MAYBE;
+               }
+       }
+
+       /* (non-Javadoc)
+        * @see org.aspectj.weaver.patterns.Pointcut#match(org.aspectj.weaver.Shadow)
+        */
+       public FuzzyBoolean match(Shadow shadow) {
+               AnnotatedElement toMatchAgainst = null;
+               Member member = shadow.getSignature();
+               ResolvedMember rMember = member.resolve(shadow.getIWorld());
+
+               if (rMember == null) {
+                   if (member.getName().startsWith(NameMangler.PREFIX)) {
+                       return FuzzyBoolean.NO;
+                       }
+                       shadow.getIWorld().getLint().unresolvableMember.signal(member.toString(), getSourceLocation());
+                       return FuzzyBoolean.NO;
+               }
+
+               Shadow.Kind kind = shadow.getKind();
+               if (kind == Shadow.StaticInitialization) {
+                       toMatchAgainst = rMember.getType();
+               } else if ( (kind == Shadow.ExceptionHandler)) {
+                       toMatchAgainst = TypeX.forName(rMember.getSignature()).resolve(shadow.getIWorld());
+               } else {
+                       toMatchAgainst = rMember;
+               }
+               
+               return annotationTypePattern.matches(toMatchAgainst);
+       }
+       
+
+       /* (non-Javadoc)
+        * @see org.aspectj.weaver.patterns.Pointcut#resolveBindings(org.aspectj.weaver.patterns.IScope, org.aspectj.weaver.patterns.Bindings)
+        */
+       protected void resolveBindings(IScope scope, Bindings bindings) {
+               annotationTypePattern = (ExactAnnotationTypePattern) annotationTypePattern.resolveBindings(scope,bindings,true);
+               // must be either a Var, or an annotation type pattern
+       }
+
+       /* (non-Javadoc)
+        * @see org.aspectj.weaver.patterns.Pointcut#resolveBindingsFromRTTI()
+        */
+       protected void resolveBindingsFromRTTI() {
+               // TODO Auto-generated method stub
+
+       }
+
+       /* (non-Javadoc)
+        * @see org.aspectj.weaver.patterns.Pointcut#concretize1(org.aspectj.weaver.ResolvedTypeX, org.aspectj.weaver.IntMap)
+        */
+       protected Pointcut concretize1(ResolvedTypeX inAspect, IntMap bindings) {
+               ExactAnnotationTypePattern newType = (ExactAnnotationTypePattern) annotationTypePattern.remapAdviceFormals(bindings);           
+               Pointcut ret = new AnnotationPointcut(newType, bindings.getEnclosingAdvice());
+        ret.copyLocationFrom(this);
+        return ret;
+       }
+
+       /* (non-Javadoc)
+        * @see org.aspectj.weaver.patterns.Pointcut#findResidue(org.aspectj.weaver.Shadow, org.aspectj.weaver.patterns.ExposedState)
+        */
+       public Test findResidue(Shadow shadow, ExposedState state) {
+               
+               if (annotationTypePattern instanceof BindingAnnotationTypePattern) {
+                       BindingAnnotationTypePattern btp = (BindingAnnotationTypePattern)annotationTypePattern;
+                       TypeX annotationType = btp.annotationType;
+                       Var var = shadow.getKindedAnnotationVar(annotationType);
+                       if (var == null) return Literal.FALSE;
+                       // Check if we have already bound something to this formal
+                       if (state.get(btp.getFormalIndex())!=null) {
+                               ISourceLocation pcdSloc = getSourceLocation(); 
+                               ISourceLocation shadowSloc = shadow.getSourceLocation();
+                               Message errorMessage = new Message(
+                                       "Cannot use @pointcut to match at this location and bind a formal to type '"+var.getType()+
+                                       "' - the formal is already bound to type '"+state.get(btp.getFormalIndex()).getType()+"'"+
+                                       ".  The secondary source location points to the problematic binding.",
+                                       shadowSloc,true,new ISourceLocation[]{pcdSloc}); 
+                               shadow.getIWorld().getMessageHandler().handleMessage(errorMessage);
+                               state.setErroneousVar(btp.getFormalIndex());
+                       }
+                       state.set(btp.getFormalIndex(),var);
+               } 
+               return Literal.TRUE;
+       }
+
+       /* (non-Javadoc)
+        * @see org.aspectj.weaver.patterns.PatternNode#write(java.io.DataOutputStream)
+        */
+       public void write(DataOutputStream s) throws IOException {
+               s.writeByte(Pointcut.ANNOTATION);
+               annotationTypePattern.write(s);
+               writeLocation(s);
+       }
+
+       public static Pointcut read(DataInputStream s, ISourceContext context) throws IOException {
+               AnnotationTypePattern type = AnnotationTypePattern.read(s, context);
+               AnnotationPointcut ret = new AnnotationPointcut((ExactAnnotationTypePattern)type);
+               ret.readLocation(context, s);
+               return ret;
+       }
+
+       public boolean equals(Object other) {
+               if (!(other instanceof AnnotationPointcut)) return false;
+               AnnotationPointcut o = (AnnotationPointcut)other;
+               return o.annotationTypePattern.equals(this.annotationTypePattern);
+       }
+    
+    public int hashCode() {
+        int result = 17;
+        result = 37*result + annotationTypePattern.hashCode();
+        return result;
+    }
+       
+       public String toString() {
+               StringBuffer buf = new StringBuffer();
+               buf.append("@annotation(");
+               buf.append(annotationTypePattern.toString());
+               buf.append(")");
+               return buf.toString();
+       }
+
+}
diff --git a/weaver/src/org/aspectj/weaver/patterns/KindedAnnotationPointcut.java b/weaver/src/org/aspectj/weaver/patterns/KindedAnnotationPointcut.java
deleted file mode 100644 (file)
index 6dc0c55..0000000
+++ /dev/null
@@ -1,198 +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 java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-
-import org.aspectj.bridge.ISourceLocation;
-import org.aspectj.bridge.Message;
-import org.aspectj.util.FuzzyBoolean;
-import org.aspectj.weaver.ISourceContext;
-import org.aspectj.weaver.IntMap;
-import org.aspectj.weaver.Member;
-import org.aspectj.weaver.NameMangler;
-import org.aspectj.weaver.ResolvedMember;
-import org.aspectj.weaver.ResolvedTypeX;
-import org.aspectj.weaver.Shadow;
-import org.aspectj.weaver.ShadowMunger;
-import org.aspectj.weaver.TypeX;
-import org.aspectj.weaver.ast.Literal;
-import org.aspectj.weaver.ast.Test;
-import org.aspectj.weaver.ast.Var;
-
-/**
- * A KindedAnnotationPointcut matches iff the kind of a join point 
- * matches the kind of the pointcut (with no distinction between
- * method and constructor for call and execution), AND if the
- * member (field, method or constructor) has an annotation of the
- * given type.
- */
-public class KindedAnnotationPointcut extends NameBindingPointcut {
-
-       private Shadow.Kind kind;
-       private AnnotationTypePattern type;
-    private ShadowMunger munger = null; // only set after concretization
-       
-       public KindedAnnotationPointcut(Shadow.Kind kind, AnnotationTypePattern type) {
-               super();
-               this.kind = kind;
-               this.type = type;
-               this.pointcutKind = Pointcut.ATKINDED;
-       }
-
-       public KindedAnnotationPointcut(Shadow.Kind kind, AnnotationTypePattern type, ShadowMunger munger) {
-               this(kind,type);
-               this.munger = munger;
-       }
-
-       /* (non-Javadoc)
-        * @see org.aspectj.weaver.patterns.Pointcut#fastMatch(org.aspectj.weaver.patterns.FastMatchInfo)
-        */
-       public FuzzyBoolean fastMatch(FastMatchInfo info) {
-               if (info.getKind() != null) {
-                       if (info.getKind() != kind) {
-                               // no distinction between method and constructors
-                               if ((info.getKind() == Shadow.ConstructorExecution) &&
-                                        kind == Shadow.MethodExecution) {
-                                       return FuzzyBoolean.MAYBE;
-                               } 
-                               if ((info.getKind() == Shadow.ConstructorCall) &&
-                                                kind == Shadow.MethodCall) {
-                                               return FuzzyBoolean.MAYBE;
-                               }                               
-                       } else {
-                               return FuzzyBoolean.NO;
-                       }
-       }
-               return FuzzyBoolean.MAYBE;
-       }
-
-       /* (non-Javadoc)
-        * @see org.aspectj.weaver.patterns.Pointcut#match(org.aspectj.weaver.Shadow)
-        */
-       public FuzzyBoolean match(Shadow shadow) {
-               if (!couldMatch(shadow)) return FuzzyBoolean.NO;
-               Member member = shadow.getSignature();
-               ResolvedMember rMember = member.resolve(shadow.getIWorld());
-               if (rMember == null) {
-                   if (member.getName().startsWith(NameMangler.PREFIX)) {
-                       return FuzzyBoolean.NO;
-                       }
-                       shadow.getIWorld().getLint().unresolvableMember.signal(member.toString(), getSourceLocation());
-                       return FuzzyBoolean.NO;
-               }
-               return type.matches(rMember);
-       }
-       
-       private boolean couldMatch(Shadow shadow) {
-               Shadow.Kind kindToMatch = shadow.getKind();
-               if (kindToMatch == Shadow.ConstructorExecution) kindToMatch = Shadow.MethodExecution;
-               if (kindToMatch == Shadow.ConstructorCall) kindToMatch = Shadow.MethodCall;
-               return (kindToMatch == kind);           
-       }
-
-       /* (non-Javadoc)
-        * @see org.aspectj.weaver.patterns.Pointcut#resolveBindings(org.aspectj.weaver.patterns.IScope, org.aspectj.weaver.patterns.Bindings)
-        */
-       protected void resolveBindings(IScope scope, Bindings bindings) {
-               type = type.resolveBindings(scope,bindings,true);
-               // must be either a Var, or an annotation type pattern
-       }
-
-       /* (non-Javadoc)
-        * @see org.aspectj.weaver.patterns.Pointcut#resolveBindingsFromRTTI()
-        */
-       protected void resolveBindingsFromRTTI() {
-               // TODO Auto-generated method stub
-
-       }
-
-       /* (non-Javadoc)
-        * @see org.aspectj.weaver.patterns.Pointcut#concretize1(org.aspectj.weaver.ResolvedTypeX, org.aspectj.weaver.IntMap)
-        */
-       protected Pointcut concretize1(ResolvedTypeX inAspect, IntMap bindings) {
-               AnnotationTypePattern newType = type.remapAdviceFormals(bindings);              
-               Pointcut ret = new KindedAnnotationPointcut(kind, newType, bindings.getEnclosingAdvice());
-        ret.copyLocationFrom(this);
-        return ret;
-       }
-
-       /* (non-Javadoc)
-        * @see org.aspectj.weaver.patterns.Pointcut#findResidue(org.aspectj.weaver.Shadow, org.aspectj.weaver.patterns.ExposedState)
-        */
-       public Test findResidue(Shadow shadow, ExposedState state) {
-               if (!couldMatch(shadow)) return Literal.FALSE;
-               
-               if (type instanceof BindingAnnotationTypePattern) {
-                       BindingAnnotationTypePattern btp = (BindingAnnotationTypePattern)type;
-                       TypeX annotationType = btp.annotationType;
-                       Var var = shadow.getKindedAnnotationVar(annotationType);
-                       if (var == null) return Literal.FALSE;
-                       // Check if we have already bound something to this formal
-                       if (state.get(btp.getFormalIndex())!=null) {
-                               ISourceLocation pcdSloc = getSourceLocation(); 
-                               ISourceLocation shadowSloc = shadow.getSourceLocation();
-                               Message errorMessage = new Message(
-                                       "Cannot use @pointcut to match at this location and bind a formal to type '"+var.getType()+
-                                       "' - the formal is already bound to type '"+state.get(btp.getFormalIndex()).getType()+"'"+
-                                       ".  The secondary source location points to the problematic binding.",
-                                       shadowSloc,true,new ISourceLocation[]{pcdSloc}); 
-                               shadow.getIWorld().getMessageHandler().handleMessage(errorMessage);
-                               state.setErroneousVar(btp.getFormalIndex());
-                       }
-                       state.set(btp.getFormalIndex(),var);
-               } 
-               return Literal.TRUE;
-       }
-
-       /* (non-Javadoc)
-        * @see org.aspectj.weaver.patterns.PatternNode#write(java.io.DataOutputStream)
-        */
-       public void write(DataOutputStream s) throws IOException {
-               s.writeByte(Pointcut.ATKINDED);
-               kind.write(s);
-               type.write(s);
-               writeLocation(s);
-       }
-
-       public static Pointcut read(DataInputStream s, ISourceContext context) throws IOException {
-               Shadow.Kind kind = Shadow.Kind.read(s);
-               AnnotationTypePattern type = AnnotationTypePattern.read(s, context);
-               KindedAnnotationPointcut ret = new KindedAnnotationPointcut(kind, type);
-               ret.readLocation(context, s);
-               return ret;
-       }
-
-       public boolean equals(Object other) {
-               if (!(other instanceof KindedAnnotationPointcut)) return false;
-               KindedAnnotationPointcut o = (KindedAnnotationPointcut)other;
-               return o.kind == this.kind && o.type.equals(this.type);
-       }
-    
-    public int hashCode() {
-        int result = 17;
-        result = 37*result + kind.hashCode();
-        result = 37*result + type.hashCode();
-        return result;
-    }
-       
-       public String toString() {
-               StringBuffer buf = new StringBuffer();
-               buf.append(kind.getSimpleName());
-               buf.append("(");
-               buf.append(type.toString());
-               buf.append(")");
-               return buf.toString();
-       }
-
-}
index 0cb850d3e809568f6d48b42789d51e65dc7f872b..fd1ab22e32a29e07d143ee79147f55a42fdf2aae 100644 (file)
@@ -270,13 +270,8 @@ public class PatternParser {
                IToken t = tokenSource.peek();
                String kind = parseIdentifier();
                tokenSource.setIndex(start);
-               if (kind.equals("execution") || kind.equals("call") || 
-                                               kind.equals("get") || kind.equals("set") ||
-                                               kind.equals("adviceexecution") ||
-                                               kind.equals("initialization") || 
-                                               kind.equals("preinitialization") ||
-                                               kind.equals("staticinitialization")) {
-                       return parseKindedAnnotationPointcut();
+               if (kind.equals("annotation")) {
+                       return parseAtAnnotationPointcut();
                } else if (kind.equals("args")) {
                        return parseArgsAnnotationPointcut();
                } else if (kind.equals("this") || kind.equals("target")) {
@@ -288,35 +283,15 @@ public class PatternParser {
                } throw new ParserException("@pointcut name expected, but found " + kind, t);
        }
        
-       private Pointcut parseKindedAnnotationPointcut() {
-               String kind = parseIdentifier();
-               Shadow.Kind shadowKind = null;
-               if (kind.equals("execution")) {
-                       shadowKind = Shadow.MethodExecution; // also matches cons execution
-               } else if (kind.equals("call")) {
-                       shadowKind = Shadow.MethodCall; // also matches cons call
-               } else if (kind.equals("get")) {
-                       shadowKind = Shadow.FieldGet;
-               } else if (kind.equals("set")) {
-                       shadowKind = Shadow.FieldSet;
-               } else if (kind.equals("adviceexecution")) {
-                       shadowKind = Shadow.AdviceExecution;
-               } else if (kind.equals("initialization")) {
-                       shadowKind = Shadow.Initialization;
-               } else if (kind.equals("preinitialization")) {
-                       shadowKind = Shadow.PreInitialization;
-               } else if (kind.equals("staticinitialization")) {
-                       shadowKind = Shadow.StaticInitialization;
-               } else {
-                       throw new ParserException(("bad kind: " + kind), tokenSource.peek());
-               }
+       private Pointcut parseAtAnnotationPointcut() {
+               parseIdentifier();
                eat("(");
                if (maybeEat(")")) {
-                       throw new ParserException("expecting @AnnotationName or parameter, but found ')'", tokenSource.peek());
+                       throw new ParserException("@AnnotationName or parameter", tokenSource.peek());
                }
-               AnnotationTypePattern type = parseAnnotationNameOrVarTypePattern(); 
+               ExactAnnotationTypePattern type = parseAnnotationNameOrVarTypePattern(); 
                eat(")");
-               return new KindedAnnotationPointcut(shadowKind,type);
+               return new AnnotationPointcut(type);
        }
 
        
@@ -648,8 +623,8 @@ public class PatternParser {
 //     }
        
        
-       protected AnnotationTypePattern parseAnnotationNameOrVarTypePattern() {
-               AnnotationTypePattern p = null;
+       protected ExactAnnotationTypePattern parseAnnotationNameOrVarTypePattern() {
+               ExactAnnotationTypePattern p = null;
                int startPos = tokenSource.peek().getStart();
                if (maybeEat("@")) {
                        p = parseSimpleAnnotationName();
@@ -666,9 +641,9 @@ public class PatternParser {
        /**
         * @return
         */
-       private AnnotationTypePattern parseSimpleAnnotationName() {
+       private ExactAnnotationTypePattern parseSimpleAnnotationName() {
                // the @ has already been eaten...
-               AnnotationTypePattern p;
+               ExactAnnotationTypePattern p;
                StringBuffer annotationName = new StringBuffer();
                annotationName.append(parseIdentifier());
                while (maybeEat(".")) {
index 2babd0c33f9cf8c524dcd7a60e460b2e0c572fd5..e85db612fa42178c83de8ab03165ef42bd602fef 100644 (file)
@@ -124,7 +124,7 @@ public abstract class Pointcut extends PatternNode implements PointcutExpression
        public static final byte HANDLER = 13;
        public static final byte IF_TRUE = 14;
        public static final byte IF_FALSE = 15;
-       public static final byte ATKINDED = 16;
+       public static final byte ANNOTATION = 16;
        
        public static final byte NONE = 20;
 
@@ -242,7 +242,7 @@ public abstract class Pointcut extends PatternNode implements PointcutExpression
                        case HANDLER: ret = HandlerPointcut.read(s, context); break;
                        case IF_TRUE: ret = IfPointcut.makeIfTruePointcut(RESOLVED); break;
                        case IF_FALSE: ret = IfPointcut.makeIfFalsePointcut(RESOLVED); break;
-                       case ATKINDED: ret = KindedAnnotationPointcut.read(s, context); break;
+                       case ANNOTATION: ret = AnnotationPointcut.read(s, context); break;
                        case NONE: ret = makeMatchesNothing(RESOLVED); break;
                        default:
                                throw new BCException("unknown kind: " + kind);