]> source.dussan.org Git - aspectj.git/commitdiff
@within, @withincode impl (non-binding)
authoracolyer <acolyer>
Wed, 8 Dec 2004 17:10:18 +0000 (17:10 +0000)
committeracolyer <acolyer>
Wed, 8 Dec 2004 17:10:18 +0000 (17:10 +0000)
weaver/src/org/aspectj/weaver/patterns/PatternParser.java
weaver/src/org/aspectj/weaver/patterns/Pointcut.java
weaver/src/org/aspectj/weaver/patterns/ThisOrTargetAnnotationPointcut.java
weaver/src/org/aspectj/weaver/patterns/WithinAnnotationPointcut.java
weaver/src/org/aspectj/weaver/patterns/WithinCodeAnnotationPointcut.java

index ae6f0cbc206c0ffff74420f35f8079c7851e4647..684377120e5aae5e06558489c46211cb38c22d1f 100644 (file)
@@ -373,7 +373,7 @@ public class PatternParser {
                if (maybeEat(")")) {
                        throw new ParserException("expecting @AnnotationName or parameter, but found ')'", tokenSource.peek());
                }
-               AnnotationTypePattern type = parseAnnotationNameOrVarTypePattern(); 
+               ExactAnnotationTypePattern type = parseAnnotationNameOrVarTypePattern(); 
                eat(")");
                return new WithinCodeAnnotationPointcut(type);          
        }
index e85db612fa42178c83de8ab03165ef42bd602fef..e29b80c445402ff9c0f9779c77f8a6a40ccf2081 100644 (file)
@@ -125,6 +125,8 @@ public abstract class Pointcut extends PatternNode implements PointcutExpression
        public static final byte IF_TRUE = 14;
        public static final byte IF_FALSE = 15;
        public static final byte ANNOTATION = 16;
+       public static final byte ATWITHIN = 17;
+       public static final byte ATWITHINCODE = 18;
        
        public static final byte NONE = 20;
 
@@ -243,6 +245,8 @@ public abstract class Pointcut extends PatternNode implements PointcutExpression
                        case IF_TRUE: ret = IfPointcut.makeIfTruePointcut(RESOLVED); break;
                        case IF_FALSE: ret = IfPointcut.makeIfFalsePointcut(RESOLVED); break;
                        case ANNOTATION: ret = AnnotationPointcut.read(s, context); break;
+                       case ATWITHIN: ret = WithinAnnotationPointcut.read(s, context); break;
+                       case ATWITHINCODE: ret = WithinCodeAnnotationPointcut.read(s, context); break;
                        case NONE: ret = makeMatchesNothing(RESOLVED); break;
                        default:
                                throw new BCException("unknown kind: " + kind);
index de488dc17bbec22e138c96202182426705f2ffc8..7c1a302640e8c19d14fdab1668ec58a19f979873 100644 (file)
@@ -104,5 +104,6 @@ public class ThisOrTargetAnnotationPointcut extends NameBindingPointcut {
                buf.append(isThis ? "@this(" : "@target(");
                buf.append(type.toString());
                buf.append(")");
-               return buf.toString();    }
+               return buf.toString();   
+       }
 }
index 71937aadff4644df7a2aa0f988dbcf93d9b6b9b0..e5242d7d1781b46e88693aced70801fe022c395a 100644 (file)
@@ -9,14 +9,24 @@
  * ******************************************************************/
 package org.aspectj.weaver.patterns;
 
+import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
 
+import org.aspectj.bridge.IMessage;
+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.ResolvedTypeX;
 import org.aspectj.weaver.Shadow;
+import org.aspectj.weaver.ShadowMunger;
+import org.aspectj.weaver.TypeX;
+import org.aspectj.weaver.WeaverMessages;
+import org.aspectj.weaver.ast.Literal;
 import org.aspectj.weaver.ast.Test;
+import org.aspectj.weaver.ast.Var;
 
 /**
  * @author colyer
@@ -26,37 +36,50 @@ import org.aspectj.weaver.ast.Test;
  */
 public class WithinAnnotationPointcut extends NameBindingPointcut {
 
-       private AnnotationTypePattern type;
+       private AnnotationTypePattern annotationTypePattern;
+       private ShadowMunger munger;
+       
        /**
         * 
         */
        public WithinAnnotationPointcut(AnnotationTypePattern type) {
                super();
-               this.type = type;
+               this.annotationTypePattern = type;
+       }
+       
+       public WithinAnnotationPointcut(AnnotationTypePattern 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) {
-               // TODO Auto-generated method stub
-               return null;
+           return annotationTypePattern.matches(info.getType());
        }
 
        /* (non-Javadoc)
         * @see org.aspectj.weaver.patterns.Pointcut#match(org.aspectj.weaver.Shadow)
         */
        public FuzzyBoolean match(Shadow shadow) {
-               // TODO Auto-generated method stub
-               return null;
+               ResolvedTypeX enclosingType = shadow.getIWorld().resolve(shadow.getEnclosingType(),true);
+               if (enclosingType == ResolvedTypeX.MISSING) {
+                       IMessage msg = new Message(
+                           WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE_WITHINPCD,
+                                                     shadow.getEnclosingType().getName()),
+                               shadow.getSourceLocation(),true,new ISourceLocation[]{getSourceLocation()});
+                       shadow.getIWorld().getMessageHandler().handleMessage(msg);
+               }
+               return annotationTypePattern.matches(enclosingType);
        }
 
        /* (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) {
-               // TODO Auto-generated method stub
-
+               annotationTypePattern = (ExactAnnotationTypePattern) annotationTypePattern.resolveBindings(scope,bindings,true);
+               // must be either a Var, or an annotation type pattern
        }
 
        /* (non-Javadoc)
@@ -71,33 +94,77 @@ public class WithinAnnotationPointcut extends NameBindingPointcut {
         * @see org.aspectj.weaver.patterns.Pointcut#concretize1(org.aspectj.weaver.ResolvedTypeX, org.aspectj.weaver.IntMap)
         */
        protected Pointcut concretize1(ResolvedTypeX inAspect, IntMap bindings) {
-               // TODO Auto-generated method stub
-               return null;
+               ExactAnnotationTypePattern newType = (ExactAnnotationTypePattern) annotationTypePattern.remapAdviceFormals(bindings);           
+               Pointcut ret = new WithinAnnotationPointcut(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) {
-               // TODO Auto-generated method stub
-               return null;
+               if (annotationTypePattern instanceof BindingAnnotationTypePattern) {
+                       BindingAnnotationTypePattern btp = (BindingAnnotationTypePattern)annotationTypePattern;
+                       TypeX annotationType = btp.annotationType;
+                       Var var = shadow.getWithinAnnotationVar(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 {
-               // TODO Auto-generated method stub
-
+               s.writeByte(Pointcut.ATWITHIN);
+               annotationTypePattern.write(s);
+               writeLocation(s);
        }
 
+       public static Pointcut read(DataInputStream s, ISourceContext context) throws IOException {
+               AnnotationTypePattern type = AnnotationTypePattern.read(s, context);
+               WithinAnnotationPointcut ret = new WithinAnnotationPointcut((ExactAnnotationTypePattern)type);
+               ret.readLocation(context, s);
+               return ret;
+       }
+       
+       /* (non-Javadoc)
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    public boolean equals(Object obj) {
+        if (!(obj instanceof WithinAnnotationPointcut)) return false;
+        WithinAnnotationPointcut other = (WithinAnnotationPointcut) obj;
+        return other.annotationTypePattern.equals(this.annotationTypePattern);
+    }
+    
+    /* (non-Javadoc)
+     * @see java.lang.Object#hashCode()
+     */
+    public int hashCode() {
+        return 17 + 19*annotationTypePattern.hashCode();
+    }
+    
        /* (non-Javadoc)
      * @see java.lang.Object#toString()
      */
     public String toString() {
                StringBuffer buf = new StringBuffer();
                buf.append("@within(");
-               buf.append(type.toString());
+               buf.append(annotationTypePattern.toString());
                buf.append(")");
                return buf.toString();
     }
index 2ebff9be924f25e65c41808b8971c966fa8b04d4..b2801171806c8916b9cbb3fe71cf7b4195a04299 100644 (file)
@@ -9,14 +9,26 @@
  * ******************************************************************/
 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;
 
 /**
  * @author colyer
@@ -26,37 +38,55 @@ import org.aspectj.weaver.ast.Test;
  */
 public class WithinCodeAnnotationPointcut extends NameBindingPointcut {
 
-       private AnnotationTypePattern type;
-       /**
-        * 
-        */
-       public WithinCodeAnnotationPointcut(AnnotationTypePattern type) {
+       private ExactAnnotationTypePattern annotationTypePattern;
+    private ShadowMunger munger = null; // only set after concretization
+       
+       public WithinCodeAnnotationPointcut(ExactAnnotationTypePattern type) {
                super();
-               this.type = type;
+               this.annotationTypePattern =  type;
+               this.pointcutKind = Pointcut.ANNOTATION;
+       }
+
+       public WithinCodeAnnotationPointcut(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) {
-               // TODO Auto-generated method stub
-               return null;
+               return FuzzyBoolean.MAYBE;
        }
 
        /* (non-Javadoc)
         * @see org.aspectj.weaver.patterns.Pointcut#match(org.aspectj.weaver.Shadow)
         */
        public FuzzyBoolean match(Shadow shadow) {
-               // TODO Auto-generated method stub
-               return null;
+               AnnotatedElement toMatchAgainst = null;
+               Member member = shadow.getEnclosingCodeSignature();             
+               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;
+               }
+
+               toMatchAgainst = TypeX.forName(rMember.getSignature()).resolve(shadow.getIWorld());
+               
+               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) {
-               // TODO Auto-generated method stub
-
+               annotationTypePattern = (ExactAnnotationTypePattern) annotationTypePattern.resolveBindings(scope,bindings,true);
+               // must be either a Var, or an annotation type pattern
        }
 
        /* (non-Javadoc)
@@ -71,34 +101,72 @@ public class WithinCodeAnnotationPointcut extends NameBindingPointcut {
         * @see org.aspectj.weaver.patterns.Pointcut#concretize1(org.aspectj.weaver.ResolvedTypeX, org.aspectj.weaver.IntMap)
         */
        protected Pointcut concretize1(ResolvedTypeX inAspect, IntMap bindings) {
-               // TODO Auto-generated method stub
-               return null;
+               ExactAnnotationTypePattern newType = (ExactAnnotationTypePattern) annotationTypePattern.remapAdviceFormals(bindings);           
+               Pointcut ret = new WithinCodeAnnotationPointcut(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) {
-               // TODO Auto-generated method stub
-               return null;
+               
+               if (annotationTypePattern instanceof BindingAnnotationTypePattern) {
+                       BindingAnnotationTypePattern btp = (BindingAnnotationTypePattern)annotationTypePattern;
+                       TypeX annotationType = btp.annotationType;
+                       Var var = shadow.getWithinCodeAnnotationVar(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 {
-               // TODO Auto-generated method stub
+               s.writeByte(Pointcut.ATWITHINCODE);
+               annotationTypePattern.write(s);
+               writeLocation(s);
+       }
 
+       public static Pointcut read(DataInputStream s, ISourceContext context) throws IOException {
+               AnnotationTypePattern type = AnnotationTypePattern.read(s, context);
+               WithinCodeAnnotationPointcut ret = new WithinCodeAnnotationPointcut((ExactAnnotationTypePattern)type);
+               ret.readLocation(context, s);
+               return ret;
        }
 
-       /* (non-Javadoc)
-     * @see java.lang.Object#toString()
-     */
-    public String toString() {
-               StringBuffer buf = new StringBuffer();
+       public boolean equals(Object other) {
+               if (!(other instanceof WithinCodeAnnotationPointcut)) return false;
+               WithinCodeAnnotationPointcut o = (WithinCodeAnnotationPointcut)other;
+               return o.annotationTypePattern.equals(this.annotationTypePattern);
+       }
+    
+    public int hashCode() {
+        int result = 17;
+        result = 23*result + annotationTypePattern.hashCode();
+        return result;
+    }
+       
+       public String toString() {
+           StringBuffer buf = new StringBuffer();
                buf.append("@withincode(");
-               buf.append(type.toString());
+               buf.append(annotationTypePattern.toString());
                buf.append(")");
                return buf.toString();
-    }
+       }
 }