]> source.dussan.org Git - aspectj.git/commitdiff
@style if support, parser support for if() / if(true)/ if(false) [might lead to issue...
authoravasseur <avasseur>
Wed, 8 Jun 2005 16:19:16 +0000 (16:19 +0000)
committeravasseur <avasseur>
Wed, 8 Jun 2005 16:19:16 +0000 (16:19 +0000)
14 files changed:
tests/src/org/aspectj/systemtest/ajc150/ataspectj/misuse.xml
weaver/src/org/aspectj/weaver/IntMap.java
weaver/src/org/aspectj/weaver/PerObjectInterfaceTypeMunger.java
weaver/src/org/aspectj/weaver/PerTypeWithinTargetTypeMunger.java
weaver/src/org/aspectj/weaver/ResolvedPointcutDefinition.java
weaver/src/org/aspectj/weaver/bcel/AtAjAttributes.java
weaver/src/org/aspectj/weaver/patterns/ExposedState.java
weaver/src/org/aspectj/weaver/patterns/IfPointcut.java
weaver/src/org/aspectj/weaver/patterns/PatternParser.java
weaver/src/org/aspectj/weaver/patterns/PerThisOrTargetPointcutVisitor.java
weaver/src/org/aspectj/weaver/patterns/PointcutVisitor.java
weaver/src/org/aspectj/weaver/tools/PointcutParser.java
weaver/testdata/visitor.pointcuts.txt
weaver/testsrc/org/aspectj/weaver/tools/PointcutParserTest.java

index f78aa87b34788a1c15f594232edb7a5a525f40b7..d0204141a0c3c02eeaa104f2e04766387962fcbc 100644 (file)
@@ -21,7 +21,7 @@
     <ajc-test dir="java5/ataspectj"
         pr="" title="@Pointcut not returning void">
         <compile files="ataspectj/misuse/Test008.java" options="-1.5 -Xdev:NoAtAspectJProcessing">
-            <message kind="warning" line="9" text="Found @Pointcut on a method not returning void"/>
+            <message kind="warning" line="9" text="Found @Pointcut on a method not returning 'void' or not 'public static boolean'"/>
         </compile>
     </ajc-test>
 
index 4025a62114027da8953aa01766e0d9e7973185d8..f8646c8e3f3ceaf5f5d220b54bb42b9aa670cb86 100644 (file)
@@ -38,7 +38,11 @@ public class IntMap {
        
        
        public ResolvedPointcutDefinition peekEnclosingDefinitition() {
-               return (ResolvedPointcutDefinition)enclosingDefinition.get(enclosingDefinition.size()-1);
+        try {
+                   return (ResolvedPointcutDefinition)enclosingDefinition.get(enclosingDefinition.size()-1);
+        } catch (IndexOutOfBoundsException e) {
+            return null;
+        }
        }
        
        
index 99ce3bd50a47c373826fd66c43932c4646226486..c044edb29140672a98a4ad673ff9e87e8eeb8e3b 100644 (file)
 /* *******************************************************************
  * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
- * 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: 
- *     PARC     initial implementation 
+ * 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:
+ *     PARC                 initial implementation
+ *     Alexandre Vasseur    rearchitected for #75442 finer grained matching
  * ******************************************************************/
-
-
 package org.aspectj.weaver;
 
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.Map;
-import java.util.WeakHashMap;
-import java.util.List;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.HashMap;
-
-import org.aspectj.weaver.patterns.Pointcut;
-import org.aspectj.weaver.patterns.FastMatchInfo;
-import org.aspectj.weaver.patterns.PerClause;
-import org.aspectj.weaver.patterns.PointcutVisitor;
-import org.aspectj.weaver.patterns.PatternNode;
-import org.aspectj.weaver.patterns.PerThisOrTargetPointcutVisitor;
+import org.aspectj.weaver.patterns.PerFromSuper;
 import org.aspectj.weaver.patterns.PerObject;
+import org.aspectj.weaver.patterns.PerThisOrTargetPointcutVisitor;
+import org.aspectj.weaver.patterns.Pointcut;
 import org.aspectj.weaver.patterns.TypePattern;
-import org.aspectj.weaver.patterns.PerFromSuper;
-import org.aspectj.util.FuzzyBoolean;
-
-public class PerObjectInterfaceTypeMunger extends ResolvedTypeMunger {
-
-    // key is advisedType, value is Set of aspect type that advise the type and are perObject
-    public static Map s_advisedTypeToAspects = new HashMap();
-    public static void registerAsAdvisedBy(ResolvedTypeX matchType, ResolvedTypeX aspectType) {
-        if (PerClause.PEROBJECT.equals(aspectType.getPerClause().getKind())) {
-            Set aspects = (Set)s_advisedTypeToAspects.get(matchType);
-            if (aspects == null) {
-                aspects = new HashSet(1);
-                s_advisedTypeToAspects.put(matchType, aspects);
-            }
-            aspects.add(aspectType);
-        }
-    }
-    public static void unregisterFromAsAdvisedBy(ResolvedTypeX matchType) {
-        s_advisedTypeToAspects.remove(matchType);
-    }
-
-       private ResolvedMember getMethod;
-       private ResolvedMember setMethod;
-       private TypeX aspectType;
-       private TypeX interfaceType;
-       private Pointcut testPointcut;
 
+import java.io.DataOutputStream;
+import java.io.IOException;
 
-       public PerObjectInterfaceTypeMunger(TypeX aspectType, Pointcut testPointcut) {
-               super(PerObjectInterface, null);
-               this.aspectType = aspectType;
-               this.testPointcut = testPointcut;
-               this.interfaceType = AjcMemberMaker.perObjectInterfaceType(aspectType);
-               this.getMethod = AjcMemberMaker.perObjectInterfaceGet(aspectType);
-               this.setMethod = AjcMemberMaker.perObjectInterfaceSet(aspectType);
-       }
-       
-
-       public void write(DataOutputStream s) throws IOException {
-               throw new RuntimeException("shouldn't be serialized");
-       }
-       public TypeX getAspectType() {
-               return aspectType;
-       }
-
-       public ResolvedMember getGetMethod() {
-               return getMethod;
-       }
-
-       public TypeX getInterfaceType() {
-               return interfaceType;
-       }
+public class PerObjectInterfaceTypeMunger extends ResolvedTypeMunger {
 
-       public ResolvedMember getSetMethod() {
-               return setMethod;
-       }
+    private final TypeX interfaceType;
+    private final Pointcut testPointcut;
+    private TypePattern lazyTestTypePattern;
 
-       public Pointcut getTestPointcut() {
-               return testPointcut;
-       }
-       
-       public boolean matches(ResolvedTypeX matchType, ResolvedTypeX aspectType) {
-        if (matchType.isInterface()) return false;
+    public PerObjectInterfaceTypeMunger(TypeX aspectType, Pointcut testPointcut) {
+        super(PerObjectInterface, null);
+        this.testPointcut = testPointcut;
+        this.interfaceType = AjcMemberMaker.perObjectInterfaceType(aspectType);
+    }
 
-        //FIXME AV - cache that
-        final boolean isPerThis;
-        if (aspectType.getPerClause() instanceof PerFromSuper) {
-            PerFromSuper ps = (PerFromSuper) aspectType.getPerClause();
-            isPerThis = ((PerObject)ps.lookupConcretePerClause(aspectType)).isThis();
-        } else {
-            isPerThis = ((PerObject)aspectType.getPerClause()).isThis();
+    private TypePattern getTestTypePattern(ResolvedTypeX aspectType) {
+        if (lazyTestTypePattern == null) {
+            final boolean isPerThis;
+            if (aspectType.getPerClause() instanceof PerFromSuper) {
+                PerFromSuper ps = (PerFromSuper) aspectType.getPerClause();
+                isPerThis = ((PerObject) ps.lookupConcretePerClause(aspectType)).isThis();
+            } else {
+                isPerThis = ((PerObject) aspectType.getPerClause()).isThis();
+            }
+            PerThisOrTargetPointcutVisitor v = new PerThisOrTargetPointcutVisitor(!isPerThis, aspectType);
+            lazyTestTypePattern = v.getPerTypePointcut(testPointcut);
         }
-        PerThisOrTargetPointcutVisitor v = new PerThisOrTargetPointcutVisitor(
-                !isPerThis,
-                aspectType
-        );
-        TypePattern tp = v.getPerTypePointcut(testPointcut);
-
-        if (true) return tp.matchesStatically(matchType);
-
-
-        //FIXME ATAJ waiting Andy patch...
-        // comment from Andy - this is hard to fix...
-
-        // right now I filter @AJ aspect else it end up with duplicate members
-        //return !matchType.isInterface() && !matchType.isAnnotationStyleAspect();
-        Set aspects = (Set)s_advisedTypeToAspects.get(matchType);
-        if (aspects == null) {
-            //return false;
-            // FIXME AV - #75442 see thread
-            // back off on old style : it can happen for perTarget that target type is presented first to the weaver
-            // while caller side is not thus we have advisedTypeToAspects still empty..
+        return lazyTestTypePattern;
+    }
 
-            // note: needed only for perTarget if lateMunger is used (see PerObject)
-            return !matchType.isInterface() && !matchType.isAnnotationStyleAspect();
-        } else {
-            return aspects.contains(aspectType);
-        }
+    public void write(DataOutputStream s) throws IOException {
+        throw new RuntimeException("shouldn't be serialized");
+    }
 
+    public TypeX getInterfaceType() {
+        return interfaceType;
     }
 
-    private FuzzyBoolean isWithinType(ResolvedTypeX type) {
-        return testPointcut.fastMatch(new FastMatchInfo(type, null));
+    public Pointcut getTestPointcut() {
+        return testPointcut;
     }
 
+    public boolean matches(ResolvedTypeX matchType, ResolvedTypeX aspectType) {
+        if (matchType.isInterface()) return false;
+        return getTestTypePattern(aspectType).matchesStatically(matchType);
+    }
 }
index 965d7717e2075ab799577381630cf23f61a487d6..107898a2d031e59c9887570e220c5eab9f99e5e7 100644 (file)
@@ -21,17 +21,14 @@ import org.aspectj.weaver.patterns.Pointcut;
 
 // PTWIMPL Target type munger adds the localAspectOf() method
 public class PerTypeWithinTargetTypeMunger extends ResolvedTypeMunger {
-       private ResolvedMember localAspectOfMethod;
        private TypeX aspectType;
        private PerTypeWithin testPointcut;
 
-
        public PerTypeWithinTargetTypeMunger(TypeX aspectType, PerTypeWithin testPointcut) {
                super(PerTypeWithinInterface, null);
                this.aspectType    = aspectType;
                this.testPointcut  = testPointcut;
        }
-       
 
        public void write(DataOutputStream s) throws IOException {
                throw new RuntimeException("shouldn't be serialized");
index 21af036b5ceac3b3173d6b1eab82fa5757168039..79f7689ce69dbd5a02a82f363d56e3960468d5db 100644 (file)
@@ -21,19 +21,40 @@ import org.aspectj.weaver.patterns.Pointcut;
 
 public class ResolvedPointcutDefinition extends ResolvedMember {
        private Pointcut pointcut;
-       
-       public ResolvedPointcutDefinition(
+
+    public ResolvedPointcutDefinition(
+        TypeX declaringType,
+        int modifiers,
+        String name,
+        TypeX[] parameterTypes,
+        Pointcut pointcut)
+    {
+        this(declaringType, modifiers, name, parameterTypes, ResolvedTypeX.VOID, pointcut);
+    }
+
+    /**
+     * An instance which can be given a specific returnType, used f.e. in if() pointcut for @AJ
+     * 
+     * @param declaringType
+     * @param modifiers
+     * @param name
+     * @param parameterTypes
+     * @param returnType
+     * @param pointcut
+     */
+    public ResolvedPointcutDefinition(
                TypeX declaringType,
                int modifiers,
                String name,
                TypeX[] parameterTypes,
-               Pointcut pointcut) 
+        TypeX returnType,
+               Pointcut pointcut)
     {
                super(
                        POINTCUT,
                        declaringType,
                        modifiers,
-                       ResolvedTypeX.VOID,
+                       returnType,
                        name,
                        parameterTypes);
                this.pointcut = pointcut;
index 5de34cf380309e2794fe53ca6065bfc712e5355d..938411661a5d183a3d492da376e8ca3ab9116ecf 100644 (file)
@@ -847,9 +847,10 @@ public class AtAjAttributes {
             ElementNameValuePair pointcutExpr = getAnnotationElement(pointcut, VALUE);
             if (pointcutExpr != null) {
 
-                // semantic check: the method must return void
-                if (!Type.VOID.equals(struct.method.getReturnType())) {
-                    reportWarning("Found @Pointcut on a method not returning void", struct);
+                // semantic check: the method must return void, or be "public static boolean" for if() support
+                if (!(Type.VOID.equals(struct.method.getReturnType())
+                      || (Type.BOOLEAN.equals(struct.method.getReturnType()) && struct.method.isStatic() && struct.method.isPublic()))) {
+                    reportWarning("Found @Pointcut on a method not returning 'void' or not 'public static boolean'", struct);
                     ;//no need to stop
                 }
                 // semantic check: the method must not throw anything
@@ -888,6 +889,7 @@ public class AtAjAttributes {
                                         struct.method.getModifiers(),
                                         struct.method.getName(),
                                         argumentTypes,
+                                        TypeX.forSignature(struct.method.getReturnType().getSignature()),
                                         pc,
                                         binding
                                 )
@@ -1064,7 +1066,6 @@ public class AtAjAttributes {
 //        }
     }
 
-
     /**
      * Compute the flag for the xxxJoinPoint extra argument
      *
@@ -1072,17 +1073,30 @@ public class AtAjAttributes {
      * @return
      */
     private static int extractExtraArgument(Method method) {
-        int extraArgument = 0;
         Type[] methodArgs = method.getArgumentTypes();
+        String[] sigs = new String[methodArgs.length];
         for (int i = 0; i < methodArgs.length; i++) {
-            String methodArg = methodArgs[i].getSignature();
-            if (AjcMemberMaker.TYPEX_JOINPOINT.getSignature().equals(methodArg)) {
+            sigs[i] = methodArgs[i].getSignature();
+        }
+        return extractExtraArgument(sigs);
+    }
+
+    /**
+     * Compute the flag for the xxxJoinPoint extra argument
+     *
+     * @param argumentSignatures
+     * @return
+     */
+    public static int extractExtraArgument(String[] argumentSignatures) {
+        int extraArgument = 0;
+        for (int i = 0; i < argumentSignatures.length; i++) {
+            if (AjcMemberMaker.TYPEX_JOINPOINT.getSignature().equals(argumentSignatures[i])) {
                 extraArgument |= Advice.ThisJoinPoint;
-            } else if (AjcMemberMaker.TYPEX_PROCEEDINGJOINPOINT.getSignature().equals(methodArg)) {
+            } else if (AjcMemberMaker.TYPEX_PROCEEDINGJOINPOINT.getSignature().equals(argumentSignatures[i])) {
                 extraArgument |= Advice.ThisJoinPoint;
-            } else if (AjcMemberMaker.TYPEX_STATICJOINPOINT.getSignature().equals(methodArg)) {
+            } else if (AjcMemberMaker.TYPEX_STATICJOINPOINT.getSignature().equals(argumentSignatures[i])) {
                 extraArgument |= Advice.ThisJoinPointStaticPart;
-            } else if (AjcMemberMaker.TYPEX_ENCLOSINGSTATICJOINPOINT.getSignature().equals(methodArg)) {
+            } else if (AjcMemberMaker.TYPEX_ENCLOSINGSTATICJOINPOINT.getSignature().equals(argumentSignatures[i])) {
                 extraArgument |= Advice.ThisEnclosingJoinPointStaticPart;
             }
         }
@@ -1231,9 +1245,10 @@ public class AtAjAttributes {
 
         private Pointcut m_lazyPointcut = null;
 
-        public LazyResolvedPointcutDefinition(ResolvedTypeX declaringType, int modifiers, String name, TypeX[] parameterTypes,
+        public LazyResolvedPointcutDefinition(ResolvedTypeX declaringType, int modifiers, String name,
+                                              TypeX[] parameterTypes, TypeX returnType,
                                               Pointcut pointcut, IScope binding) {
-            super(declaringType, modifiers, name, parameterTypes, null);
+            super(declaringType, modifiers, name, parameterTypes, returnType, null);
             m_pointcutUnresolved = pointcut;
             m_binding = binding;
         }
@@ -1328,7 +1343,7 @@ public class AtAjAttributes {
      */
     private static Pointcut parsePointcut(String pointcutString, AjAttributeStruct location) {
         try {
-            Pointcut pointcut = Pointcut.fromString(pointcutString);
+            Pointcut pointcut = new PatternParser(pointcutString, location.context).parsePointcut();
             pointcut.setLocation(location.context, -1, -1);//FIXME -1,-1 is not good enough
             return pointcut;
         } catch (ParserException e) {
index e76be017b1a5fb6fe31e999cdd398c8c6b07a6cb..03dd40e1530627c6d4c5663881535bb9a93d8acf 100644 (file)
@@ -46,7 +46,7 @@ public class ExposedState {
                //XXX add sanity checks
                // Some checks added in ArgsPointcut and ThisOrTargetPointcut
 //             if (vars[i]!=null) {
-//                     if (!var.getType().equals(vars[i].getType())) 
+//                     if (!var.getType().equals(vars[i].getType()))
 //                       throw new RuntimeException("Shouldn't allow a slot to change type! Currently="+var.getType()+"   New="+vars[i].getType());
 //             }
                vars[i] = var;
index 9a716e6e62ba7d7b588bac065cf4807eb538d634..dc3ffc57679ecf906d372161937447c3df5e4f43 100644 (file)
@@ -1,16 +1,15 @@
 /* *******************************************************************
  * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
- * 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: 
- *     PARC     initial implementation 
+ * 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:
+ *     PARC                 initial implementation
+ *     Alexandre Vasseur    if() implementation for @AJ style
  * ******************************************************************/
-
-
 package org.aspectj.weaver.patterns;
 
 import java.io.DataOutputStream;
@@ -34,28 +33,45 @@ import org.aspectj.weaver.Shadow;
 import org.aspectj.weaver.ShadowMunger;
 import org.aspectj.weaver.VersionedDataInputStream;
 import org.aspectj.weaver.WeaverMessages;
+import org.aspectj.weaver.TypeX;
+import org.aspectj.weaver.AjcMemberMaker;
+import org.aspectj.weaver.bcel.AtAjAttributes;
 import org.aspectj.weaver.ast.Expr;
 import org.aspectj.weaver.ast.Literal;
 import org.aspectj.weaver.ast.Test;
 import org.aspectj.weaver.ast.Var;
 
-
 public class IfPointcut extends Pointcut {
        public ResolvedMember testMethod;
        public int extraParameterFlags;
-       
+
+    /**
+     * A token source dump that looks like a pointcut (but is NOT parseable at all - just here to help debugging etc)
+     */
+    private String enclosingPointcutHint;
+
        public Pointcut residueSource;
        int baseArgsCount;
        
        //XXX some way to compute args
 
-       
        public IfPointcut(ResolvedMember testMethod, int extraParameterFlags) {
                this.testMethod = testMethod;
                this.extraParameterFlags = extraParameterFlags;
                this.pointcutKind = IF;
+        this.enclosingPointcutHint = null;
        }
-       
+
+    /**
+     * No-arg constructor for @AJ style, where the if() body is actually the @Pointcut annotated method
+     */
+    public IfPointcut(String enclosingPointcutHint) {
+        this.pointcutKind = IF;
+        this.enclosingPointcutHint = enclosingPointcutHint;
+        this.testMethod = null;// resolved during concretize
+        this.extraParameterFlags = -1;//allows to keep track of the @Aj style
+    }
+
        public Set couldMatchKinds() {
                return Shadow.ALL_SHADOW_KINDS;
        }
@@ -122,19 +138,24 @@ public class IfPointcut extends Pointcut {
                IfPointcut o = (IfPointcut)other;
                return o.testMethod.equals(this.testMethod);
        }
+
     public int hashCode() {
         int result = 17;
         result = 37*result + testMethod.hashCode();
         return result;
     }
-       public String toString() {
-               return "if(" + testMethod + ")";
-       }
 
+    public String toString() {
+        if (extraParameterFlags < 0) {
+            //@AJ style
+            return "if()";
+        } else {
+                   return "if(" + testMethod + ")";//FIXME AV - bad, this makes it unparsable. Perhaps we can use if() for code style behind the scene!
+        }
+       }
 
        //??? The implementation of name binding and type checking in if PCDs is very convoluted
        //    There has to be a better way...
-
     private boolean findingResidue = false;
        
        // Similar to lastMatchedShadowId - but only for if PCDs.
@@ -155,43 +176,68 @@ public class IfPointcut extends Pointcut {
                        Test ret = Literal.TRUE;
                        List args = new ArrayList();
                        
-                       // If there are no args to sort out, don't bother with the recursive call
-                       if (baseArgsCount > 0) {
-                               ExposedState myState = new ExposedState(baseArgsCount);
-                               //??? we throw out the test that comes from this walk.  All we want here
-                               //    is bindings for the arguments
-                               residueSource.findResidue(shadow, myState);
-                               
-                               
-                       for (int i=0; i < baseArgsCount; i++) {
-                               Var v = myState.get(i);
-                               args.add(v);
-                               ret = Test.makeAnd(ret, 
-                                       Test.makeInstanceof(v, 
-                                               testMethod.getParameterTypes()[i].resolve(shadow.getIWorld())));
-                       }
-                       }
-       
-               // handle thisJoinPoint parameters
-               if ((extraParameterFlags & Advice.ThisJoinPoint) != 0) {
-                       args.add(shadow.getThisJoinPointVar());
-               }
-               
-               if ((extraParameterFlags & Advice.ThisJoinPointStaticPart) != 0) {
-                       args.add(shadow.getThisJoinPointStaticPartVar());
-               }
-               
-               if ((extraParameterFlags & Advice.ThisEnclosingJoinPointStaticPart) != 0) {
-                       args.add(shadow.getThisEnclosingJoinPointStaticPartVar());
-               }
-               
+               // code style
+            if (extraParameterFlags >= 0) {
+                // If there are no args to sort out, don't bother with the recursive call
+                if (baseArgsCount > 0) {
+                    ExposedState myState = new ExposedState(baseArgsCount);
+                    //??? we throw out the test that comes from this walk.  All we want here
+                    //    is bindings for the arguments
+                    residueSource.findResidue(shadow, myState);
+
+
+                    for (int i=0; i < baseArgsCount; i++) {
+                        Var v = myState.get(i);
+                        args.add(v);
+                        ret = Test.makeAnd(ret,
+                            Test.makeInstanceof(v,
+                                testMethod.getParameterTypes()[i].resolve(shadow.getIWorld())));
+                    }
+                }
+
+                // handle thisJoinPoint parameters
+                if ((extraParameterFlags & Advice.ThisJoinPoint) != 0) {
+                    args.add(shadow.getThisJoinPointVar());
+                }
+
+                if ((extraParameterFlags & Advice.ThisJoinPointStaticPart) != 0) {
+                    args.add(shadow.getThisJoinPointStaticPartVar());
+                }
+
+                if ((extraParameterFlags & Advice.ThisEnclosingJoinPointStaticPart) != 0) {
+                    args.add(shadow.getThisEnclosingJoinPointStaticPartVar());
+                }
+            } else {
+                // @style is slightly different
+                int currentStateIndex = 0;
+                //FIXME AV - "args(jp)" test(jp, thejp) will fail here
+                for (int i = 0; i < testMethod.getParameterTypes().length; i++) {
+                    String argSignature = testMethod.getParameterTypes()[i].getSignature();
+                    if (AjcMemberMaker.TYPEX_JOINPOINT.getSignature().equals(argSignature)) {
+                        args.add(shadow.getThisJoinPointVar());
+                    } else if (AjcMemberMaker.TYPEX_PROCEEDINGJOINPOINT.getSignature().equals(argSignature)) {
+                        args.add(shadow.getThisJoinPointVar());
+                    } else if (AjcMemberMaker.TYPEX_STATICJOINPOINT.getSignature().equals(argSignature)) {
+                        args.add(shadow.getThisJoinPointStaticPartVar());
+                    } else if (AjcMemberMaker.TYPEX_ENCLOSINGSTATICJOINPOINT.getSignature().equals(argSignature)) {
+                        args.add(shadow.getThisEnclosingJoinPointStaticPartVar());
+                    } else {
+                        // we don't use i as JoinPoint.* can be anywhere in the signature in @style
+                        Var v = state.get(currentStateIndex++);
+                        args.add(v);
+                        ret = Test.makeAnd(ret,
+                            Test.makeInstanceof(v,
+                                testMethod.getParameterTypes()[i].resolve(shadow.getIWorld())));
+                    }
+                }
+            }
+
                ret = Test.makeAnd(ret, Test.makeCall(testMethod, (Expr[])args.toArray(new Expr[args.size()])));
 
                        // Remember...
                        ifLastMatchedShadowId = shadow.shadowId;
                        ifLastMatchedShadowResidue = ret;
                        return ret; 
-                       
                } finally {
                        findingResidue = false;
                }
@@ -221,14 +267,56 @@ public class IfPointcut extends Pointcut {
                                        null);
                        return Pointcut.makeMatchesNothing(Pointcut.CONCRETE);
                }
-               
+
                if (partiallyConcretized != null) {
                        return partiallyConcretized;
                }
-               IfPointcut ret = new IfPointcut(testMethod, extraParameterFlags);
-               ret.copyLocationFrom(this);
-               partiallyConcretized = ret;
-               
+
+        final IfPointcut ret;
+        if (extraParameterFlags < 0 && testMethod == null) {
+            // @AJ style, we need to find the testMethod in the aspect defining the "if()" enclosing pointcut
+            ResolvedPointcutDefinition def = bindings.peekEnclosingDefinitition();
+            if (def != null) {
+                ResolvedTypeX aspect = inAspect.getWorld().resolve(def.getDeclaringType());
+                ResolvedMember[] methods = aspect.getDeclaredJavaMethods();
+                for (int i = 0; i < methods.length; i++) {
+                    ResolvedMember method = methods[i];
+                    if (def.getName().equals(method.getName())
+                        && def.getParameterTypes().length == method.getParameterTypes().length) {
+                        boolean sameSig = true;
+                        for (int j = 0; j < method.getParameterTypes().length; j++) {
+                            TypeX argJ = method.getParameterTypes()[j];
+                            if (!argJ.equals(def.getParameterTypes()[j])) {
+                                sameSig = false;
+                                break;
+                            }
+                        }
+                        if (sameSig) {
+                            testMethod = method;
+                            break;
+                        }
+                    }
+                }
+                if (testMethod == null) {
+                    inAspect.getWorld().showMessage(
+                            IMessage.ERROR,
+                            "Cannot find if() body from '" + def.toString() + "' for '" + enclosingPointcutHint + "'",
+                            this.getSourceLocation(),
+                            null
+                    );
+                    return Pointcut.makeMatchesNothing(Pointcut.CONCRETE);
+                }
+            } else {
+                testMethod = inAspect.getWorld().resolve(bindings.getAdviceSignature());
+            }
+            ret = new IfPointcut(enclosingPointcutHint);
+            ret.testMethod = testMethod;
+        } else {
+            ret = new IfPointcut(testMethod, extraParameterFlags);
+        }
+        ret.copyLocationFrom(this);
+        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,
@@ -260,7 +348,24 @@ public class IfPointcut extends Pointcut {
                                return Pointcut.makeMatchesNothing(Pointcut.CONCRETE);
                        }
                        ret.baseArgsCount = def.getParameterTypes().length;
-                       
+
+            // for @style, we have implicit binding for JoinPoint.* things
+            //FIXME AV - will lead to failure for "args(jp)" test(jp, thejp) / see args() implementation
+            if (ret.extraParameterFlags < 0) {
+                ret.baseArgsCount = 0;
+                for (int i = 0; i < testMethod.getParameterTypes().length; i++) {
+                    String argSignature = testMethod.getParameterTypes()[i].getSignature();
+                    if (AjcMemberMaker.TYPEX_JOINPOINT.getSignature().equals(argSignature)
+                        || AjcMemberMaker.TYPEX_PROCEEDINGJOINPOINT.getSignature().equals(argSignature)
+                        || AjcMemberMaker.TYPEX_STATICJOINPOINT.getSignature().equals(argSignature)
+                        || AjcMemberMaker.TYPEX_ENCLOSINGSTATICJOINPOINT.getSignature().equals(argSignature)) {
+                        ;
+                    } else {
+                        ret.baseArgsCount++;
+                    }
+                }
+            }
+
                        IntMap newBindings = IntMap.idMap(ret.baseArgsCount);
                        newBindings.copyContext(bindings);
                        ret.residueSource = def.getPointcut().concretize(inAspect, newBindings);
@@ -281,10 +386,11 @@ public class IfPointcut extends Pointcut {
         return visitor.visit(this, data);
     }
 
-       private static class IfFalsePointcut extends IfPointcut {
+       public static class IfFalsePointcut extends IfPointcut {
                
                public IfFalsePointcut() {
                        super(null,0);
+            this.pointcutKind = Pointcut.IF_FALSE;
                }
                
                public Set couldMatchKinds() {
@@ -355,10 +461,11 @@ public class IfPointcut extends Pointcut {
                return ret;
        }
 
-       private static class IfTruePointcut extends IfPointcut {                
+       public static class IfTruePointcut extends IfPointcut {
                        
                public IfTruePointcut() {
                        super(null,0);
+            this.pointcutKind = Pointcut.IF_TRUE;
                }
 
                public boolean alwaysTrue() {
index 32ff9d1a9ec8ea45032383da25141b291d195ecb..d63484e0fa15637b7a715fefc62aca5349a72e62 100644 (file)
@@ -317,6 +317,33 @@ public class PatternParser {
                        SignaturePattern sig = parseConstructorSignaturePattern();
                        eat(")");
                        return new KindedPointcut(Shadow.PreInitialization, sig);
+        } else if (kind.equals("if")) {
+            //@style support
+            parseIdentifier();
+            eat("(");
+            if (maybeEat("true")) {
+                eat(")");
+                return new IfPointcut.IfTruePointcut();
+            } else if (maybeEat("false")) {
+                eat(")");
+                return new IfPointcut.IfFalsePointcut();
+            } else {
+                //TODO AV - true/false stuff needed ? What are the token here ?
+                eat(")");
+                // build a readable pointcut as an hint (toString() dumps raw token array into an horrible thing)
+                StringBuffer sb = new StringBuffer();
+                int currentIndex = tokenSource.getIndex();
+                try {
+                    tokenSource.setIndex(0);
+                    for (int i = 0; !IToken.EOF.equals(tokenSource.peek(i)); i++) {
+                        if (i > 0) sb.append(' ');
+                        sb.append(tokenSource.peek(i).getString());
+                    }
+                } finally {
+                    tokenSource.setIndex(currentIndex);
+                }
+                return new IfPointcut(sb.toString());
+            }
                } else {
                        return parseReferencePointcut();
                }
@@ -770,9 +797,9 @@ public class PatternParser {
                                if (previous != null) {
                                        if (!isAdjacent(previous, tok)) break;
                                }
-                               if (tok.getString() == "*" || (tok.isIdentifier() && tok.getString()!="...")) {
+                               if ("*".equals(tok.getString()) || (tok.isIdentifier() && !"...".equals(tok.getString()))) {
                                        buf.append(tok.getString());
-                               } else if (tok.getString()=="...") {
+                               } else if ("...".equals(tok.getString())) {
                                        break;
                                } else if (tok.getLiteralKind() != null) {
                                        //System.err.println("literal kind: " + tok.getString());
@@ -842,7 +869,7 @@ public class PatternParser {
                        if (previous != null) {
                                if (!isAdjacent(previous, tok)) break;
                        }
-                       if (tok.getString() == "*" || tok.isIdentifier()) {
+                       if (tok.getString().equals("*") || tok.isIdentifier()) {
                                buf.append(tok.getString());
                        } else if (tok.getLiteralKind() != null) {
                                //System.err.println("literal kind: " + tok.getString());
@@ -1103,7 +1130,7 @@ public class PatternParser {
        public String parseStringLiteral() {
                IToken token = tokenSource.next();
                String literalKind = token.getLiteralKind();
-               if (literalKind == "string") {
+               if (literalKind.equals("string")) {
                        return token.getString();
                }
 
@@ -1142,7 +1169,7 @@ public class PatternParser {
        
        public boolean maybeEat(String token) {
                IToken next = tokenSource.peek();
-               if (next.getString() == token) {
+               if (next.getString().equals(token)) {
                        tokenSource.next();
                        return true;
                } else {
@@ -1162,7 +1189,7 @@ public class PatternParser {
                
        public boolean peek(String token) {
                IToken next = tokenSource.peek();
-               return next.getString() == token;
+               return next.getString().equals(token);
        }
 
        
index 54eead76cf2cc02db65813e06caa45d6a614ae8b..6eb953e7e5f0d432df1c96f3d8e6264e2a36956b 100644 (file)
  *******************************************************************************/
 package org.aspectj.weaver.patterns;
 
-import org.aspectj.weaver.Member;
 import org.aspectj.weaver.Shadow;
 import org.aspectj.weaver.ResolvedPointcutDefinition;
 import org.aspectj.weaver.ResolvedTypeX;
-import org.aspectj.weaver.World;
 
 /**
  * A visitor that turns a pointcut into a type pattern equivalent for a perthis or pertarget matching:
index 6f2acffd0f1506b00fc62b9d6e81d450c7300490..1abf102ff07cbb7408a53169d57a7e013dc37718 100644 (file)
@@ -610,11 +610,13 @@ public interface PointcutVisitor {
 
         public static void main(String args[]) throws Throwable {
             String[] s = new String[]{
-                //"@args(Foo, Goo, *, .., Moo)",
-                //"execution(* *())",
-                //"call(* *(int, Integer...))",
-                //"staticinitialization(@(Foo) @(Boo) @(Goo) Moo)",
-                "staticinitialization(!@(Immutable) *)"
+//                "@args(Foo, Goo, *, .., Moo)",
+//                "execution(* *())",
+//                "call(* *(int, Integer...))",
+//                "staticinitialization(@(Foo) @(Boo) @(Goo) Moo)",
+//                "staticinitialization(!@(Immutable) *)"
+//                "execution(* *()) && if()",
+                "(if(true) && set(int BaseApp.i))"
 
             };
             for (int i = 0; i < s.length; i++) {
index 949165053692a6d56923e8bf2ceb3159d1a77da2..f1f12af6724ac26c081b835469bb3845b1bb7ff9 100644 (file)
@@ -24,6 +24,7 @@ import org.aspectj.weaver.patterns.ParserException;
 import org.aspectj.weaver.patterns.PatternParser;
 import org.aspectj.weaver.patterns.Pointcut;
 import org.aspectj.weaver.patterns.ThisOrTargetPointcut;
+import org.aspectj.weaver.patterns.IfPointcut;
 
 /**
  * A PointcutParser can be used to build PointcutExpressions for a 
@@ -142,9 +143,13 @@ public class PointcutParser {
                        throw new UnsupportedOperationException("handler is not supported by this parser");
                    break;
                case Pointcut.IF:
+                if (((IfPointcut)pc).extraParameterFlags >= 0) {
+                    throw new UnsupportedOperationException("if not supported for non @AspectJ style");
+                }
+                break;
                case Pointcut.IF_FALSE:
                case Pointcut.IF_TRUE:
-                   throw new UnsupportedOperationException("if is not supported by this parser");                  
+                   break;
                case Pointcut.KINDED:
                        validateKindedPointcut(((KindedPointcut)pc));
                    break;
index f75db3d5cc4e5e808a77ae86bf3ab05cf7dd7419..17e4a7d9f8a13ae4353138a4748e662309bc54cc 100644 (file)
@@ -2340,3 +2340,60 @@ this(i)
 target(foo)
 set(Integer *)
 call(* System.*(..))
+(args(x) && if())
+(execution(void IfPcd.main(..)) && if())
+if()
+(args(o) && if())
+(if() && execution(* LazyTjp.doit(..)))
+(if() && execution(* LazyTjp.doit2(..)))
+(if() && execution(* LazyTjp.doit3(..)))
+if(true)
+(execution(* doCommand(..)) && if())
+if(false)
+(within(IfFalse) && if(false))
+!if(true)
+(!if() && execution(* *(..)))
+(within(IfTrue) && !if(true))
+(execution(void m2()) && if())
+(execution(void main(..)) && !if())
+(execution(void main(..)) && if())
+(execution(void main(String)) && (!if() && args(a)))
+call(* ThisJoinPointAndVerifier.*(..))
+(if() && (lexicalScope() && !within(Trace+)))
+serverIdentification(FTPServer)
+(checkedCut() && if())
+(if() && if())
+(if() && (if() && call(void IfPCDExprJoinPointVisibleCE.main(..))))
+(if() && (if() && callMain(args)))
+ifFalse(Object)
+(this(t) && if())
+(!within(Aspect) && if())
+(if(true) && set(int BaseApp.i))
+(if(true) && get(int BaseApp.i))
+(if(true) && (call(void *.call(int)) && within(BaseApp)))
+(if(true) && call(void BaseApp.call(int)))
+(if(true) && (within(BaseApp) && execution(void *(int))))
+(if(true) && initialization(BaseApp.new(..)))
+(if(true) && call(void *.uncountedCall()))
+(if(true) && call(void BaseApp.uncountedCall()))
+(if(true) && execution(void BaseApp.uncountedCall()))
+(if() && (!within(A) && (!call(* A.*(..)) && (!initialization(new(..)) && !preinitialization(new(..))))))
+(hasEnclosingJoinPoint() && enclosingDiffers())
+!enclosingDiffers()
+(hasEnclosingJoinPoint() && !enclosingDiffers())
+hasDifferentEnclosingJoinPoint()
+(execution(static String PR590.staticMethod()) && if())
+(args(i) && (if() && safety()))
+(safety() && if())
+(if() && get(int AroundCasting.x))
+(call(String C.doit(Object)) && if())
+(execution(String C.doit(Object)) && if())
+(p() && if())
+(if() && (call(void C.foo(C)) && args(d)))
+(execution(* Test.a(..)) && if())
+set(@(Persisted) @(Classified) * *)
+(call(* *(..)) && @target(Classified))
+(call(* *(..)) && @target(classificationInfo))
+callToClassifiedObject(classification)
+@args(Classified, ..)
+classifiedArgument()
index aea55aaf3647f149010fbf6a2d469274af128812..b5f442a03b872f07727e17ca9cce8ff6efc17ea6 100644 (file)
@@ -65,10 +65,12 @@ public class PointcutParserTest extends TestCase {
        public void testParseIfPCD() {
                PointcutParser p = new PointcutParser();
                try {
+            // AV - those 3 are supported for @style 
                        p.parsePointcutExpression("if(true)");
-                       fail("Expected UnsupportedOperationException");
-               } catch(UnsupportedOperationException ex) {
-                       assertTrue(ex.getMessage().startsWith("if pointcuts and reference pointcuts are not supported"));
+            p.parsePointcutExpression("if(true)");
+            p.parsePointcutExpression("if()");
+               } catch(Throwable t) {
+            fail(t.toString());
                }
        }