]> source.dussan.org Git - aspectj.git/commitdiff
formatted
authoraclement <aclement>
Fri, 30 Oct 2009 23:05:59 +0000 (23:05 +0000)
committeraclement <aclement>
Fri, 30 Oct 2009 23:05:59 +0000 (23:05 +0000)
org.aspectj.matcher/src/org/aspectj/weaver/patterns/PointcutRewriter.java

index 7adce3928ed347b10034ebae871cc42740b47b19..6c13ad7f94bf10eae640a7810843dc067025ea52 100644 (file)
@@ -20,124 +20,135 @@ import org.aspectj.weaver.patterns.Pointcut.MatchesNothingPointcut;
 /**
  * @author colyer
  * 
- * Performs term rewriting for pointcut expressions.
+ *         Performs term rewriting for pointcut expressions.
  * 
  */
 public class PointcutRewriter {
 
        private static final boolean WATCH_PROGRESS = false;
-       
+
        /**
-        * Set forcerewrite if you want to override the checking for something already in DNF (useful for
-        * some testing)
-        * Repeated processing of something already in DNF is expensive (it ends up being done for
-        * every pointcut on every incremental compile) - so let's not do it if we don't have to.
-        * See pr113257
+        * Set forcerewrite if you want to override the checking for something already in DNF (useful for some testing) Repeated
+        * processing of something already in DNF is expensive (it ends up being done for every pointcut on every incremental compile) -
+        * so let's not do it if we don't have to. See pr113257
         */
-       public Pointcut rewrite(Pointcut pc,boolean forceRewrite) {
-               Pointcut result = pc;//checkPC(result);
+       public Pointcut rewrite(Pointcut pc, boolean forceRewrite) {
+               Pointcut result = pc;// checkPC(result);
                if (forceRewrite || !isDNF(pc)) {
-                       if (WATCH_PROGRESS) System.out.println("Initial pointcut is        ==> " + format(pc));
-                       result = distributeNot(result);//checkPC(result);
-                       if (WATCH_PROGRESS) System.out.println("Distributing NOT gives     ==> " + format(result));
-                       result = pullUpDisjunctions(result);//checkPC(result);
-                       if (WATCH_PROGRESS) System.out.println("Pull up disjunctions gives ==> " + format(result));             
-           } else {
-                       if (WATCH_PROGRESS) System.out.println("Not distributing NOTs or pulling up disjunctions, already DNF ==> "+format(pc));
-           }
-               result = simplifyAnds(result);  //checkPC(result);
-               if (WATCH_PROGRESS) System.out.println("Simplifying ANDs gives     ==> " + format(result));
-               result = removeNothings(result); //checkPC(result);
-           if (WATCH_PROGRESS) System.out.println("Removing nothings gives    ==> " + format(result));
-               result = sortOrs(result); //checkPC(result);
-               if (WATCH_PROGRESS) System.out.println("Sorting ORs gives          ==> " + format(result));
+                       if (WATCH_PROGRESS) {
+                               System.out.println("Initial pointcut is        ==> " + format(pc));
+                       }
+                       result = distributeNot(result);// checkPC(result);
+                       if (WATCH_PROGRESS) {
+                               System.out.println("Distributing NOT gives     ==> " + format(result));
+                       }
+                       result = pullUpDisjunctions(result);// checkPC(result);
+                       if (WATCH_PROGRESS) {
+                               System.out.println("Pull up disjunctions gives ==> " + format(result));
+                       }
+               } else {
+                       if (WATCH_PROGRESS) {
+                               System.out.println("Not distributing NOTs or pulling up disjunctions, already DNF ==> " + format(pc));
+                       }
+               }
+               result = simplifyAnds(result); // checkPC(result);
+               if (WATCH_PROGRESS) {
+                       System.out.println("Simplifying ANDs gives     ==> " + format(result));
+               }
+               result = removeNothings(result); // checkPC(result);
+               if (WATCH_PROGRESS) {
+                       System.out.println("Removing nothings gives    ==> " + format(result));
+               }
+               result = sortOrs(result); // checkPC(result);
+               if (WATCH_PROGRESS) {
+                       System.out.println("Sorting ORs gives          ==> " + format(result));
+               }
                return result;
        }
-       
-//     /**
-//      * Checks pointcuts - used for debugging.
-//      * - this variant checks if the context has been lost, since
-//      *   that can indicate an NPE will happen later reporting a message (pr162657).
-//      *   Not finished, but helped locate the problem ;)
-//      */
-//     private void checkPC(Pointcut pc) {
-//             if (isNot(pc)) {
-//                     NotPointcut npc = (NotPointcut)pc;
-//                     checkPC(npc.getNegatedPointcut());
-//                     if (npc.getSourceContext()==null) {
-//                             System.out.println("Lost context for "+npc);
-//                             throw new RuntimeException("Lost context");
-//                     }
-//             } else if (isOr(pc)) {
-//                     OrPointcut opc = (OrPointcut)pc;
-//                     checkPC(opc.getLeft());
-//                     checkPC(opc.getRight());
-//                     if (opc.getSourceContext()==null) {
-//                             System.out.println("Lost context for "+opc);
-//                             throw new RuntimeException("Lost context");
-//                     }
-//             } else if (isAnd(pc)) {
-//                     AndPointcut apc = (AndPointcut)pc;
-//                     checkPC(apc.getLeft());
-//                     checkPC(apc.getRight());
-//                     if (apc.getSourceContext()==null) {
-//                             System.out.println("Lost context for "+apc);
-//                             throw new RuntimeException("Lost context");
-//                     }
-//             } else {
-//                     if (pc.getSourceContext()==null) {
-//                             System.out.println("Lost context for "+pc);
-//                             throw new RuntimeException("Lost context");             
-//                     }
-//             }
-//     }
-                               
+
+       // /**
+       // * Checks pointcuts - used for debugging.
+       // * - this variant checks if the context has been lost, since
+       // * that can indicate an NPE will happen later reporting a message (pr162657).
+       // * Not finished, but helped locate the problem ;)
+       // */
+       // private void checkPC(Pointcut pc) {
+       // if (isNot(pc)) {
+       // NotPointcut npc = (NotPointcut)pc;
+       // checkPC(npc.getNegatedPointcut());
+       // if (npc.getSourceContext()==null) {
+       // System.out.println("Lost context for "+npc);
+       // throw new RuntimeException("Lost context");
+       // }
+       // } else if (isOr(pc)) {
+       // OrPointcut opc = (OrPointcut)pc;
+       // checkPC(opc.getLeft());
+       // checkPC(opc.getRight());
+       // if (opc.getSourceContext()==null) {
+       // System.out.println("Lost context for "+opc);
+       // throw new RuntimeException("Lost context");
+       // }
+       // } else if (isAnd(pc)) {
+       // AndPointcut apc = (AndPointcut)pc;
+       // checkPC(apc.getLeft());
+       // checkPC(apc.getRight());
+       // if (apc.getSourceContext()==null) {
+       // System.out.println("Lost context for "+apc);
+       // throw new RuntimeException("Lost context");
+       // }
+       // } else {
+       // if (pc.getSourceContext()==null) {
+       // System.out.println("Lost context for "+pc);
+       // throw new RuntimeException("Lost context");
+       // }
+       // }
+       // }
+
        public Pointcut rewrite(Pointcut pc) {
-               return rewrite(pc,false);
+               return rewrite(pc, false);
        }
-       
+
        /**
-        * Check if a pointcut is in DNF - if it is then it should be lots of 'ORs' up the 
-        * top with 'ANDs' beneath them.
+        * Check if a pointcut is in DNF - if it is then it should be lots of 'ORs' up the top with 'ANDs' beneath them.
         */
        private boolean isDNF(Pointcut pc) {
-               return isDNFHelper(pc,true);
+               return isDNFHelper(pc, true);
        }
-       
+
        /**
-        * Helper function for determining DNFness.  Records when we have crossed the point of allowing ORs.
+        * Helper function for determining DNFness. Records when we have crossed the point of allowing ORs.
         */
-       private boolean isDNFHelper(Pointcut pc,boolean canStillHaveOrs) {
+       private boolean isDNFHelper(Pointcut pc, boolean canStillHaveOrs) {
                if (isAnd(pc)) {
-                       AndPointcut ap = (AndPointcut)pc;
-                       return isDNFHelper(ap.getLeft(),false) && isDNFHelper(ap.getRight(),false);
+                       AndPointcut ap = (AndPointcut) pc;
+                       return isDNFHelper(ap.getLeft(), false) && isDNFHelper(ap.getRight(), false);
                } else if (isOr(pc)) {
-                       if (!canStillHaveOrs) return false;
-                       OrPointcut op = (OrPointcut)pc;
-                       return isDNFHelper(op.getLeft(),true) && isDNFHelper(op.getRight(),true);
+                       if (!canStillHaveOrs) {
+                               return false;
+                       }
+                       OrPointcut op = (OrPointcut) pc;
+                       return isDNFHelper(op.getLeft(), true) && isDNFHelper(op.getRight(), true);
                } else if (isNot(pc)) {
-                       return isDNFHelper(((NotPointcut)pc).getNegatedPointcut(),canStillHaveOrs);
+                       return isDNFHelper(((NotPointcut) pc).getNegatedPointcut(), canStillHaveOrs);
                } else {
                        return true;
                }
        }
-       
-       /** 
+
+       /**
         * Allows formatting of the output pointcut for debugging...
         */
        public static String format(Pointcut p) {
                String s = p.toString();
                // Regex param needs '(' and '*' changing to '.'
-//             s = s.replaceAll("persingleton.pkg1.monitoring.ErrorMonitoring.","M");
-//             s = s.replaceAll("args.BindingTypePattern.java.lang.Throwable, 0.","Z");
-//             s = s.replaceAll("within.pkg1.monitoring.DoMonitorErrors+.","X");
-//             s=s.replaceAll("within.pkg1.monitoring....","Y");
-//             s=s.replaceAll("if.true.","N");
+               // s = s.replaceAll("persingleton.pkg1.monitoring.ErrorMonitoring.","M");
+               // s = s.replaceAll("args.BindingTypePattern.java.lang.Throwable, 0.","Z");
+               // s = s.replaceAll("within.pkg1.monitoring.DoMonitorErrors+.","X");
+               // s=s.replaceAll("within.pkg1.monitoring....","Y");
+               // s=s.replaceAll("if.true.","N");
                return s;
        }
-       
-       
-       
+
        // !!X => X
        // !(X && Y) => !X || !Y
        // !(X || Y) => !X && !Y
@@ -147,43 +158,43 @@ public class PointcutRewriter {
                        Pointcut notBody = distributeNot(npc.getNegatedPointcut());
                        if (isNot(notBody)) {
                                // !!X => X
-                               return ((NotPointcut)notBody).getNegatedPointcut();
+                               return ((NotPointcut) notBody).getNegatedPointcut();
                        } else if (isAnd(notBody)) {
                                // !(X && Y) => !X || !Y
                                AndPointcut apc = (AndPointcut) notBody;
-                               Pointcut newLeft = distributeNot(new NotPointcut(apc.getLeft(),npc.getStart())); 
-                               Pointcut newRight = distributeNot(new NotPointcut(apc.getRight(),npc.getStart()));
-                               return new OrPointcut(newLeft,newRight);
+                               Pointcut newLeft = distributeNot(new NotPointcut(apc.getLeft(), npc.getStart()));
+                               Pointcut newRight = distributeNot(new NotPointcut(apc.getRight(), npc.getStart()));
+                               return new OrPointcut(newLeft, newRight);
                        } else if (isOr(notBody)) {
                                // !(X || Y) => !X && !Y
                                OrPointcut opc = (OrPointcut) notBody;
-                               Pointcut newLeft = distributeNot(new NotPointcut(opc.getLeft(),npc.getStart())); 
-                               Pointcut newRight = distributeNot(new NotPointcut(opc.getRight(),npc.getStart()));
-                               return new AndPointcut(newLeft,newRight);                               
+                               Pointcut newLeft = distributeNot(new NotPointcut(opc.getLeft(), npc.getStart()));
+                               Pointcut newRight = distributeNot(new NotPointcut(opc.getRight(), npc.getStart()));
+                               return new AndPointcut(newLeft, newRight);
                        } else {
-                               return new NotPointcut(notBody,npc.getStart());
+                               return new NotPointcut(notBody, npc.getStart());
                        }
                } else if (isAnd(pc)) {
                        AndPointcut apc = (AndPointcut) pc;
                        Pointcut left = distributeNot(apc.getLeft());
                        Pointcut right = distributeNot(apc.getRight());
-                       return new AndPointcut(left,right);
+                       return new AndPointcut(left, right);
                } else if (isOr(pc)) {
                        OrPointcut opc = (OrPointcut) pc;
                        Pointcut left = distributeNot(opc.getLeft());
                        Pointcut right = distributeNot(opc.getRight());
-                       return new OrPointcut(left,right);
+                       return new OrPointcut(left, right);
                } else {
                        return pc;
                }
        }
-       
+
        // A && (B || C) => (A && B) || (A && C)
        // (A || B) && C => (A && C) || (B && C)
        private Pointcut pullUpDisjunctions(Pointcut pc) {
                if (isNot(pc)) {
-                       NotPointcut npc = (NotPointcut)pc;
-                                               return new NotPointcut(pullUpDisjunctions(npc.getNegatedPointcut()));
+                       NotPointcut npc = (NotPointcut) pc;
+                       return new NotPointcut(pullUpDisjunctions(npc.getNegatedPointcut()));
                } else if (isAnd(pc)) {
                        AndPointcut apc = (AndPointcut) pc;
                        // dive into left and right here...
@@ -191,250 +202,242 @@ public class PointcutRewriter {
                        Pointcut right = pullUpDisjunctions(apc.getRight());
                        if (isOr(left) && !isOr(right)) {
                                // (A || B) && C => (A && C) || (B && C)
-                               Pointcut leftLeft = ((OrPointcut)left).getLeft();
-                               Pointcut leftRight = ((OrPointcut)left).getRight();
-                               return pullUpDisjunctions(
-                                                       new OrPointcut(
-                                                                       new AndPointcut(leftLeft,right),
-                                                                       new AndPointcut(leftRight,right))
-                                                       );
+                               Pointcut leftLeft = ((OrPointcut) left).getLeft();
+                               Pointcut leftRight = ((OrPointcut) left).getRight();
+                               return pullUpDisjunctions(new OrPointcut(new AndPointcut(leftLeft, right), new AndPointcut(leftRight, right)));
                        } else if (isOr(right) && !isOr(left)) {
                                // A && (B || C) => (A && B) || (A && C)
-                               Pointcut rightLeft = ((OrPointcut)right).getLeft();
-                               Pointcut rightRight = ((OrPointcut)right).getRight();
-                               return pullUpDisjunctions(
-                                                       new OrPointcut(
-                                                                       new AndPointcut(left,rightLeft),
-                                                                       new AndPointcut(left,rightRight))
-                                                       );
-                       }  else if (isOr(right) && isOr(left)) {
+                               Pointcut rightLeft = ((OrPointcut) right).getLeft();
+                               Pointcut rightRight = ((OrPointcut) right).getRight();
+                               return pullUpDisjunctions(new OrPointcut(new AndPointcut(left, rightLeft), new AndPointcut(left, rightRight)));
+                       } else if (isOr(right) && isOr(left)) {
                                // (A || B) && (C || D) => (A && C) || (A && D) || (B && C) || (B && D)
-                               Pointcut A = pullUpDisjunctions(((OrPointcut)left).getLeft());
-                               Pointcut B = pullUpDisjunctions(((OrPointcut)left).getRight());
-                               Pointcut C = pullUpDisjunctions(((OrPointcut)right).getLeft());
-                               Pointcut D = pullUpDisjunctions(((OrPointcut)right).getRight());
-                               Pointcut newLeft = new OrPointcut(
-                                                                               new AndPointcut(A,C),
-                                                                               new AndPointcut(A,D)
-                                                                       );
-                               Pointcut newRight = new OrPointcut(
-                                                              new AndPointcut(B,C),
-                                                              new AndPointcut(B,D)
-                                                          );                           
-                               return pullUpDisjunctions(new OrPointcut(newLeft,newRight));
-                       }       else {
-                               return new AndPointcut(left,right);
+                               Pointcut A = pullUpDisjunctions(((OrPointcut) left).getLeft());
+                               Pointcut B = pullUpDisjunctions(((OrPointcut) left).getRight());
+                               Pointcut C = pullUpDisjunctions(((OrPointcut) right).getLeft());
+                               Pointcut D = pullUpDisjunctions(((OrPointcut) right).getRight());
+                               Pointcut newLeft = new OrPointcut(new AndPointcut(A, C), new AndPointcut(A, D));
+                               Pointcut newRight = new OrPointcut(new AndPointcut(B, C), new AndPointcut(B, D));
+                               return pullUpDisjunctions(new OrPointcut(newLeft, newRight));
+                       } else {
+                               return new AndPointcut(left, right);
                        }
-               } else if (isOr(pc)){
+               } else if (isOr(pc)) {
                        OrPointcut opc = (OrPointcut) pc;
-                       return new OrPointcut(pullUpDisjunctions(opc.getLeft()),
-                                                     pullUpDisjunctions(opc.getRight()));
+                       return new OrPointcut(pullUpDisjunctions(opc.getLeft()), pullUpDisjunctions(opc.getRight()));
                } else {
                        return pc;
                }
        }
-       
+
        /**
         * Returns a NOTted form of the pointcut p - we cope with already NOTted pointcuts.
         */
        public Pointcut not(Pointcut p) {
                if (isNot(p)) {
-                       return ((NotPointcut)p).getNegatedPointcut();
+                       return ((NotPointcut) p).getNegatedPointcut();
                }
                return new NotPointcut(p);
        }
-       
+
        /**
         * Passed an array of pointcuts, returns an AND tree with them in.
         */
        public Pointcut createAndsFor(Pointcut[] ps) {
-               if (ps.length==1) return ps[0]; // dumb case
-               if (ps.length==2) { // recursion exit case
-                       return new AndPointcut(ps[0],ps[1]);
+               if (ps.length == 1) {
+                       return ps[0]; // dumb case
+               }
+               if (ps.length == 2) { // recursion exit case
+                       return new AndPointcut(ps[0], ps[1]);
                }
                // otherwise ...
-               Pointcut[] subset = new Pointcut[ps.length-1];
+               Pointcut[] subset = new Pointcut[ps.length - 1];
                for (int i = 1; i < ps.length; i++) {
-                       subset[i-1]=ps[i];
+                       subset[i - 1] = ps[i];
                }
-               return new AndPointcut(ps[0],createAndsFor(subset));
+               return new AndPointcut(ps[0], createAndsFor(subset));
        }
 
-       
        // NOT: execution(* TP.*(..)) => within(TP) && execution(* *(..))
-       //      since this breaks when the pattern matches an interface
+       // since this breaks when the pattern matches an interface
        // NOT: withincode(* TP.*(..)) => within(TP) && withincode(* *(..))
-       //      since this is not correct when an aspect makes an ITD
-//     private Pointcut splitOutWithins(Pointcut pc) {
-//             if (isExecution(pc)) {
-//                     KindedPointcut kpc = (KindedPointcut) pc;
-//                     SignaturePattern sp = kpc.signature;
-//                     TypePattern within = sp.getDeclaringType();
-//                     if (isAnyType(within)) return pc;
-//                     SignaturePattern simplified = removeDeclaringTypePattern(sp);
-//                     return new AndPointcut(new WithinPointcut(within),
-//                                                    new KindedPointcut(kpc.kind,simplified));
-//             } else if (isNot(pc)) {
-//                     return new NotPointcut(splitOutWithins(((NotPointcut)pc).getNegatedPointcut()));
-//             } else if (isAnd(pc)) {
-//                     AndPointcut apc = (AndPointcut) pc;
-//                     return new AndPointcut(splitOutWithins(apc.getLeft()),
-//                                                    splitOutWithins(apc.getRight()));
-//             } else if (isOr(pc)) {
-//                     OrPointcut opc = (OrPointcut) pc;
-//                     return new OrPointcut(splitOutWithins(opc.getLeft()),
-//                                                           splitOutWithins(opc.getRight()));
-//             } else {
-//                     return pc;
-//             }
-//     }
-       
-//     private SignaturePattern removeDeclaringTypePattern(SignaturePattern sp) {
-//             return new SignaturePattern(
-//               sp.getKind(),
-//               sp.getModifiers(),
-//               sp.getReturnType(),
-//               TypePattern.ANY,
-//               sp.getName(),
-//               sp.getParameterTypes(),
-//               sp.getThrowsPattern(),
-//               sp.getAnnotationPattern()
-//             );
-//     }
+       // since this is not correct when an aspect makes an ITD
+       // private Pointcut splitOutWithins(Pointcut pc) {
+       // if (isExecution(pc)) {
+       // KindedPointcut kpc = (KindedPointcut) pc;
+       // SignaturePattern sp = kpc.signature;
+       // TypePattern within = sp.getDeclaringType();
+       // if (isAnyType(within)) return pc;
+       // SignaturePattern simplified = removeDeclaringTypePattern(sp);
+       // return new AndPointcut(new WithinPointcut(within),
+       // new KindedPointcut(kpc.kind,simplified));
+       // } else if (isNot(pc)) {
+       // return new NotPointcut(splitOutWithins(((NotPointcut)pc).getNegatedPointcut()));
+       // } else if (isAnd(pc)) {
+       // AndPointcut apc = (AndPointcut) pc;
+       // return new AndPointcut(splitOutWithins(apc.getLeft()),
+       // splitOutWithins(apc.getRight()));
+       // } else if (isOr(pc)) {
+       // OrPointcut opc = (OrPointcut) pc;
+       // return new OrPointcut(splitOutWithins(opc.getLeft()),
+       // splitOutWithins(opc.getRight()));
+       // } else {
+       // return pc;
+       // }
+       // }
+
+       // private SignaturePattern removeDeclaringTypePattern(SignaturePattern sp) {
+       // return new SignaturePattern(
+       // sp.getKind(),
+       // sp.getModifiers(),
+       // sp.getReturnType(),
+       // TypePattern.ANY,
+       // sp.getName(),
+       // sp.getParameterTypes(),
+       // sp.getThrowsPattern(),
+       // sp.getAnnotationPattern()
+       // );
+       // }
 
        // this finds the root of each && tree and then aggregates all of the branches
        // into a sorted set:
-       //   - duplicates are removed
-       //   - A && !A is replaced by a matchesNothingPointcut
-       //   - the kind(s) matched by the set are evaluated
-       //   - elements are sorted by evaluation complexity
-       //   - the result is written out with the least expensive branch leftmost
+       // - duplicates are removed
+       // - A && !A is replaced by a matchesNothingPointcut
+       // - the kind(s) matched by the set are evaluated
+       // - elements are sorted by evaluation complexity
+       // - the result is written out with the least expensive branch leftmost
        private Pointcut simplifyAnds(Pointcut pc) {
                if (isNot(pc)) {
                        NotPointcut npc = (NotPointcut) pc;
                        Pointcut notBody = npc.getNegatedPointcut();
                        if (isNot(notBody)) {
                                // !!X => X
-                               return simplifyAnds(((NotPointcut)notBody).getNegatedPointcut());
+                               return simplifyAnds(((NotPointcut) notBody).getNegatedPointcut());
                        } else {
-                                                       return new NotPointcut(simplifyAnds(npc.getNegatedPointcut()));
+                               return new NotPointcut(simplifyAnds(npc.getNegatedPointcut()));
                        }
                } else if (isOr(pc)) {
                        OrPointcut opc = (OrPointcut) pc;
-                       return new OrPointcut(simplifyAnds(opc.getLeft()),simplifyAnds(opc.getRight()));
+                       return new OrPointcut(simplifyAnds(opc.getLeft()), simplifyAnds(opc.getRight()));
                } else if (isAnd(pc)) {
-                       return simplifyAnd((AndPointcut)pc);
+                       return simplifyAnd((AndPointcut) pc);
                } else {
                        return pc;
                }
        }
-       
+
        private Pointcut simplifyAnd(AndPointcut apc) {
                SortedSet nodes = new TreeSet(new PointcutEvaluationExpenseComparator());
-               collectAndNodes(apc,nodes);
+               collectAndNodes(apc, nodes);
                // look for A and !A, or IfFalse
                for (Iterator iter = nodes.iterator(); iter.hasNext();) {
                        Pointcut element = (Pointcut) iter.next();
                        if (element instanceof NotPointcut) {
-                               Pointcut body = ((NotPointcut)element).getNegatedPointcut();
-                               if (nodes.contains(body)) return Pointcut.makeMatchesNothing(body.state);
+                               Pointcut body = ((NotPointcut) element).getNegatedPointcut();
+                               if (nodes.contains(body)) {
+                                       return Pointcut.makeMatchesNothing(body.state);
+                               }
                        }
                        if (element instanceof IfPointcut) {
-                               if (((IfPointcut)element).alwaysFalse()) return Pointcut.makeMatchesNothing(element.state);
+                               if (((IfPointcut) element).alwaysFalse()) {
+                                       return Pointcut.makeMatchesNothing(element.state);
+                               }
                        }
                        // If it can't match anything, the whole AND can't match anything
-                       if (element.couldMatchKinds()==Shadow.NO_SHADOW_KINDS_BITS) return element;
+                       if (element.couldMatchKinds() == Shadow.NO_SHADOW_KINDS_BITS) {
+                               return element;
+                       }
+               }
+               if (apc.couldMatchKinds() == Shadow.NO_SHADOW_KINDS_BITS) {
+                       return Pointcut.makeMatchesNothing(apc.state);
                }
-               if (apc.couldMatchKinds()==Shadow.NO_SHADOW_KINDS_BITS) return Pointcut.makeMatchesNothing(apc.state);
                // write out with cheapest on left
                Iterator iter = nodes.iterator();
                Pointcut result = (Pointcut) iter.next();
-               while(iter.hasNext()) {
+               while (iter.hasNext()) {
                        Pointcut right = (Pointcut) iter.next();
-                       result = new AndPointcut(result,right);
+                       result = new AndPointcut(result, right);
                }
                return result;
        }
-       
+
        private Pointcut sortOrs(Pointcut pc) {
                SortedSet nodes = new TreeSet(new PointcutEvaluationExpenseComparator());
-               collectOrNodes(pc,nodes);               
+               collectOrNodes(pc, nodes);
                // write out with cheapest on left
                Iterator iter = nodes.iterator();
                Pointcut result = (Pointcut) iter.next();
-               while(iter.hasNext()) {
+               while (iter.hasNext()) {
                        Pointcut right = (Pointcut) iter.next();
-                       result = new OrPointcut(result,right);
+                       result = new OrPointcut(result, right);
                }
                return result;
        }
-       
+
        /**
         * Removes MATCHES_NOTHING pointcuts
         */
        private Pointcut removeNothings(Pointcut pc) {
                if (isAnd(pc)) {
-                       AndPointcut apc = (AndPointcut)pc;
+                       AndPointcut apc = (AndPointcut) pc;
                        Pointcut right = removeNothings(apc.getRight());
-                       Pointcut left  = removeNothings(apc.getLeft());
-                       if (left instanceof MatchesNothingPointcut || right instanceof MatchesNothingPointcut) return new MatchesNothingPointcut();
-                       return new AndPointcut(left,right);
+                       Pointcut left = removeNothings(apc.getLeft());
+                       if (left instanceof MatchesNothingPointcut || right instanceof MatchesNothingPointcut) {
+                               return new MatchesNothingPointcut();
+                       }
+                       return new AndPointcut(left, right);
                } else if (isOr(pc)) {
-                       OrPointcut opc = (OrPointcut)pc;
+                       OrPointcut opc = (OrPointcut) pc;
                        Pointcut right = removeNothings(opc.getRight());
-                       Pointcut left  = removeNothings(opc.getLeft());
-                       if (left instanceof MatchesNothingPointcut 
-                                       && !(right instanceof MatchesNothingPointcut)) {
+                       Pointcut left = removeNothings(opc.getLeft());
+                       if (left instanceof MatchesNothingPointcut && !(right instanceof MatchesNothingPointcut)) {
                                return right;
-                       } else if (right instanceof MatchesNothingPointcut 
-                                       && !(left instanceof MatchesNothingPointcut)) {
+                       } else if (right instanceof MatchesNothingPointcut && !(left instanceof MatchesNothingPointcut)) {
                                return left;
-                       } else if (!(left instanceof MatchesNothingPointcut)
-                                       && !(right instanceof MatchesNothingPointcut)) {
-                               return new OrPointcut(left,right);
-                       } else if (left instanceof MatchesNothingPointcut
-                                       && right instanceof MatchesNothingPointcut) {
-                               return new MatchesNothingPointcut();    
-                       }                       
+                       } else if (!(left instanceof MatchesNothingPointcut) && !(right instanceof MatchesNothingPointcut)) {
+                               return new OrPointcut(left, right);
+                       } else if (left instanceof MatchesNothingPointcut && right instanceof MatchesNothingPointcut) {
+                               return new MatchesNothingPointcut();
+                       }
                }
                return pc;
        }
-       
-       private void collectAndNodes(AndPointcut apc,Set nodesSoFar) {
+
+       private void collectAndNodes(AndPointcut apc, Set nodesSoFar) {
                Pointcut left = apc.getLeft();
                Pointcut right = apc.getRight();
                if (isAnd(left)) {
-                       collectAndNodes((AndPointcut)left,nodesSoFar);
+                       collectAndNodes((AndPointcut) left, nodesSoFar);
                } else {
                        nodesSoFar.add(left);
                }
                if (isAnd(right)) {
-                       collectAndNodes((AndPointcut)right,nodesSoFar);
+                       collectAndNodes((AndPointcut) right, nodesSoFar);
                } else {
                        nodesSoFar.add(right);
-               }               
+               }
        }
-       
+
        private void collectOrNodes(Pointcut pc, Set nodesSoFar) {
                if (isOr(pc)) {
                        OrPointcut opc = (OrPointcut) pc;
-                       collectOrNodes(opc.getLeft(),nodesSoFar);
-                       collectOrNodes(opc.getRight(),nodesSoFar);
+                       collectOrNodes(opc.getLeft(), nodesSoFar);
+                       collectOrNodes(opc.getRight(), nodesSoFar);
                } else {
                        nodesSoFar.add(pc);
                }
        }
-       
+
        private boolean isNot(Pointcut pc) {
                return (pc instanceof NotPointcut);
        }
-       
+
        private boolean isAnd(Pointcut pc) {
                return (pc instanceof AndPointcut);
        }
-       
+
        private boolean isOr(Pointcut pc) {
                return (pc instanceof OrPointcut);
        }
-       
+
 }
\ No newline at end of file