]> source.dussan.org Git - aspectj.git/commitdiff
support for asking a pointcut if it matches at a join point
authoracolyer <acolyer>
Tue, 8 Jun 2004 13:54:29 +0000 (13:54 +0000)
committeracolyer <acolyer>
Tue, 8 Jun 2004 13:54:29 +0000 (13:54 +0000)
35 files changed:
weaver/src/org/aspectj/weaver/patterns/AndPointcut.java
weaver/src/org/aspectj/weaver/patterns/AndTypePattern.java
weaver/src/org/aspectj/weaver/patterns/ArgsPointcut.java
weaver/src/org/aspectj/weaver/patterns/CflowPointcut.java
weaver/src/org/aspectj/weaver/patterns/ConcreteCflowPointcut.java
weaver/src/org/aspectj/weaver/patterns/ExactTypePattern.java
weaver/src/org/aspectj/weaver/patterns/ExposedState.java
weaver/src/org/aspectj/weaver/patterns/HandlerPointcut.java
weaver/src/org/aspectj/weaver/patterns/IfPointcut.java
weaver/src/org/aspectj/weaver/patterns/KindedPointcut.java
weaver/src/org/aspectj/weaver/patterns/NotPointcut.java
weaver/src/org/aspectj/weaver/patterns/NotTypePattern.java
weaver/src/org/aspectj/weaver/patterns/OrPointcut.java
weaver/src/org/aspectj/weaver/patterns/OrTypePattern.java
weaver/src/org/aspectj/weaver/patterns/PerCflow.java
weaver/src/org/aspectj/weaver/patterns/PerClause.java
weaver/src/org/aspectj/weaver/patterns/Pointcut.java
weaver/src/org/aspectj/weaver/patterns/ReferencePointcut.java
weaver/src/org/aspectj/weaver/patterns/SignaturePattern.java
weaver/src/org/aspectj/weaver/patterns/ThisOrTargetPointcut.java
weaver/src/org/aspectj/weaver/patterns/ThrowsPattern.java
weaver/src/org/aspectj/weaver/patterns/TypePattern.java
weaver/src/org/aspectj/weaver/patterns/TypePatternList.java
weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java
weaver/src/org/aspectj/weaver/patterns/WithinPointcut.java
weaver/src/org/aspectj/weaver/patterns/WithincodePointcut.java
weaver/testsrc/org/aspectj/weaver/patterns/AndOrNotTestCase.java
weaver/testsrc/org/aspectj/weaver/patterns/ArgsTestCase.java [new file with mode: 0644]
weaver/testsrc/org/aspectj/weaver/patterns/HandlerTestCase.java [new file with mode: 0644]
weaver/testsrc/org/aspectj/weaver/patterns/KindedTestCase.java [new file with mode: 0644]
weaver/testsrc/org/aspectj/weaver/patterns/PatternsTests.java
weaver/testsrc/org/aspectj/weaver/patterns/PointcutTestCase.java [new file with mode: 0644]
weaver/testsrc/org/aspectj/weaver/patterns/ThisOrTargetTestCase.java
weaver/testsrc/org/aspectj/weaver/patterns/WithinCodeTestCase.java [new file with mode: 0644]
weaver/testsrc/org/aspectj/weaver/patterns/WithinTestCase.java

index aea40a3e314eb42da78690ac46019e05a18b9d5c..05952f59310db09cd8dcc90115b3ff01d4493d0c 100644 (file)
@@ -17,6 +17,7 @@ import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
 
+import org.aspectj.lang.JoinPoint;
 import org.aspectj.util.FuzzyBoolean;
 import org.aspectj.weaver.ISourceContext;
 import org.aspectj.weaver.IntMap;
@@ -42,6 +43,14 @@ public class AndPointcut extends Pointcut {
                return left.match(shadow).and(right.match(shadow));
        }
        
+       public FuzzyBoolean match(JoinPoint jp, JoinPoint.StaticPart encJP) {
+               return left.match(jp,encJP).and(right.match(jp,encJP));
+       }
+       
+       public FuzzyBoolean match(JoinPoint.StaticPart jpsp) {
+               return left.match(jpsp).and(right.match(jpsp));
+       }
+       
        public String toString() {
                return "(" + left.toString() + " && " + right.toString() + ")";
        }
@@ -63,8 +72,11 @@ public class AndPointcut extends Pointcut {
                left.resolveBindings(scope, bindings);
                right.resolveBindings(scope, bindings);
        }
-
-
+       
+       public void resolveBindingsFromRTTI() {
+               left.resolveBindingsFromRTTI();
+               right.resolveBindingsFromRTTI();
+       }
 
        public void write(DataOutputStream s) throws IOException {
                s.writeByte(Pointcut.AND);
index 468e95ab219795700da7c92161a5c62819ef34ce..c055692fec53609329dbd9cf79b36f3762c1b910 100644 (file)
@@ -48,10 +48,23 @@ public class AndTypePattern extends TypePattern {
                return left.matchesExactly(type) && right.matchesExactly(type);
        }
        
-       public boolean matchesStatically(ResolvedTypeX type) {
+       public boolean matchesStatically(Class type) {
                return left.matchesStatically(type) && right.matchesStatically(type);
        }
 
+       public FuzzyBoolean matchesInstanceof(Class type) {
+               return left.matchesInstanceof(type).and(right.matchesInstanceof(type));
+       }
+
+       protected boolean matchesExactly(Class type) {
+               //??? if these had side-effects, this sort-circuit could be a mistake
+               return left.matchesExactly(type) && right.matchesExactly(type);
+       }
+       
+       public boolean matchesStatically(ResolvedTypeX type) {
+               return left.matchesStatically(type) && right.matchesStatically(type);
+       }
+       
        public void write(DataOutputStream s) throws IOException {
                s.writeByte(TypePattern.AND);
                left.write(s);
@@ -76,6 +89,13 @@ public class AndTypePattern extends TypePattern {
                return this;
        }
        
+       public TypePattern resolveBindingsFromRTTI(boolean allowBinding, boolean requireExactType) {
+               if (requireExactType) return TypePattern.NO;
+               left = left.resolveBindingsFromRTTI(allowBinding,requireExactType);
+               right = right.resolveBindingsFromRTTI(allowBinding,requireExactType);
+               return this;
+       }
+       
        public String toString() {
                return "(" + left.toString() + " && " + right.toString() + ")";
        }
index 86c55b920595c20006e45cda39c7c47df40ef2de..efc1219c02f6c2e01c4cfc9ce4241d283069176c 100644 (file)
@@ -18,6 +18,9 @@ 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.lang.JoinPoint;
 import org.aspectj.util.FuzzyBoolean;
 import org.aspectj.weaver.BetaException;
 import org.aspectj.weaver.ISourceContext;
@@ -34,7 +37,7 @@ import org.aspectj.weaver.ast.Test;
  * @author Erik Hilsdale
  * @author Jim Hugunin
  */
-public class ArgsPointcut extends NameBindingPointcut {
+public class ArgsPointcut extends NameBindingPointcut { 
        TypePatternList arguments;
        
        public ArgsPointcut(TypePatternList arguments) {
@@ -50,6 +53,10 @@ public class ArgsPointcut extends NameBindingPointcut {
                        arguments.matches(shadow.getIWorld().resolve(shadow.getArgTypes()), TypePattern.DYNAMIC);
                return ret;
        }
+       
+       public FuzzyBoolean match(JoinPoint jp, JoinPoint.StaticPart jpsp) {
+               return arguments.matches(jp.getArgs(),TypePattern.DYNAMIC);
+       }
 
        public void write(DataOutputStream s) throws IOException {
                s.writeByte(Pointcut.ARGS);
@@ -82,6 +89,13 @@ public class ArgsPointcut extends NameBindingPointcut {
                }
        }
        
+       public void resolveBindingsFromRTTI() {
+               arguments.resolveBindingsFromRTTI(true, true);
+               if (arguments.ellipsisCount > 1) {
+                       throw new UnsupportedOperationException("uses more than one .. in args (compiler limitation)");
+               }               
+       }
+       
        public void postRead(ResolvedTypeX enclosingType) {
                arguments.postRead(enclosingType);
        }
@@ -118,6 +132,17 @@ public class ArgsPointcut extends NameBindingPointcut {
                                if (type.matchesInstanceof(shadow.getIWorld().resolve(argType)).alwaysTrue()) {
                                        continue;
                                }
+                       } else {
+                         BindingTypePattern btp = (BindingTypePattern)type;
+                         // Check if we have already bound something to this formal
+                         if (state.get(btp.getFormalIndex())!=null) {
+                               ISourceLocation isl = getSourceLocation();
+                               Message errorMessage = new Message(
+                    "Ambiguous binding of type "+type.getExactType().toString()+
+                    " using args(..) at this line.  Use one args(..) per matched join point,"+"" +\r                    " see secondary source location for location of extraneous args(..)",
+                                       shadow.getSourceLocation(),true,new ISourceLocation[]{getSourceLocation()});
+                               shadow.getIWorld().getMessageHandler().handleMessage(errorMessage);
+                         }
                        }
                        ret = Test.makeAnd(ret,
                                exposeStateForVar(shadow.getArgVar(i), type, state,shadow.getIWorld()));
index ef6dc5d80163e0c8ce7ccbc7d078fa4ee77e7ecc..3a00891b1b38704586b5f4fcdc97f1ae80d156d5 100644 (file)
@@ -101,6 +101,12 @@ public class CflowPointcut extends Pointcut {
                }
        }
        
+       public void resolveBindingsFromRTTI() {
+               if (entry.state != RESOLVED) {
+                       entry.resolveBindingsFromRTTI();
+               }
+       }
+       
        public boolean equals(Object other) {
                if (!(other instanceof CflowPointcut)) return false;
                CflowPointcut o = (CflowPointcut)other;
index cbb65f37e3d3a0abe0fd42459e84168fb9e8140c..df2c76bbaf4f55b2a62e7931a08c653bfa739b73 100644 (file)
@@ -58,6 +58,9 @@ public class ConcreteCflowPointcut extends Pointcut {
                throw new RuntimeException("unimplemented");
        }
        
+       public void resolveBindingsFromRTTI() {
+               throw new RuntimeException("unimplemented");
+       }
        
        public boolean equals(Object other) {
                if (!(other instanceof ConcreteCflowPointcut)) return false;
index 1da25d363d9bc97840cf88cd1767fe02a41db440..99ecf90126dfe0b07aa9db73332631631cbb8e45 100644 (file)
@@ -48,6 +48,26 @@ public class ExactTypePattern extends TypePattern {
                return matchType.isCoerceableFrom(type) ? FuzzyBoolean.MAYBE : FuzzyBoolean.NO;
        }
        
+       public boolean matchesExactly(Class matchType) {
+               try {
+                       Class toMatchAgainst = Class.forName(type.getName());
+                       return matchType == toMatchAgainst;
+               } catch (ClassNotFoundException cnfEx) {
+                       return false;                   
+               }
+       }
+       
+       public FuzzyBoolean matchesInstanceof(Class matchType) {
+               if (matchType.equals(Object.class)) return FuzzyBoolean.YES;
+               
+               try {
+                       Class toMatchAgainst = Class.forName(type.getName());
+                       return toMatchAgainst.isAssignableFrom(matchType) ? FuzzyBoolean.YES : FuzzyBoolean.NO;
+               } catch (ClassNotFoundException cnfEx) {
+                       return FuzzyBoolean.NO;                 
+               }
+       }
+       
     public boolean equals(Object other) {
        if (!(other instanceof ExactTypePattern)) return false;
        ExactTypePattern o = (ExactTypePattern)other;
@@ -81,5 +101,9 @@ public class ExactTypePattern extends TypePattern {
                throw new BCException("trying to re-resolve");
                
        }
+       
+       public TypePattern resolveBindingsFromRTTI(boolean allowBinding, boolean requireExactType) {
+               throw new IllegalStateException("trying to re-resolve");
+       }
 
 }
index 8e130c6893e7c2e1b7e3ce5993c4507851eea0b0..063b5608e614b124c42752b709598d083c6a3259 100644 (file)
@@ -35,6 +35,7 @@ public class ExposedState {
 
        public void set(int i, Var var) {
                //XXX add sanity checks
+               // Check (1) added to call of set(), verifies we aren't binding twice to the same formal
                vars[i] = var;
        }
     public Var get(int i) {
index aa50bd7b6925c5c8712a505fffce9ac27a4e44b4..c1fcfdbd351ef995beffc6576215f7d446cf7395 100644 (file)
@@ -17,6 +17,7 @@ import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
 
+import org.aspectj.lang.JoinPoint;
 import org.aspectj.util.FuzzyBoolean;
 import org.aspectj.weaver.ISourceContext;
 import org.aspectj.weaver.IntMap;
@@ -52,6 +53,18 @@ public class HandlerPointcut extends Pointcut {
                                TypePattern.STATIC);
        }
        
+       public FuzzyBoolean match(JoinPoint jp, JoinPoint.StaticPart jpsp) {
+               if (!jp.getKind().equals(JoinPoint.EXCEPTION_HANDLER)) return FuzzyBoolean.NO;
+               if (jp.getArgs().length > 0) {
+                       Object caughtException = jp.getArgs()[0];
+                       return exceptionType.matches(caughtException,TypePattern.STATIC);
+               } else {
+                       return FuzzyBoolean.NO;
+               }
+       }
+       
+
+       
        public boolean equals(Object other) {
                if (!(other instanceof HandlerPointcut)) return false;
                HandlerPointcut o = (HandlerPointcut)other;
@@ -92,6 +105,11 @@ public class HandlerPointcut extends Pointcut {
                exceptionType = exceptionType.resolveBindings(scope, bindings, false, false);
                //XXX add error if exact binding and not an exception
        }
+       
+       public void resolveBindingsFromRTTI() {
+               exceptionType = exceptionType.resolveBindingsFromRTTI(false,false);
+       }
+       
        public Test findResidue(Shadow shadow, ExposedState state) {
                return match(shadow).alwaysTrue() ? Literal.TRUE : Literal.FALSE;
        }
index baf55d85b12164b02de55bb9817b4825f825b8f1..e770509b379693fb2536e29e50de8d59cd9b6cb9 100644 (file)
@@ -75,6 +75,8 @@ public class IfPointcut extends Pointcut {
                //??? all we need is good error messages in here in cflow contexts
        }
        
+       public void resolveBindingsFromRTTI() {}
+       
        public boolean equals(Object other) {
                if (!(other instanceof IfPointcut)) return false;
                IfPointcut o = (IfPointcut)other;
@@ -161,6 +163,21 @@ public class IfPointcut extends Pointcut {
                }
                IfPointcut ret = new IfPointcut(testMethod, extraParameterFlags);
                partiallyConcretized = ret;
+               
+               // It is possible to directly code your pointcut expression in a per clause
+               // rather than defining a pointcut declaration and referencing it in your
+               // per clause.  If you do this, we have problems (bug #62458).  For now,
+               // let's police that you are trying to code a pointcut in a per clause and
+               // put out a compiler error.
+               if (bindings.directlyInAdvice() && bindings.getEnclosingAdvice()==null) {
+                       // Assumption: if() is in a per clause if we say we are directly in advice
+                       // but we have no enclosing advice.
+                       inAspect.getWorld().showMessage(IMessage.ERROR,
+                               "if() pointcut designator cannot be used directly in a per clause (compiler limitation).  Create a named pointcut containing the if() and refer to it",
+                               this.getSourceLocation(),null);
+                       return Pointcut.makeMatchesNothing(Pointcut.CONCRETE);
+               }
+               
                if (bindings.directlyInAdvice()) {
                        ShadowMunger advice = bindings.getEnclosingAdvice();
                        if (advice instanceof Advice) {
index 43e53724b92300d11da6c2562ea1027ff74c9d0c..6154f07d883a604677dbb414bc9b4195eec598a0 100644 (file)
@@ -18,10 +18,12 @@ import java.io.DataOutputStream;
 import java.io.IOException;
 
 import org.aspectj.bridge.ISourceLocation;
+import org.aspectj.lang.JoinPoint;
 import org.aspectj.util.FuzzyBoolean;
 import org.aspectj.weaver.Checker;
 import org.aspectj.weaver.ISourceContext;
 import org.aspectj.weaver.IntMap;
+import org.aspectj.weaver.Member;
 import org.aspectj.weaver.ResolvedTypeX;
 import org.aspectj.weaver.Shadow;
 import org.aspectj.weaver.ShadowMunger;
@@ -72,6 +74,15 @@ public class KindedPointcut extends Pointcut {
                return FuzzyBoolean.YES;
        }
        
+       public FuzzyBoolean match(JoinPoint.StaticPart jpsp) {
+               if (jpsp.getKind().equals(kind.getName())) {
+                       if (signature.matches(jpsp)) {
+                               return FuzzyBoolean.YES;
+                       }
+               }
+               return FuzzyBoolean.NO;
+       }
+       
        private void warnOnConfusingSig(Shadow shadow) {
         // no warnings for declare error/warning
         if (munger instanceof Checker) return;
@@ -180,7 +191,26 @@ public class KindedPointcut extends Pointcut {
 //                                     this.getSourceLocation()));
                }
                signature = signature.resolveBindings(scope, bindings);
+               
+               
+               if (kind == Shadow.ConstructorExecution) {              // Bug fix 60936
+                 if (signature.getDeclaringType() != null) {
+                       World world = scope.getWorld();
+                       TypeX exactType = signature.getDeclaringType().getExactType();
+                       if (signature.getKind() == Member.CONSTRUCTOR &&
+                               !exactType.equals(ResolvedTypeX.MISSING) &&
+                               exactType.isInterface(world) &&
+                               !signature.getDeclaringType().isIncludeSubtypes()) {
+                                       world.getLint().noInterfaceCtorJoinpoint.signal(exactType.toString(), getSourceLocation());
+                               }
+                 }
+               }
+       }
+       
+       public void resolveBindingsFromRTTI() {
+               signature = signature.resolveBindingsFromRTTI();
        }
+       
        public Test findResidue(Shadow shadow, ExposedState state) {
                return match(shadow).alwaysTrue() ? Literal.TRUE : Literal.FALSE;
        }
index 59fe2522ab475391a0a9b0062a2dcace82b852cd..f57d2475d98ae726928e8889aac62f20eae59414 100644 (file)
@@ -17,6 +17,7 @@ import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
 
+import org.aspectj.lang.JoinPoint;
 import org.aspectj.util.FuzzyBoolean;
 import org.aspectj.weaver.ISourceContext;
 import org.aspectj.weaver.IntMap;
@@ -44,6 +45,14 @@ public class NotPointcut extends Pointcut {
        public FuzzyBoolean match(Shadow shadow) {
                return body.match(shadow).not();
        }
+
+       public FuzzyBoolean match(JoinPoint jp, JoinPoint.StaticPart encJP) {
+               return body.match(jp,encJP).not();
+       }
+
+       public FuzzyBoolean match(JoinPoint.StaticPart jpsp) {
+               return body.match(jpsp).not();
+       }
        
        public String toString() {
                return "!" + body.toString();
@@ -73,6 +82,10 @@ public class NotPointcut extends Pointcut {
                
        }
        
+       public void resolveBindingsFromRTTI() {
+               body.resolveBindingsFromRTTI();
+       }
+       
 
        public void write(DataOutputStream s) throws IOException {
                s.writeByte(Pointcut.NOT);
index 5a3ceacf9b77ce0bc7663176124ab6091dc661e6..68a719c7372aeafe410baf51a3f8fa69cb19ed22 100644 (file)
@@ -47,10 +47,22 @@ public class NotTypePattern extends TypePattern {
                return !pattern.matchesExactly(type);
        }
        
-       public boolean matchesStatically(ResolvedTypeX type) {
+       public boolean matchesStatically(Class type) {
                return !pattern.matchesStatically(type);
        }
 
+       public FuzzyBoolean matchesInstanceof(Class type) {
+               return pattern.matchesInstanceof(type).not();
+       }
+
+       protected boolean matchesExactly(Class type) {
+               return !pattern.matchesExactly(type);
+       }
+       
+       public boolean matchesStatically(ResolvedTypeX type) {
+               return !pattern.matchesStatically(type);
+       }
+       
        public void write(DataOutputStream s) throws IOException {
                s.writeByte(TypePattern.NOT);
                pattern.write(s);
@@ -72,6 +84,12 @@ public class NotTypePattern extends TypePattern {
                pattern = pattern.resolveBindings(scope, bindings, false, false);
                return this;
        }
+       
+       public TypePattern resolveBindingsFromRTTI(boolean allowBinding, boolean requireExactType) {
+               if (requireExactType) return TypePattern.NO;
+               pattern = pattern.resolveBindingsFromRTTI(allowBinding,requireExactType);
+               return this;
+       }
 
        public String toString() {
                return "!" + pattern;
index 1d1ce62982da6495ce1000c74fe4f21864ee56cc..225b100d797dd1fd82d6930dd0f9081a3cbd3789 100644 (file)
@@ -17,6 +17,7 @@ import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
 
+import org.aspectj.lang.JoinPoint;
 import org.aspectj.util.FuzzyBoolean;
 import org.aspectj.weaver.ISourceContext;
 import org.aspectj.weaver.IntMap;
@@ -43,6 +44,14 @@ public class OrPointcut extends Pointcut {
                return left.match(shadow).or(right.match(shadow));
        }
        
+       public FuzzyBoolean match(JoinPoint jp, JoinPoint.StaticPart encJP) {
+               return left.match(jp,encJP).or(right.match(jp,encJP));
+       }
+       
+       public FuzzyBoolean match(JoinPoint.StaticPart jpsp) {
+               return left.match(jpsp).or(right.match(jpsp));
+       }
+       
        public String toString() {
                return "(" + left.toString() + " || " + right.toString() + ")";
        }
@@ -69,6 +78,11 @@ public class OrPointcut extends Pointcut {
                if (bindings != null) bindings.checkEquals(old, scope);
                
        }
+       
+       public void resolveBindingsFromRTTI() {
+               left.resolveBindingsFromRTTI();
+               right.resolveBindingsFromRTTI();
+       }
 
        public void write(DataOutputStream s) throws IOException {
                s.writeByte(Pointcut.OR);
index 2900d4a2b0ec858ab9a25314f03a819f6bbd6182..da53ad6e554ca03a237049d152ee466819bbb7c4 100644 (file)
@@ -52,6 +52,19 @@ public class OrTypePattern extends TypePattern {
                return left.matchesStatically(type) || right.matchesStatically(type);
        }
 
+       public FuzzyBoolean matchesInstanceof(Class type) {
+               return left.matchesInstanceof(type).or(right.matchesInstanceof(type));
+       }
+
+       protected boolean matchesExactly(Class type) {
+               //??? if these had side-effects, this sort-circuit could be a mistake
+               return left.matchesExactly(type) || right.matchesExactly(type);
+       }
+       
+       public boolean matchesStatically(Class type) {
+               return left.matchesStatically(type) || right.matchesStatically(type);
+       }
+       
        public void write(DataOutputStream s) throws IOException {
                s.writeByte(TypePattern.OR);
                left.write(s);
@@ -76,6 +89,13 @@ public class OrTypePattern extends TypePattern {
                return this;
        }
        
+       public TypePattern resolveBindingsFromRTTI(boolean allowBinding, boolean requireExactType) {
+               if (requireExactType) return TypePattern.NO;
+               left = left.resolveBindingsFromRTTI(allowBinding,requireExactType);
+               right = right.resolveBindingsFromRTTI(allowBinding,requireExactType);
+               return this;
+       }
+       
        public String toString() {
                return "(" + left.toString() + " || " + right.toString() + ")";
        }
index 1c511bb080c9db7489730c44d13465e2d881ef4b..f0626758f8f7b01a7789b7b0d0605f20d6ca41a8 100644 (file)
@@ -59,7 +59,7 @@ public class PerCflow extends PerClause {
        // assert bindings == null;
        entry.resolve(scope);  
     }
-
+    
     public Test findResidue(Shadow shadow, ExposedState state) {
        Expr myInstance =
                Expr.makeCallExpr(AjcMemberMaker.perCflowAspectOfMethod(inAspect),
index b28e8fc24e7775fde36950b6d4fe0fa04663c3f6..632778c9e018f172970c99d074610463963b5659 100644 (file)
@@ -54,7 +54,11 @@ public abstract class PerClause extends Pointcut {
             throw new BCException("weird kind " + key);
         }
     }
-    
+
+       public void resolveBindingsFromRTTI() {
+       throw new UnsupportedOperationException("Can't resolve per-clauses at runtime");
+    }
+
        public static final Kind SINGLETON = new Kind("issingleton", 1);
        public static final Kind PERCFLOW  = new Kind("percflow", 2);
        public static final Kind PEROBJECT  = new Kind("perobject", 3);
index c7c98b425e4a057aed2b9a5cc5ae27a24dc973db..46636313522b2c3b87d9f642236c4d03bf6e6830 100644 (file)
@@ -17,6 +17,7 @@ import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
 
+import org.aspectj.lang.JoinPoint;
 import org.aspectj.util.FuzzyBoolean;
 import org.aspectj.util.TypeSafeEnum;
 import org.aspectj.weaver.Advice;
@@ -72,7 +73,23 @@ public abstract class Pointcut extends PatternNode {
         * XXX implementors need to handle state
         */
        public abstract FuzzyBoolean match(Shadow shadow);
+       
+       /*
+        * for runtime / dynamic pointcuts.
+        * Default implementation delegates to StaticPart matcher
+        */
+       public FuzzyBoolean match(JoinPoint jp, JoinPoint.StaticPart enclosingJoinPoint) {
+               return match(jp.getStaticPart());
+       }
 
+       /*
+        * for runtime / dynamic pointcuts.
+        * Not all pointcuts can be matched at runtime, those that can should overide either
+        * match(JoinPoint), or this method, or both.
+        */
+       public FuzzyBoolean match(JoinPoint.StaticPart jpsp) {
+               throw new UnsupportedOperationException("Pointcut expression " + this.toString() + "cannot be matched at runtime");
+       }
 
        public static final byte KINDED = 1;
        public static final byte WITHIN = 2;
@@ -93,6 +110,9 @@ public abstract class Pointcut extends PatternNode {
        // internal, only called from resolve
        protected abstract void resolveBindings(IScope scope, Bindings bindings);
        
+       // internal, only called from resolve
+       protected abstract void resolveBindingsFromRTTI();
+       
     /**
      * Returns this pointcut mutated
      */
@@ -104,6 +124,16 @@ public abstract class Pointcut extends PatternNode {
         this.state = RESOLVED;
         return this;   
     }
+    
+    /**
+     * Returns this pointcut with type patterns etc resolved based on available RTTI 
+     */
+    public Pointcut resolve() {
+       assertState(SYMBOLIC);
+       this.resolveBindingsFromRTTI();
+       this.state = RESOLVED;
+       return this;
+    }
        
        /**
         * Returns a new pointcut
@@ -218,9 +248,16 @@ public abstract class Pointcut extends PatternNode {
                public FuzzyBoolean match(Shadow shadow) {
                        return FuzzyBoolean.NO;
                }
+               
+               public FuzzyBoolean match(JoinPoint.StaticPart jpsp) {
+                       return FuzzyBoolean.NO;
+               }
 
                public void resolveBindings(IScope scope, Bindings bindings) {
                }
+               
+               public void resolveBindingsFromRTTI() {
+               }
        
                public void postRead(ResolvedTypeX enclosingType) {
                }
index b253b4d18a70b37cadf7a1e6615690de776c0353..af09bf906dc2fcc87660388713744f01bd2d7a20 100644 (file)
@@ -199,6 +199,10 @@ public class ReferencePointcut extends Pointcut {
                }
        }
        
+       public void resolveBindingsFromRTTI() {
+               throw new UnsupportedOperationException("Referenced pointcuts are not supported in runtime evaluation");
+       }
+       
        public void postRead(ResolvedTypeX enclosingType) {
                arguments.postRead(enclosingType);
        }
index 64a3f66b701487b69fc1d6a96ea08474ba69d755..5e4e121854a5172c9f3f6760ce3288753e9b6749 100644 (file)
@@ -16,9 +16,19 @@ package org.aspectj.weaver.patterns;
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
+import java.util.List;
 
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.Signature;
+import org.aspectj.lang.reflect.AdviceSignature;
+import org.aspectj.lang.reflect.ConstructorSignature;
+import org.aspectj.lang.reflect.FieldSignature;
+import org.aspectj.lang.reflect.MethodSignature;
 import org.aspectj.weaver.ISourceContext;
 import org.aspectj.weaver.Member;
 import org.aspectj.weaver.NameMangler;
@@ -68,6 +78,23 @@ public class SignaturePattern extends PatternNode {
        return this;
     }
     
+    public SignaturePattern resolveBindingsFromRTTI() {
+               if (returnType != null) {
+                       returnType = returnType.resolveBindingsFromRTTI(false, false);
+               } 
+               if (declaringType != null) {
+                       declaringType = declaringType.resolveBindingsFromRTTI(false, false);
+               }
+               if (parameterTypes != null) {
+                       parameterTypes = parameterTypes.resolveBindingsFromRTTI(false, false);
+               }
+               if (throwsPattern != null) {
+                       throwsPattern = throwsPattern.resolveBindingsFromRTTI();
+               }
+               
+       return this;            
+    }
+    
     
        public void postRead(ResolvedTypeX enclosingType) {
                if (returnType != null) {
@@ -134,6 +161,57 @@ public class SignaturePattern extends PatternNode {
                return false;
        }
 
+       // for dynamic join point matching
+       public boolean matches(JoinPoint.StaticPart jpsp) {
+               Signature sig = jpsp.getSignature();
+           if (kind == Member.ADVICE && !(sig instanceof AdviceSignature)) return false;
+           if (kind == Member.CONSTRUCTOR && !(sig instanceof ConstructorSignature)) return false;
+           if (kind == Member.FIELD && !(sig instanceof FieldSignature)) return false;
+           if (kind == Member.METHOD && !(sig instanceof MethodSignature)) return false;
+           if (kind == Member.STATIC_INITIALIZATION && !(jpsp.getKind().equals(JoinPoint.STATICINITIALIZATION))) return false;
+           if (kind == Member.POINTCUT) return false;
+                       
+           if (kind == Member.ADVICE) return true;
+
+           if (!modifiers.matches(sig.getModifiers())) return false;
+               
+               if (kind == Member.STATIC_INITIALIZATION) {
+                       //System.err.println("match static init: " + sig.getDeclaringType() + " with " + this);
+                       return declaringType.matchesStatically(sig.getDeclaringType());
+               } else if (kind == Member.FIELD) {
+                       Class returnTypeClass = ((FieldSignature)sig).getFieldType();
+                       if (!returnType.matchesStatically(returnTypeClass)) return false;
+                       if (!name.matches(sig.getName())) return false;
+                       boolean ret = declaringTypeMatch(sig);
+                       //System.out.println("   ret: " + ret);
+                       return ret;
+               } else if (kind == Member.METHOD) {
+                       MethodSignature msig = ((MethodSignature)sig);
+                       Class returnTypeClass = msig.getReturnType();
+                       Class[] params = msig.getParameterTypes();
+                       Class[] exceptionTypes = msig.getExceptionTypes();
+                       if (!returnType.matchesStatically(returnTypeClass)) return false;
+                       if (!name.matches(sig.getName())) return false;
+                       if (!parameterTypes.matches(params, TypePattern.STATIC).alwaysTrue()) {
+                               return false;
+                       }
+                       if (!throwsPattern.matches(exceptionTypes)) return false;
+                       return declaringTypeMatch(sig);
+               } else if (kind == Member.CONSTRUCTOR) {
+                       ConstructorSignature csig = (ConstructorSignature)sig;
+                       Class[] params = csig.getParameterTypes();
+                       Class[] exceptionTypes = csig.getExceptionTypes();
+                       if (!parameterTypes.matches(params, TypePattern.STATIC).alwaysTrue()) {
+                               return false;
+                       }
+                       if (!throwsPattern.matches(exceptionTypes)) return false;
+                       return declaringType.matchesStatically(sig.getDeclaringType());
+                       //return declaringTypeMatch(member.getDeclaringType(), member, world);                  
+               }
+                           
+               return false;
+       }
+       
        private boolean declaringTypeMatch(TypeX onTypeUnresolved, Member member, World world) {
                ResolvedTypeX onType = onTypeUnresolved.resolve(world);
                
@@ -149,7 +227,50 @@ public class SignaturePattern extends PatternNode {
                return false;
        }
 
-
+       private boolean declaringTypeMatch(Signature sig) {
+               Class onType = sig.getDeclaringType();
+               if (declaringType.matchesStatically(onType)) return true;
+               
+               Collection declaringTypes = getDeclaringTypes(sig);
+               
+               for (Iterator it = declaringTypes.iterator(); it.hasNext(); ) {
+                       Class pClass = (Class) it.next();
+                       if (declaringType.matchesStatically(pClass)) return true;
+               }
+               
+               return false;
+       }
+       
+       private Collection getDeclaringTypes(Signature sig) {
+               List l = new ArrayList();
+               Class onType = sig.getDeclaringType();
+               String memberName = sig.getName();
+               if (sig instanceof FieldSignature) {
+                       Class fieldType = ((FieldSignature)sig).getFieldType();
+                       Class superType = onType;
+                       while(superType != null) {
+                               try {
+                                       Field f =  (superType.getDeclaredField(memberName));
+                                       if (f.getType() == fieldType) {
+                                               l.add(superType);
+                                       }
+                               } catch (NoSuchFieldException nsf) {}
+                               superType = superType.getSuperclass();
+                       }
+               } else if (sig instanceof MethodSignature) {
+                       Class[] paramTypes = ((MethodSignature)sig).getParameterTypes();
+                       Class superType = onType;
+                       while(superType != null) {
+                               try {
+                                       Method m =  (superType.getDeclaredMethod(memberName,paramTypes));
+                                       l.add(superType);
+                               } catch (NoSuchMethodException nsm) {}
+                               superType = superType.getSuperclass();
+                       }
+               }
+               return l;
+       }
+       
     public NamePattern getName() { return name; }
     public TypePattern getDeclaringType() { return declaringType; }
     
index daca6f9227fd40194787c391b3c4b6d03c011457..4e8c9fc7249b95b89f2042d1d4a68a7d65739b9b 100644 (file)
@@ -18,6 +18,7 @@ import java.io.DataOutputStream;
 import java.io.IOException;
 
 import org.aspectj.bridge.IMessage;
+import org.aspectj.lang.JoinPoint;
 import org.aspectj.util.FuzzyBoolean;
 import org.aspectj.weaver.ISourceContext;
 import org.aspectj.weaver.IntMap;
@@ -67,6 +68,12 @@ public class ThisOrTargetPointcut extends NameBindingPointcut {
                return type.matches(typeToMatch.resolve(shadow.getIWorld()), TypePattern.DYNAMIC);
        }
 
+       public FuzzyBoolean match(JoinPoint jp, JoinPoint.StaticPart encJP) {
+               Object toMatch = isThis ? jp.getThis() : jp.getTarget(); 
+               if (toMatch == null) return FuzzyBoolean.NO;
+               return type.matches(toMatch.getClass(), TypePattern.DYNAMIC);
+       }
+       
        public void write(DataOutputStream s) throws IOException {
                s.writeByte(Pointcut.THIS_OR_TARGET);
                s.writeBoolean(isThis);
@@ -87,6 +94,10 @@ public class ThisOrTargetPointcut extends NameBindingPointcut {
                // ??? handle non-formal
        }
        
+       public void resolveBindingsFromRTTI() {
+               type = type.resolveBindingsFromRTTI(true,true);
+       }
+       
        public void postRead(ResolvedTypeX enclosingType) {
                type.postRead(enclosingType);
        }
index 113b900006d38db86dfb260a1cdb8703d1ffe175..dd95137ec7f1cfcf2ff23b5c26f6b31223d852c0 100644 (file)
@@ -66,6 +66,12 @@ public class ThrowsPattern extends PatternNode {
        return this;
     }
     
+    public ThrowsPattern resolveBindingsFromRTTI() {
+       required = required.resolveBindingsFromRTTI(false,false);
+       forbidden = forbidden.resolveBindingsFromRTTI(false,false);
+       return this;
+    }
+    
        public boolean matches(TypeX[] tys, World world) {
                if (this == ANY) return true;
                
@@ -85,6 +91,25 @@ public class ThrowsPattern extends PatternNode {
                }
                return true;
        }
+       
+       public boolean matches(Class[] onTypes) {
+               if (this == ANY) return true;
+               
+               //System.out.println("matching: " + this + " with " + Arrays.asList(tys));
+               
+               for (int j=0, lenj = required.size(); j < lenj; j++) {
+                       if (! matchesAny(required.get(j), onTypes)) {
+                               return false;
+                       }
+               }
+               for (int j=0, lenj = forbidden.size(); j < lenj; j++) {
+                       if (matchesAny(forbidden.get(j), onTypes)) {
+                               return false;
+                       }
+               }
+               return true;
+               
+       }
 
        private boolean matchesAny(
                TypePattern typePattern,
@@ -95,6 +120,13 @@ public class ThrowsPattern extends PatternNode {
                }
                return false;
        }
+       
+       private boolean matchesAny(TypePattern typePattern, Class[] types) {
+               for (int i = types.length - 1; i >= 0; i--) {
+                       if (typePattern.matchesStatically(types[i])) return true;       
+               }
+               return false;
+       }
 
        public static ThrowsPattern read(DataInputStream s, ISourceContext context) throws IOException {
                TypePatternList required = TypePatternList.read(s, context);
index 6c58c5c6b6aad1794e42cc5a3225a001afaaafd8..ad6b88fb401ccf4a24c2c41dfd93c776df82999d 100644 (file)
@@ -83,6 +83,51 @@ public abstract class TypePattern extends PatternNode {
        }
        
        
+       // methods for dynamic pc matching...
+       public final FuzzyBoolean matches(Class toMatch, MatchKind kind) {
+               if (kind == STATIC) {
+                       return FuzzyBoolean.fromBoolean(matchesStatically(toMatch));
+               } else if (kind == DYNAMIC) {
+                       //System.err.println("matching: " + this + " with " + type);
+                       FuzzyBoolean ret = matchesInstanceof(toMatch);
+                       //System.err.println("    got: " + ret);
+                       return ret;
+               } else {
+                       throw new IllegalArgumentException("kind must be DYNAMIC or STATIC");
+               }
+       }
+               
+       public final FuzzyBoolean matches(Object o, MatchKind kind) {
+               if (kind == STATIC) {
+                       return FuzzyBoolean.fromBoolean(matchesStatically(o.getClass()));
+               } else if (kind == DYNAMIC) {
+                       return FuzzyBoolean.fromBoolean(matchesSubtypes(o.getClass()));
+               } else {
+                       throw new IllegalArgumentException("kind must be DYNAMIC or STATIC");                   
+               }
+       }
+       
+       public boolean matchesStatically(Class toMatch) {
+               if (includeSubtypes) {
+                       return matchesSubtypes(toMatch);
+               } else {
+                       return matchesExactly(toMatch);
+               }
+       }
+       public abstract FuzzyBoolean matchesInstanceof(Class toMatch);  
+       
+       protected abstract boolean matchesExactly(Class toMatch);
+       protected boolean matchesSubtypes(Class toMatch) {
+               if (matchesExactly(toMatch)) {
+                       return true;
+               } 
+               Class superClass = toMatch.getSuperclass();
+               if (superClass != null) {
+                       return matchesSubtypes(superClass);
+               }
+               return false;
+       }
+       
        protected abstract boolean matchesExactly(ResolvedTypeX type);
        protected boolean matchesSubtypes(ResolvedTypeX type) {
                //System.out.println("matching: " + this + " to " + type);
@@ -133,6 +178,10 @@ public abstract class TypePattern extends PatternNode {
        return this;
     }
     
+    public TypePattern resolveBindingsFromRTTI(boolean allowBindng, boolean requireExactType) {
+       return this;
+    }
+    
        public void postRead(ResolvedTypeX enclosingType) {
        }
        
@@ -221,6 +270,19 @@ class EllipsisTypePattern extends TypePattern {
                return FuzzyBoolean.NO;
        }
 
+       /**
+        * @see org.aspectj.weaver.patterns.TypePattern#matchesExactly(IType)
+        */
+       protected boolean matchesExactly(Class type) {
+               return false;
+       }
+
+       /**
+        * @see org.aspectj.weaver.patterns.TypePattern#matchesInstanceof(IType)
+        */
+       public FuzzyBoolean matchesInstanceof(Class type) {
+               return FuzzyBoolean.NO;
+       }
        /**
         * @see org.aspectj.weaver.patterns.PatternNode#write(DataOutputStream)
         */
@@ -255,6 +317,19 @@ class AnyTypePattern extends TypePattern {
                return FuzzyBoolean.YES;
        }
 
+       /**
+        * @see org.aspectj.weaver.patterns.TypePattern#matchesExactly(IType)
+        */
+       protected boolean matchesExactly(Class type) {
+               return true;
+       }
+
+       /**
+        * @see org.aspectj.weaver.patterns.TypePattern#matchesInstanceof(IType)
+        */
+       public FuzzyBoolean matchesInstanceof(Class type) {
+               return FuzzyBoolean.YES;
+       }
        /**
         * @see org.aspectj.weaver.patterns.PatternNode#write(DataOutputStream)
         */
@@ -304,6 +379,19 @@ class NoTypePattern extends TypePattern {
                return FuzzyBoolean.NO;
        }
 
+       /**
+        * @see org.aspectj.weaver.patterns.TypePattern#matchesExactly(IType)
+        */
+       protected boolean matchesExactly(Class type) {
+               return false;
+       }
+
+       /**
+        * @see org.aspectj.weaver.patterns.TypePattern#matchesInstanceof(IType)
+        */
+       public FuzzyBoolean matchesInstanceof(Class type) {
+               return FuzzyBoolean.NO;
+       }
        /**
         * @see org.aspectj.weaver.patterns.PatternNode#write(DataOutputStream)
         */
index dc4979e30bff7f2b3e16bb24498b65b0796c8559..25111cf15f4d95e12bc0187d7ce6b472d7221966 100644 (file)
@@ -122,6 +122,86 @@ public class TypePatternList extends PatternNode {
             return b;
        }
     }
+    
+    
+    // TODO Add TypePatternList.matches(Object[] objs)
+    public FuzzyBoolean matches(Object[] objs, TypePattern.MatchKind kind) {
+       int nameLength = objs.length;
+               int patternLength = typePatterns.length;
+               
+               int nameIndex = 0;
+               int patternIndex = 0;
+               
+               if (ellipsisCount == 0) {
+                       if (nameLength != patternLength) return FuzzyBoolean.NO;
+                       FuzzyBoolean finalReturn = FuzzyBoolean.YES;
+                       while (patternIndex < patternLength) {
+                               FuzzyBoolean ret = typePatterns[patternIndex++].matches(objs[nameIndex++],kind);
+                               if (ret == FuzzyBoolean.NO) return ret;
+                               if (ret == FuzzyBoolean.MAYBE) finalReturn = ret;
+                       }
+                       return finalReturn;
+               } else if (ellipsisCount == 1) {
+                       if (nameLength < patternLength-1) return FuzzyBoolean.NO;
+                       FuzzyBoolean finalReturn = FuzzyBoolean.YES;
+                       while (patternIndex < patternLength) {
+                               TypePattern p = typePatterns[patternIndex++];
+                               if (p == TypePattern.ELLIPSIS) {
+                                       nameIndex = nameLength - (patternLength-patternIndex);
+                               } else {
+                                       FuzzyBoolean ret = p.matches(objs[nameIndex++],kind);
+                                   if (ret == FuzzyBoolean.NO) return ret;
+                                   if (ret == FuzzyBoolean.MAYBE) finalReturn = ret;
+                               }
+                       }
+                       return finalReturn;
+               } else {
+//            System.err.print("match(" + arguments + ", " + types + ") -> ");
+            FuzzyBoolean b =  outOfStar(typePatterns, objs, 0, 0, patternLength - ellipsisCount, nameLength, ellipsisCount, kind);
+//            System.err.println(b);
+            return b;
+       }
+    }
+    // XXX run-time signature matching, too much duplicated code
+    public FuzzyBoolean matches(Class[] types, TypePattern.MatchKind kind) {
+       int nameLength = types.length;
+               int patternLength = typePatterns.length;
+               
+               int nameIndex = 0;
+               int patternIndex = 0;
+               
+               if (ellipsisCount == 0) {
+                       if (nameLength != patternLength) return FuzzyBoolean.NO;
+                       FuzzyBoolean finalReturn = FuzzyBoolean.YES;
+                       while (patternIndex < patternLength) {
+                               FuzzyBoolean ret = typePatterns[patternIndex++].matches(types[nameIndex++], kind);
+                               if (ret == FuzzyBoolean.NO) return ret;
+                               if (ret == FuzzyBoolean.MAYBE) finalReturn = ret;
+                       }
+                       return finalReturn;
+               } else if (ellipsisCount == 1) {
+                       if (nameLength < patternLength-1) return FuzzyBoolean.NO;
+                       FuzzyBoolean finalReturn = FuzzyBoolean.YES;
+                       while (patternIndex < patternLength) {
+                               TypePattern p = typePatterns[patternIndex++];
+                               if (p == TypePattern.ELLIPSIS) {
+                                       nameIndex = nameLength - (patternLength-patternIndex);
+                               } else {
+                                       FuzzyBoolean ret = p.matches(types[nameIndex++], kind);
+                                   if (ret == FuzzyBoolean.NO) return ret;
+                                   if (ret == FuzzyBoolean.MAYBE) finalReturn = ret;
+                               }
+                       }
+                       return finalReturn;
+               } else {
+//            System.err.print("match(" + arguments + ", " + types + ") -> ");
+            FuzzyBoolean b =  outOfStar(typePatterns, types, 0, 0, patternLength - ellipsisCount, nameLength, ellipsisCount, kind);
+//            System.err.println(b);
+            return b;
+       }
+    }
+    
     private static FuzzyBoolean outOfStar(final TypePattern[] pattern, final ResolvedTypeX[] target, 
                                                   int           pi,            int    ti, 
                                                   int           pLeft,         int    tLeft,
@@ -168,6 +248,130 @@ public class TypePatternList extends PatternNode {
             ti++; tLeft--;
         }
     }
+
+    
+    
+    private static FuzzyBoolean outOfStar(final TypePattern[] pattern,
+                       final Class[] target, int pi, int ti, int pLeft, int tLeft,
+                       final int starsLeft, TypePattern.MatchKind kind) {
+               if (pLeft > tLeft)
+                       return FuzzyBoolean.NO;
+               FuzzyBoolean finalReturn = FuzzyBoolean.YES;
+               while (true) {
+                       // invariant: if (tLeft > 0) then (ti < target.length && pi <
+                       // pattern.length)
+                       if (tLeft == 0)
+                               return finalReturn;
+                       if (pLeft == 0) {
+                               if (starsLeft > 0) {
+                                       return finalReturn;
+                               } else {
+                                       return FuzzyBoolean.NO;
+                               }
+                       }
+                       if (pattern[pi] == TypePattern.ELLIPSIS) {
+                               return inStar(pattern, target, pi + 1, ti, pLeft, tLeft,
+                                               starsLeft - 1, kind);
+                       }
+                       FuzzyBoolean ret = pattern[pi].matches(target[ti], kind);
+                       if (ret == FuzzyBoolean.NO)
+                               return ret;
+                       if (ret == FuzzyBoolean.MAYBE)
+                               finalReturn = ret;
+                       pi++;
+                       ti++;
+                       pLeft--;
+                       tLeft--;
+               }
+       }       
+  
+    private static FuzzyBoolean inStar(final TypePattern[] pattern,
+                       final Class[] target, int pi, int ti, final int pLeft,
+                       int tLeft, int starsLeft, TypePattern.MatchKind kind) {
+               // invariant: pLeft > 0, so we know we'll run out of stars and find a
+               // real char in pattern
+               TypePattern patternChar = pattern[pi];
+               while (patternChar == TypePattern.ELLIPSIS) {
+                       starsLeft--;
+                       patternChar = pattern[++pi];
+               }
+               while (true) {
+                       // invariant: if (tLeft > 0) then (ti < target.length)
+                       if (pLeft > tLeft)
+                               return FuzzyBoolean.NO;
+                       FuzzyBoolean ff = patternChar.matches(target[ti], kind);
+                       if (ff.maybeTrue()) {
+                               FuzzyBoolean xx = outOfStar(pattern, target, pi + 1, ti + 1,
+                                               pLeft - 1, tLeft - 1, starsLeft, kind);
+                               if (xx.maybeTrue())
+                                       return ff.and(xx);
+                       }
+                       ti++;
+                       tLeft--;
+               }
+       }
+
+    private static FuzzyBoolean outOfStar(final TypePattern[] pattern,
+                       final Object[] target, int pi, int ti, int pLeft, int tLeft,
+                       final int starsLeft, TypePattern.MatchKind kind) {
+               if (pLeft > tLeft)
+                       return FuzzyBoolean.NO;
+               FuzzyBoolean finalReturn = FuzzyBoolean.YES;
+               while (true) {
+                       // invariant: if (tLeft > 0) then (ti < target.length && pi <
+                       // pattern.length)
+                       if (tLeft == 0)
+                               return finalReturn;
+                       if (pLeft == 0) {
+                               if (starsLeft > 0) {
+                                       return finalReturn;
+                               } else {
+                                       return FuzzyBoolean.NO;
+                               }
+                       }
+                       if (pattern[pi] == TypePattern.ELLIPSIS) {
+                               return inStar(pattern, target, pi + 1, ti, pLeft, tLeft,
+                                               starsLeft - 1,kind);
+                       }
+                       FuzzyBoolean ret = pattern[pi].matches(target[ti],kind);
+                       if (ret == FuzzyBoolean.NO)
+                               return ret;
+                       if (ret == FuzzyBoolean.MAYBE)
+                               finalReturn = ret;
+                       pi++;
+                       ti++;
+                       pLeft--;
+                       tLeft--;
+               }
+       }       
+  
+    private static FuzzyBoolean inStar(final TypePattern[] pattern,
+                       final Object[] target, int pi, int ti, final int pLeft,
+                       int tLeft, int starsLeft, TypePattern.MatchKind kind) {
+               // invariant: pLeft > 0, so we know we'll run out of stars and find a
+               // real char in pattern
+               TypePattern patternChar = pattern[pi];
+               while (patternChar == TypePattern.ELLIPSIS) {
+                       starsLeft--;
+                       patternChar = pattern[++pi];
+               }
+               while (true) {
+                       // invariant: if (tLeft > 0) then (ti < target.length)
+                       if (pLeft > tLeft)
+                               return FuzzyBoolean.NO;
+                       FuzzyBoolean ff = patternChar.matches(target[ti],kind);
+                       if (ff.maybeTrue()) {
+                               FuzzyBoolean xx = outOfStar(pattern, target, pi + 1, ti + 1,
+                                               pLeft - 1, tLeft - 1, starsLeft,kind);
+                               if (xx.maybeTrue())
+                                       return ff.and(xx);
+                       }
+                       ti++;
+                       tLeft--;
+               }
+       }
+  
+
     
        public TypePatternList resolveBindings(IScope scope, Bindings bindings, boolean allowBinding, boolean requireExactType) {
                for (int i=0; i<typePatterns.length; i++) {
@@ -179,6 +383,16 @@ public class TypePatternList extends PatternNode {
                return this;
        }
        
+       public TypePatternList resolveBindingsFromRTTI(boolean allowBinding, boolean requireExactType) {
+               for (int i=0; i<typePatterns.length; i++) {
+                       TypePattern p = typePatterns[i];
+                       if (p != null) {
+                               typePatterns[i] = typePatterns[i].resolveBindingsFromRTTI(allowBinding, requireExactType);
+                       }
+               }
+               return this;            
+       }
+       
        public TypePatternList resolveReferences(IntMap bindings) {
                int len = typePatterns.length;
                TypePattern[] ret = new TypePattern[len];
index e6003191d1daa995cfc2396b5e301f344ecbb767..61c778358b81af3d29e802a67d6aac774622cd51 100644 (file)
@@ -82,6 +82,14 @@ public class WildTypePattern extends TypePattern {
                
                //System.err.println("match: " + targetTypeName + ", " + knownMatches); //Arrays.asList(importedPrefixes));
                
+               return matchesExactlyByName(targetTypeName);
+       }
+
+    /**
+        * @param targetTypeName
+        * @return
+        */
+       private boolean matchesExactlyByName(String targetTypeName) {
                //XXX hack
                if (knownMatches == null && importedPrefixes == null) {
                        return innerMatchesExactly(targetTypeName);
@@ -122,7 +130,7 @@ public class WildTypePattern extends TypePattern {
                return innerMatchesExactly(targetTypeName);
        }
 
-    private int lastIndexOfDotOrDollar(String string) {
+       private int lastIndexOfDotOrDollar(String string) {
        int dot = string.lastIndexOf('.');
        int dollar = string.lastIndexOf('$');
        return Math.max(dot, dollar);
@@ -370,6 +378,53 @@ public class WildTypePattern extends TypePattern {
                return this;
        }
        
+       public TypePattern resolveBindingsFromRTTI(boolean allowBinding, boolean requireExactType) {
+               if (isStar()) {
+                       return TypePattern.ANY;  //??? loses source location
+               }
+
+               String cleanName = maybeGetCleanName();
+               if (cleanName != null) {
+                       Class clazz = null;
+
+                       while (clazz == null) {
+                               try {
+                                       clazz = Class.forName(cleanName);
+                               } catch (ClassNotFoundException cnf) {
+                                       int lastDotIndex = cleanName.lastIndexOf('.');
+                                       if (lastDotIndex == -1) break;
+                                       cleanName = cleanName.substring(0, lastDotIndex) + '$' + cleanName.substring(lastDotIndex+1);
+                               }
+                       }
+                       
+                       if (clazz == null) {
+                               try {
+                                       clazz = Class.forName("java.lang." + cleanName);
+                               } catch (ClassNotFoundException cnf) {
+                               }
+                       }
+
+                       if (clazz == null) {
+                               if (requireExactType) {
+                                       return NO;
+                               }
+                       } else {
+                               TypeX type = TypeX.forName(clazz.getName());
+                               if (dim != 0) type = TypeX.makeArray(type,dim);
+                               TypePattern ret = new ExactTypePattern(type, includeSubtypes);
+                               ret.copyLocationFrom(this);
+                               return ret;
+                       }
+               } else if (requireExactType) {
+                       return NO;
+               }
+                                       
+               importedPrefixes = SimpleScope.javaLangPrefixArray;
+               knownMatches = new String[0];
+               
+               return this;    
+       }
+       
        public boolean isStar() {
                return namePatterns.length == 1 && namePatterns[0].isAny();
        }
@@ -429,6 +484,15 @@ public class WildTypePattern extends TypePattern {
         }
         return result;
     }
+
+    
+    public FuzzyBoolean matchesInstanceof(Class type) {
+       return FuzzyBoolean.NO;
+    }
+    
+    public boolean matchesExactly(Class type) {
+       return matchesExactlyByName(type.getName());
+    }
     
        /**
         * @see org.aspectj.weaver.patterns.PatternNode#write(DataOutputStream)
index 14267da073c41af836a8e9f89b3be4c36db23467..d0acd286be86e2fafa33b7c26069cac0a6db9810 100644 (file)
@@ -17,6 +17,7 @@ import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
 
+import org.aspectj.lang.JoinPoint;
 import org.aspectj.util.FuzzyBoolean;
 import org.aspectj.weaver.ISourceContext;
 import org.aspectj.weaver.IntMap;
@@ -51,6 +52,21 @@ public class WithinPointcut extends Pointcut {
                return isWithinType(enclosingType);
        }
 
+       public FuzzyBoolean match(JoinPoint jp, JoinPoint.StaticPart encJp) {
+               return isWithinType(encJp.getSignature().getDeclaringType());
+       }
+               
+       private FuzzyBoolean isWithinType(Class type) {
+               while (type != null) {
+                       if (typePattern.matchesStatically(type)) {
+                               return FuzzyBoolean.YES;
+                       } 
+                       type = type.getDeclaringClass();
+               }               
+               return FuzzyBoolean.NO;
+       }
+
+       
        public void write(DataOutputStream s) throws IOException {
                s.writeByte(Pointcut.WITHIN);
                typePattern.write(s);
@@ -67,6 +83,10 @@ public class WithinPointcut extends Pointcut {
                typePattern = typePattern.resolveBindings(scope, bindings, false, false);
        }
 
+       public void resolveBindingsFromRTTI() {
+               typePattern = typePattern.resolveBindingsFromRTTI(false,false);
+       }
+       
        public void postRead(ResolvedTypeX enclosingType) {
                typePattern.postRead(enclosingType);
        }
index f30329bb240f2bd7c5c3592217b9c88638a4ec75..c666d53ac4fd5ccf0bdaa20134c1e5e471db2084 100644 (file)
@@ -17,6 +17,7 @@ import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
 
+import org.aspectj.lang.JoinPoint;
 import org.aspectj.util.FuzzyBoolean;
 import org.aspectj.weaver.ISourceContext;
 import org.aspectj.weaver.IntMap;
@@ -43,6 +44,10 @@ public class WithincodePointcut extends Pointcut {
                        signature.matches(shadow.getEnclosingCodeSignature(), shadow.getIWorld()));
        }
 
+       public FuzzyBoolean match(JoinPoint jp, JoinPoint.StaticPart encJP) {
+               return FuzzyBoolean.fromBoolean(signature.matches(encJP));
+       }
+       
        public void write(DataOutputStream s) throws IOException {
                s.writeByte(Pointcut.WITHINCODE);
                signature.write(s);
@@ -58,6 +63,10 @@ public class WithincodePointcut extends Pointcut {
        public void resolveBindings(IScope scope, Bindings bindings) {
                signature = signature.resolveBindings(scope, bindings);
        }
+       
+       public void resolveBindingsFromRTTI() {
+               signature = signature.resolveBindingsFromRTTI();
+       }
 
        public void postRead(ResolvedTypeX enclosingType) {
                signature.postRead(enclosingType);
index 26d8e120788aab71a95e444fbd494bae015cd829..45f9b59d5d71cda074f056854fe71d4491bd5fe8 100644 (file)
@@ -15,6 +15,10 @@ package org.aspectj.weaver.patterns;
 
 import java.io.*;
 
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.Signature;
+import org.aspectj.runtime.reflect.Factory;
+import org.aspectj.util.FuzzyBoolean;
 import org.aspectj.weaver.bcel.*;
 
 import junit.framework.TestCase;
@@ -65,6 +69,31 @@ public class AndOrNotTestCase extends TestCase {
                checkEquals("!!this(Foo)", new NotPointcut(new NotPointcut(foo)));
                
        }
+       
+       public void testJoinPointMatch() {
+               Pointcut foo = makePointcut("this(org.aspectj.weaver.patterns.AndOrNotTestCase.Foo)").resolve();
+               Pointcut bar = makePointcut("this(org.aspectj.weaver.patterns.AndOrNotTestCase.Bar)").resolve();
+               Pointcut c   = makePointcut("this(org.aspectj.weaver.patterns.AndOrNotTestCase.C)").resolve();
+               
+               Factory f = new Factory("AndOrNotTestCase.java",AndOrNotTestCase.class);
+               
+               Signature methodSig = f.makeMethodSig("void aMethod()");
+               JoinPoint.StaticPart jpsp = f.makeSJP(JoinPoint.METHOD_EXECUTION,methodSig,1);
+               JoinPoint jp = Factory.makeJP(jpsp,new Foo(),new Foo());
+               
+               checkMatches(new AndPointcut(foo,bar),jp,null,FuzzyBoolean.NO);
+               checkMatches(new AndPointcut(foo,foo),jp,null,FuzzyBoolean.YES);
+               checkMatches(new AndPointcut(bar,foo),jp,null,FuzzyBoolean.NO);
+               checkMatches(new AndPointcut(bar,c),jp,null,FuzzyBoolean.NO);
+               
+               checkMatches(new OrPointcut(foo,bar),jp,null,FuzzyBoolean.YES);
+               checkMatches(new OrPointcut(foo,foo),jp,null,FuzzyBoolean.YES);
+               checkMatches(new OrPointcut(bar,foo),jp,null,FuzzyBoolean.YES);
+               checkMatches(new OrPointcut(bar,c),jp,null,FuzzyBoolean.NO);
+               
+               checkMatches(new NotPointcut(foo),jp,null,FuzzyBoolean.NO);
+               checkMatches(new NotPointcut(bar),jp,null,FuzzyBoolean.YES);
+       }
 
        private Pointcut makePointcut(String pattern) {
                return new PatternParser(pattern).parsePointcut();
@@ -75,6 +104,9 @@ public class AndOrNotTestCase extends TestCase {
                checkSerialization(pattern);
        }
 
+       private void checkMatches(Pointcut p, JoinPoint jp, JoinPoint.StaticPart jpsp, FuzzyBoolean expected) {
+               assertEquals(expected,p.match(jp,jpsp));
+       }
        
 //     private void checkMatch(Pointcut p, Signature[] matches, boolean shouldMatch) {
 //             for (int i=0; i<matches.length; i++) {
@@ -116,4 +148,8 @@ public class AndOrNotTestCase extends TestCase {
                assertEquals("write/read", p, newP);    
        }
        
+       private static class Foo{};
+       private static class Bar{};
+       private static class C{};
+       
 }
diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/ArgsTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/ArgsTestCase.java
new file mode 100644 (file)
index 0000000..92c27f0
--- /dev/null
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * 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
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.aspectj.weaver.patterns;
+
+import junit.framework.TestCase;
+
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.runtime.reflect.Factory;
+import org.aspectj.util.FuzzyBoolean;
+
+/**
+ * @author colyer
+ *
+ * TODO To change the template for this generated type comment go to
+ * Window - Preferences - Java - Code Generation - Code and Comments
+ */
+public class ArgsTestCase extends TestCase {
+       
+       Pointcut wildcardArgs;
+       Pointcut oneA;
+       Pointcut oneAandaC;
+       Pointcut BthenAnything;
+       Pointcut singleArg;
+       
+       public void testMatchJP() {
+               Factory f = new Factory("ArgsTestCase.java",ArgsTestCase.A.class);
+               
+               JoinPoint.StaticPart jpsp1 = f.makeSJP(JoinPoint.METHOD_EXECUTION,f.makeMethodSig(0,"aMethod",A.class,new Class[] {A.class},new String[] {"a"},new Class[] {},null) ,1);
+               JoinPoint.StaticPart jpsp2 = f.makeSJP(JoinPoint.METHOD_EXECUTION,f.makeMethodSig(0,"aMethod",A.class,new Class[] {B.class},new String[] {"b"},new Class[] {},null),1);
+               JoinPoint.StaticPart jpsp3 = f.makeSJP(JoinPoint.METHOD_EXECUTION,f.makeMethodSig(0,"aMethod",A.class,new Class[] {A.class,C.class},new String[] {"a","c"},new Class[] {},null),1);
+               JoinPoint.StaticPart jpsp4 = f.makeSJP(JoinPoint.METHOD_EXECUTION,f.makeMethodSig(0,"aMethod",A.class,new Class[] {A.class,A.class},new String[] {"a","a2"},new Class[] {},null),1);
+               JoinPoint oneAArg = Factory.makeJP(jpsp1,new A(),new A(),new A());
+               JoinPoint oneBArg = Factory.makeJP(jpsp2,new A(), new A(), new B());
+               JoinPoint acArgs = Factory.makeJP(jpsp3,new A(), new A(), new A(), new C());
+               JoinPoint baArgs = Factory.makeJP(jpsp4,new A(), new A(), new B(), new A());
+               
+               checkMatches(wildcardArgs,oneAArg,null,FuzzyBoolean.YES);
+               checkMatches(wildcardArgs,oneBArg,null,FuzzyBoolean.YES);
+               checkMatches(wildcardArgs,acArgs,null,FuzzyBoolean.YES);
+               checkMatches(wildcardArgs,baArgs,null,FuzzyBoolean.YES);
+               
+               checkMatches(oneA,oneAArg,null,FuzzyBoolean.YES);
+               checkMatches(oneA,oneBArg,null,FuzzyBoolean.YES);
+               checkMatches(oneA,acArgs,null,FuzzyBoolean.NO);
+               checkMatches(oneA,baArgs,null,FuzzyBoolean.NO);
+
+               checkMatches(oneAandaC,oneAArg,null,FuzzyBoolean.NO);
+               checkMatches(oneAandaC,oneBArg,null,FuzzyBoolean.NO);
+               checkMatches(oneAandaC,acArgs,null,FuzzyBoolean.YES);
+               checkMatches(oneAandaC,baArgs,null,FuzzyBoolean.NO);
+               
+               checkMatches(BthenAnything,oneAArg,null,FuzzyBoolean.NO);
+               checkMatches(BthenAnything,oneBArg,null,FuzzyBoolean.YES);
+               checkMatches(BthenAnything,acArgs,null,FuzzyBoolean.NO);
+               checkMatches(BthenAnything,baArgs,null,FuzzyBoolean.YES);
+
+               checkMatches(singleArg,oneAArg,null,FuzzyBoolean.YES);
+               checkMatches(singleArg,oneBArg,null,FuzzyBoolean.YES);
+               checkMatches(singleArg,acArgs,null,FuzzyBoolean.NO);
+               checkMatches(singleArg,baArgs,null,FuzzyBoolean.NO);
+
+       }
+       
+       private void checkMatches(Pointcut p, JoinPoint jp, JoinPoint.StaticPart jpsp, FuzzyBoolean expected) {
+               assertEquals(expected,p.match(jp,jpsp));
+       }
+       
+       private static class A {};
+       private static class B extends A {};
+       private static class C {};
+
+       /* (non-Javadoc)
+        * @see junit.framework.TestCase#setUp()
+        */
+       protected void setUp() throws Exception {
+               super.setUp();
+               wildcardArgs = new PatternParser("args(..)").parsePointcut().resolve();
+               oneA = new PatternParser("args(org.aspectj.weaver.patterns.ArgsTestCase.A)").parsePointcut().resolve();
+               oneAandaC = new PatternParser("args(org.aspectj.weaver.patterns.ArgsTestCase.A,org.aspectj.weaver.patterns.ArgsTestCase.C)").parsePointcut().resolve();
+               BthenAnything = new PatternParser("args(org.aspectj.weaver.patterns.ArgsTestCase.B,..)").parsePointcut().resolve();
+               singleArg = new PatternParser("args(*)").parsePointcut().resolve();
+       }
+}
diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/HandlerTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/HandlerTestCase.java
new file mode 100644 (file)
index 0000000..9238f8b
--- /dev/null
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * 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
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.aspectj.weaver.patterns;
+
+import java.io.IOException;
+
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.runtime.reflect.Factory;
+import org.aspectj.util.FuzzyBoolean;
+
+import junit.framework.TestCase;
+
+
+public class HandlerTestCase extends TestCase {
+
+       private Pointcut hEx;
+       private Pointcut hExPlus;
+       private Pointcut hIOEx;
+       
+       public void testHandlerMatch() {
+               Factory f = new Factory("HandlerTestCase.java",HandlerTestCase.class);
+               
+               JoinPoint.StaticPart jpsp1 = f.makeSJP(JoinPoint.EXCEPTION_HANDLER,f.makeCatchClauseSig(HandlerTestCase.class,Exception.class,"ex"),1);
+               JoinPoint ex = Factory.makeJP(jpsp1,this,this,new Exception());
+               JoinPoint ioex = Factory.makeJP(jpsp1,this,this,new IOException());
+               JoinPoint myex = Factory.makeJP(jpsp1,this,this,new MyException());
+               
+               checkMatches(hEx,ex,null,FuzzyBoolean.YES);
+               checkMatches(hEx,ioex,null,FuzzyBoolean.NO);
+               checkMatches(hEx,myex,null,FuzzyBoolean.NO);
+
+               checkMatches(hExPlus,ex,null,FuzzyBoolean.YES);
+               checkMatches(hExPlus,ioex,null,FuzzyBoolean.YES);
+               checkMatches(hExPlus,myex,null,FuzzyBoolean.YES);
+
+               checkMatches(hIOEx,ex,null,FuzzyBoolean.NO);
+               checkMatches(hIOEx,ioex,null,FuzzyBoolean.YES);
+               checkMatches(hIOEx,myex,null,FuzzyBoolean.NO);
+
+       }
+       
+       private void checkMatches(Pointcut p, JoinPoint jp, JoinPoint.StaticPart jpsp, FuzzyBoolean expected) {
+               assertEquals(expected,p.match(jp,jpsp));
+       }
+       
+       private static class MyException extends Exception {}
+       
+       /* (non-Javadoc)
+        * @see junit.framework.TestCase#setUp()
+        */
+       protected void setUp() throws Exception {
+               super.setUp();
+               hEx = new PatternParser("handler(Exception)").parsePointcut().resolve();
+               hExPlus = new PatternParser("handler(Exception+)").parsePointcut().resolve();
+               hIOEx = new PatternParser("handler(java.io.IOException)").parsePointcut().resolve();
+       }
+}
diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/KindedTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/KindedTestCase.java
new file mode 100644 (file)
index 0000000..0da7916
--- /dev/null
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * 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
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.aspectj.weaver.patterns;
+
+import java.lang.reflect.Modifier;
+
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.runtime.reflect.Factory;
+import org.aspectj.util.FuzzyBoolean;
+
+import junit.framework.TestCase;
+
+/**
+ * @author colyer
+ *
+ * TODO To change the template for this generated type comment go to
+ * Window - Preferences - Java - Code Generation - Code and Comments
+ */
+public class KindedTestCase extends TestCase {
+       
+       Pointcut callpc;
+       Pointcut exepc;
+       Pointcut exepcplus;
+       Pointcut exepcCons;
+       Pointcut adviceexepc;
+       Pointcut initpc;
+       Pointcut preinitpc;
+       Pointcut staticinitpc;
+       Pointcut getpc;
+       Pointcut setpc;
+       
+       public void testKindedMatch() {
+               Factory f = new Factory("KindedTestCase.java",KindedTestCase.class);
+               
+               // JoinPoints to match against...
+               JoinPoint.StaticPart calljp1 = f.makeSJP(JoinPoint.METHOD_CALL,f.makeMethodSig(0,"main",Hello.class,new Class[] {String.class},new String[] {"s"},new Class[0],String.class),1);
+               JoinPoint.StaticPart calljp2 = f.makeSJP(JoinPoint.METHOD_CALL,f.makeMethodSig(0,"sayHi",Hello.class,new Class[] {String.class},new String[] {"s"},new Class[0],String.class),1);
+               JoinPoint.StaticPart exejp1 = f.makeSJP(JoinPoint.METHOD_EXECUTION,f.makeMethodSig(0,"main",Hello.class,new Class[] {String.class},new String[] {"s"},new Class[0],String.class),1);
+               JoinPoint.StaticPart exejp2 = f.makeSJP(JoinPoint.METHOD_EXECUTION,f.makeMethodSig(0,"sayHi",Hello.class,new Class[] {String.class},new String[] {"s"},new Class[0],void.class),1);
+               JoinPoint.StaticPart execonsjp1 = f.makeSJP(JoinPoint.CONSTRUCTOR_EXECUTION,f.makeConstructorSig(0,Hello.class,new Class[0],new String[0],new Class[0]),1);
+               JoinPoint.StaticPart execonsjp2 = f.makeSJP(JoinPoint.CONSTRUCTOR_EXECUTION,f.makeConstructorSig(0,String.class,new Class[] {String.class},new String[]{"s"},new Class[0]),1);
+               JoinPoint.StaticPart initjp1 = f.makeSJP(JoinPoint.INITIALIZATION,f.makeConstructorSig(0,Hello.class,new Class[0],new String[0],new Class[0]),1);
+               JoinPoint.StaticPart initjp2 = f.makeSJP(JoinPoint.PREINTIALIZATION,f.makeConstructorSig(0,Hello.class,new Class[]{int.class, int.class},new String[]{"a","b"},new Class[0]),1);
+               JoinPoint.StaticPart sinitjp1 = f.makeSJP(JoinPoint.STATICINITIALIZATION,f.makeInitializerSig(Modifier.STATIC,Hello.class),1);
+               JoinPoint.StaticPart sinitjp2 = f.makeSJP(JoinPoint.STATICINITIALIZATION,f.makeInitializerSig(Modifier.STATIC,String.class),1);
+               JoinPoint.StaticPart getjp1 = f.makeSJP(JoinPoint.FIELD_GET,f.makeFieldSig(0,"x",Hello.class,int.class),1);
+               JoinPoint.StaticPart getjp2 = f.makeSJP(JoinPoint.FIELD_GET,f.makeFieldSig(0,"y",String.class,String.class),1);
+               JoinPoint.StaticPart setjp1 = f.makeSJP(JoinPoint.FIELD_SET,f.makeFieldSig(0,"x",Hello.class,int.class),1);
+               JoinPoint.StaticPart setjp2 = f.makeSJP(JoinPoint.FIELD_SET,f.makeFieldSig(0,"y",String.class,String.class),1);
+               JoinPoint.StaticPart advjp = f.makeSJP(JoinPoint.ADVICE_EXECUTION,f.makeAdviceSig(0,"foo",Hello.class,new Class[0],new String[0],new Class[0],void.class),1);
+               
+               checkMatches(callpc,calljp1,FuzzyBoolean.YES);
+               checkMatches(callpc,calljp2,FuzzyBoolean.NO);
+               checkMatches(callpc,exejp1,FuzzyBoolean.NO);
+               checkMatches(exepc,exejp1,FuzzyBoolean.NO);
+               checkMatches(exepc,exejp2,FuzzyBoolean.YES);
+               checkMatches(exepcplus,exejp1,FuzzyBoolean.NO);
+               checkMatches(exepcplus,exejp2,FuzzyBoolean.YES);
+               checkMatches(exepcCons,execonsjp1,FuzzyBoolean.YES);
+               checkMatches(exepcCons,execonsjp2,FuzzyBoolean.NO);
+               checkMatches(exepcCons,exejp1,FuzzyBoolean.NO);
+               checkMatches(initpc,initjp1,FuzzyBoolean.YES);
+               checkMatches(initpc,initjp2,FuzzyBoolean.NO);
+               checkMatches(preinitpc,initjp1,FuzzyBoolean.NO);
+               checkMatches(preinitpc,initjp2,FuzzyBoolean.YES);
+               checkMatches(staticinitpc,sinitjp1,FuzzyBoolean.YES);
+               checkMatches(staticinitpc,sinitjp2,FuzzyBoolean.NO);
+               checkMatches(getpc,getjp1,FuzzyBoolean.YES);
+               checkMatches(getpc,getjp2,FuzzyBoolean.YES);
+               checkMatches(setpc,setjp1,FuzzyBoolean.YES);
+               checkMatches(setpc,setjp2,FuzzyBoolean.NO);
+               checkMatches(adviceexepc,advjp,FuzzyBoolean.YES);
+       }
+       
+       private void checkMatches(Pointcut p, JoinPoint.StaticPart jpsp, FuzzyBoolean expected) {
+               assertEquals(expected,p.match(jpsp));
+       }
+       
+       protected void setUp() throws Exception {
+               super.setUp();
+               callpc = new PatternParser("call(* main(..))").parsePointcut().resolve();
+               exepc = new PatternParser("execution(void org.aspectj.weaver.patterns.KindedTestCase.Hello.sayHi(String))").parsePointcut().resolve();
+               exepcplus = new PatternParser("execution(void Object+.sayHi(String))").parsePointcut().resolve();
+               exepcCons = new PatternParser("execution(org.aspectj.weaver.patterns.KindedTestCase.Hello.new(..))").parsePointcut().resolve();
+               initpc = new PatternParser("initialization(new(..))").parsePointcut().resolve();
+               preinitpc = new PatternParser("preinitialization(*..H*.new(int,int))").parsePointcut().resolve();
+               staticinitpc = new PatternParser("staticinitialization(org.aspectj.weaver.patterns.KindedTestCase.Hello)").parsePointcut().resolve();
+               getpc = new PatternParser("get(* *)").parsePointcut().resolve();
+               setpc = new PatternParser("set(int x)").parsePointcut().resolve();
+               adviceexepc = new PatternParser("adviceexecution()").parsePointcut().resolve();
+       }
+       
+       private static class Hello {};
+}
index 9c0b672d7c48a22705032c005071790a36cd94b3..c9f986d071ef046411e763713ca4cc06adbf0153 100644 (file)
@@ -32,6 +32,11 @@ public class PatternsTests extends TestCase {
         suite.addTestSuite(TypePatternListTestCase.class); 
         suite.addTestSuite(TypePatternTestCase.class); 
         suite.addTestSuite(WithinTestCase.class); 
+        suite.addTestSuite(PointcutTestCase.class);
+        suite.addTestSuite(ArgsTestCase.class);
+        suite.addTestSuite(HandlerTestCase.class);
+        suite.addTestSuite(KindedTestCase.class);
+        suite.addTestSuite(WithinCodeTestCase.class);
         //$JUnit-END$
         return suite;
     }
diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/PointcutTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/PointcutTestCase.java
new file mode 100644 (file)
index 0000000..a640a07
--- /dev/null
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * 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
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.aspectj.weaver.patterns;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.Signature;
+import org.aspectj.runtime.reflect.Factory;
+import org.aspectj.util.FuzzyBoolean;
+import org.aspectj.weaver.IntMap;
+import org.aspectj.weaver.ResolvedTypeX;
+import org.aspectj.weaver.Shadow;
+import org.aspectj.weaver.ast.Test;
+
+import junit.framework.TestCase;
+
+
+public class PointcutTestCase extends TestCase {
+       
+       public void testMatchJP() {
+               Pointcut p = new Pointcut() {
+
+                       public FuzzyBoolean fastMatch(FastMatchInfo info) {
+                               return null;
+                       }
+
+                       public FuzzyBoolean match(Shadow shadow) {
+                               return null;
+                       }
+
+                       protected void resolveBindings(IScope scope, Bindings bindings) {
+                       }
+                       
+                       protected void resolveBindingsFromRTTI() {}
+
+                       protected Pointcut concretize1(ResolvedTypeX inAspect, IntMap bindings) {
+                               return null;
+                       }
+
+                       public Test findResidue(Shadow shadow, ExposedState state) {
+                               return null;
+                       }
+
+                       public void write(DataOutputStream s) throws IOException {
+                       }};
+               
+               Factory f = new Factory("PointcutTestCase.java",PointcutTestCase.class);
+                       
+               Signature methodSig = f.makeMethodSig("void aMethod()");
+               JoinPoint.StaticPart jpsp = f.makeSJP(JoinPoint.METHOD_EXECUTION,methodSig,1);
+               JoinPoint jp = Factory.makeJP(jpsp,this,this);
+               
+               try {
+                       p.match(jp,null);
+                       fail("Expected UnsupportedOperationException to be thrown");
+               } catch (UnsupportedOperationException unEx) {
+                       // ok
+               }
+               
+               try {
+                       p.match(jpsp);
+                       fail("Expected UnsupportedOperationException to be thrown");
+               } catch (UnsupportedOperationException unEx) {
+                       // ok
+               }
+               
+       }
+       
+}
index da8f3eecb37c3e76f616303958158248aa1e03d3..31794bcfe06325f101d3b5aa7a7cc49bb3939800 100644 (file)
@@ -15,6 +15,9 @@ package org.aspectj.weaver.patterns;
 
 import java.io.*;
 
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.runtime.reflect.Factory;
+import org.aspectj.util.FuzzyBoolean;
 import org.aspectj.weaver.bcel.*;
 
 import junit.framework.TestCase;
@@ -46,6 +49,46 @@ public class ThisOrTargetTestCase extends TestCase {
 
                
        }
+       
+       public void testMatchJP() {
+               Factory f = new Factory("ThisOrTargetTestCase.java",ThisOrTargetTestCase.class);
+               
+               Pointcut thisEx = new PatternParser("this(Exception)").parsePointcut().resolve();
+               Pointcut thisIOEx = new PatternParser("this(java.io.IOException)").parsePointcut().resolve();
+
+               Pointcut targetEx = new PatternParser("target(Exception)").parsePointcut().resolve();
+               Pointcut targetIOEx = new PatternParser("target(java.io.IOException)").parsePointcut().resolve();
+
+               JoinPoint.StaticPart jpsp1 = f.makeSJP(JoinPoint.EXCEPTION_HANDLER,f.makeCatchClauseSig(HandlerTestCase.class,Exception.class,"ex"),1);
+               JoinPoint thisExJP = Factory.makeJP(jpsp1,new Exception(),this);
+               JoinPoint thisIOExJP = Factory.makeJP(jpsp1,new IOException(),this);
+               JoinPoint targetExJP = Factory.makeJP(jpsp1,this,new Exception());
+               JoinPoint targetIOExJP = Factory.makeJP(jpsp1,this,new IOException());
+               
+               checkMatches(thisEx,thisExJP,null,FuzzyBoolean.YES);
+               checkMatches(thisIOEx,thisExJP,null,FuzzyBoolean.NO);
+               checkMatches(targetEx,thisExJP,null,FuzzyBoolean.NO);
+               checkMatches(targetIOEx,thisExJP,null,FuzzyBoolean.NO);
+
+               checkMatches(thisEx,thisIOExJP,null,FuzzyBoolean.YES);
+               checkMatches(thisIOEx,thisIOExJP,null,FuzzyBoolean.YES);
+               checkMatches(targetEx,thisIOExJP,null,FuzzyBoolean.NO);
+               checkMatches(targetIOEx,thisIOExJP,null,FuzzyBoolean.NO);
+
+               checkMatches(thisEx,targetExJP,null,FuzzyBoolean.NO);
+               checkMatches(thisIOEx,targetExJP,null,FuzzyBoolean.NO);
+               checkMatches(targetEx,targetExJP,null,FuzzyBoolean.YES);
+               checkMatches(targetIOEx,targetExJP,null,FuzzyBoolean.NO);
+
+               checkMatches(thisEx,targetIOExJP,null,FuzzyBoolean.NO);
+               checkMatches(thisIOEx,targetIOExJP,null,FuzzyBoolean.NO);
+               checkMatches(targetEx,targetIOExJP,null,FuzzyBoolean.YES);
+               checkMatches(targetIOEx,targetIOExJP,null,FuzzyBoolean.YES);
+       }
+       
+       private void checkMatches(Pointcut p, JoinPoint jp, JoinPoint.StaticPart jpsp, FuzzyBoolean expected) {
+               assertEquals(expected,p.match(jp,jpsp));
+       }
 
 //     private Pointcut makePointcut(String pattern) {
 //             return new PatternParser(pattern).parsePointcut();
diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/WithinCodeTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/WithinCodeTestCase.java
new file mode 100644 (file)
index 0000000..1f81a0d
--- /dev/null
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * 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
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.aspectj.weaver.patterns;
+
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.runtime.reflect.Factory;
+import org.aspectj.util.FuzzyBoolean;
+
+import junit.framework.TestCase;
+
+
+public class WithinCodeTestCase extends TestCase {
+       Pointcut withinCode1;
+       Pointcut withinCode2;
+       Pointcut withinCode3;
+
+       public void testMatchJP() {
+               Factory f = new Factory("WithinCodeTestCase.java",WithinCodeTestCase.class);
+               
+               // JoinPoints to match against...
+               JoinPoint.StaticPart exejp1 = f.makeSJP(JoinPoint.METHOD_EXECUTION,f.makeMethodSig(0,"toString",Object.class,new Class[] {},new String[] {},new Class[0],String.class),1);
+               JoinPoint.StaticPart exejp2 = f.makeSJP(JoinPoint.METHOD_EXECUTION,f.makeMethodSig(0,"sayHi",Hello.class,new Class[] {String.class},new String[] {"s"},new Class[0],void.class),1);
+               JoinPoint.StaticPart execonsjp1 = f.makeSJP(JoinPoint.CONSTRUCTOR_EXECUTION,f.makeConstructorSig(0,Object.class,new Class[0],new String[0],new Class[0]),1);
+               JoinPoint.StaticPart execonsjp2 = f.makeSJP(JoinPoint.CONSTRUCTOR_EXECUTION,f.makeConstructorSig(0,String.class,new Class[] {String.class},new String[]{"s"},new Class[0]),1);
+               
+               checkMatches(withinCode1,exejp1,FuzzyBoolean.YES);
+               checkMatches(withinCode1,exejp2,FuzzyBoolean.NO);
+               checkMatches(withinCode1,execonsjp1,FuzzyBoolean.NO);
+               checkMatches(withinCode1,execonsjp2,FuzzyBoolean.NO);
+
+               checkMatches(withinCode2,exejp1,FuzzyBoolean.NO);
+               checkMatches(withinCode2,exejp2,FuzzyBoolean.NO);
+               checkMatches(withinCode2,execonsjp1,FuzzyBoolean.YES);
+               checkMatches(withinCode2,execonsjp2,FuzzyBoolean.YES);
+
+               checkMatches(withinCode3,exejp1,FuzzyBoolean.NO);
+               checkMatches(withinCode3,exejp2,FuzzyBoolean.NO);
+               checkMatches(withinCode3,execonsjp1,FuzzyBoolean.NO);
+               checkMatches(withinCode3,execonsjp2,FuzzyBoolean.YES);
+
+       }
+       
+       private void checkMatches(Pointcut p, JoinPoint.StaticPart jpsp, FuzzyBoolean expected) {
+               assertEquals(expected,p.match(null,jpsp));
+       }
+       
+       protected void setUp() throws Exception {
+               super.setUp();
+               withinCode1 = new PatternParser("withincode(String Object.toString())").parsePointcut().resolve();
+               withinCode2 = new PatternParser("withincode(new(..))").parsePointcut().resolve();
+               withinCode3 = new PatternParser("withincode(String.new(..))").parsePointcut().resolve();
+       }
+       
+       private static class Hello {};
+}
index d400288fc3e7852ee12c5b6e99d466033a97e93d..18d0380ca2ce0fc554ff91eaf597df032161f6ec 100644 (file)
@@ -19,6 +19,8 @@ import junit.framework.TestCase;
 
 import org.aspectj.weaver.*;
 import org.aspectj.weaver.bcel.BcelWorld;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.runtime.reflect.Factory;
 import org.aspectj.util.FuzzyBoolean;
 
 public class WithinTestCase extends TestCase {         
@@ -67,6 +69,29 @@ public class WithinTestCase extends TestCase {
 
        }
 
+       
+       public void testMatchJP() {
+               Factory f = new Factory("WithinTestCase.java",WithinTestCase.class);
+               
+               JoinPoint.StaticPart inString = f.makeSJP(JoinPoint.CONSTRUCTOR_EXECUTION,f.makeConstructorSig(0,String.class,new Class[] {String.class},new String[]{"s"},new Class[0]),1);
+               JoinPoint.StaticPart inObject = f.makeSJP(JoinPoint.CONSTRUCTOR_EXECUTION,f.makeConstructorSig(0,Object.class,new Class[] {},new String[]{},new Class[0]),1);
+
+               Pointcut withinString = new PatternParser("within(String)").parsePointcut().resolve();
+               Pointcut withinObject = new PatternParser("within(Object)").parsePointcut().resolve();
+               Pointcut withinObjectPlus = new PatternParser("within(Object+)").parsePointcut().resolve();
+               
+               checkMatches(withinString,inString,FuzzyBoolean.YES);
+               checkMatches(withinString,inObject,FuzzyBoolean.NO);
+               checkMatches(withinObject,inString,FuzzyBoolean.NO);
+               checkMatches(withinObject,inObject, FuzzyBoolean.YES);
+               checkMatches(withinObjectPlus,inString,FuzzyBoolean.YES);
+               checkMatches(withinObjectPlus,inObject,FuzzyBoolean.YES);
+       }
+       
+       private void checkMatches(Pointcut p, JoinPoint.StaticPart jpsp, FuzzyBoolean expected) {
+               assertEquals(expected,p.match(null,jpsp));
+       }
+       
        public Pointcut makePointcut(String pattern) {
                Pointcut pointcut0 = Pointcut.fromString(pattern);