]> source.dussan.org Git - aspectj.git/commitdiff
fix for Bugzilla Bug 48990
authoracolyer <acolyer>
Wed, 28 Jul 2004 15:13:09 +0000 (15:13 +0000)
committeracolyer <acolyer>
Wed, 28 Jul 2004 15:13:09 +0000 (15:13 +0000)
  Special case if(false) to not require a dynamic test

org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/IfPseudoToken.java
tests/ajcTests.xml
tests/new/IfFalse.aj [new file with mode: 0644]
tests/new/IfTrue.aj [new file with mode: 0644]
weaver/src/org/aspectj/weaver/patterns/IfPointcut.java
weaver/src/org/aspectj/weaver/patterns/Pointcut.java

index 71f4b41a48e1ce4de494d511a662d2fa8848f2bf..573177d24594d4936b8cb318ef2afe973773fc8b 100644 (file)
@@ -23,9 +23,11 @@ import org.aspectj.weaver.patterns.Pointcut;
 import org.eclipse.jdt.internal.compiler.CompilationResult;
 import org.eclipse.jdt.internal.compiler.ast.Argument;
 import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.FalseLiteral;
 import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
 import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
 import org.eclipse.jdt.internal.compiler.ast.Statement;
+import org.eclipse.jdt.internal.compiler.ast.TrueLiteral;
 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
 import org.eclipse.jdt.internal.compiler.parser.Parser;
@@ -64,8 +66,15 @@ public class IfPseudoToken extends PseudoToken {
        }
        
        public Pointcut maybeGetParsedPointcut() {
-               pointcut = new IfPointcut(new ResolvedMember(Member.METHOD, TypeX.OBJECT, 0, "if_", "()V"), 0);
+               if (expr instanceof FalseLiteral) {
+                       return IfPointcut.makeIfFalsePointcut(Pointcut.SYMBOLIC);
+               } else if (expr instanceof TrueLiteral) {
+                       return IfPointcut.makeIfTruePointcut(Pointcut.SYMBOLIC);
+               } else {
+                 pointcut = new IfPointcut(new ResolvedMember(Member.METHOD, TypeX.OBJECT, 0, "if_", "()V"), 0);
+               }
                return pointcut;
+               
        }
 
 
index f76405da30ea2071154f6b4e8a4a2c9df8627566..96bdd14c586282256a570799727c230d85f500bf 100644 (file)
              text="void Subclass.nonstaticMethod() cannot override void Superclass.nonstaticMethod(); overriding method is static"/>
         </compile>
     </ajc-test>
+   
+      <ajc-test dir="new"
+      title="if(false) optimisation" pr="48990">
+        <compile files="IfFalse.aj"/>
+        <run class="IfFalse"/>
+    </ajc-test>
+   
+    <ajc-test dir="new"
+      title="if(true) optimisation" pr="48990">
+        <compile files="IfTrue.aj"/>
+        <run class="IfTrue"/>
+    </ajc-test> 
     
     <ajc-test dir="bugs/abstractITDs"
                pr="64331" title="java.lang.NullPointerException in WeaverMessageHandler class">
diff --git a/tests/new/IfFalse.aj b/tests/new/IfFalse.aj
new file mode 100644 (file)
index 0000000..6b1b8d4
--- /dev/null
@@ -0,0 +1,37 @@
+import org.aspectj.testing.Tester;
+
+public aspect  IfFalse {
+       
+       private static boolean x = false;
+       
+       pointcut p1() : if(false);
+       
+       pointcut p2() : if(  false  );
+       
+       pointcut p3() : if(x);
+       
+       pointcut p4() : within(IfFalse) && if(false);
+       
+       
+       after() returning : p1() {
+               // should never get here
+               Tester.checkFailed("if(false) matched!");
+       }
+
+       after() returning : p2() {
+               // should never get here
+               Tester.checkFailed("if(   false   ) matched!");
+       }
+
+       after() returning : p3() {
+               // should never get here
+               Tester.checkFailed("if(x) matched!");
+       }
+
+       after() returning : p4() {
+               // should never get here
+               Tester.checkFailed("if(false) matched!");
+       }
+       
+       public static void main(String[] args) {}
+}
\ No newline at end of file
diff --git a/tests/new/IfTrue.aj b/tests/new/IfTrue.aj
new file mode 100644 (file)
index 0000000..afbbdb4
--- /dev/null
@@ -0,0 +1,37 @@
+import org.aspectj.testing.Tester;
+
+public aspect  IfTrue {
+       
+       private static boolean x = true;
+       
+       pointcut p1() : !if(true);
+       
+       pointcut p2() : !if(  true  );
+       
+       pointcut p3() : !if(x) && execution(* *(..));
+       
+       pointcut p4() : within(IfTrue) && !if(true);
+       
+       
+       after() returning : p1() {
+               // should never get here
+               Tester.checkFailed("!if(true) matched!");
+       }
+
+       after() returning : p2() {
+               // should never get here
+               Tester.checkFailed("!if(   true   ) matched!");
+       }
+
+       after() returning : p3() {
+               // should never get here
+               Tester.checkFailed("!if(x) matched!");
+       }
+
+       after() returning : p4() {
+               // should never get here
+               Tester.checkFailed("!if(true) matched!");
+       }
+       
+       public static void main(String[] args) {}
+}
\ No newline at end of file
index e770509b379693fb2536e29e50de8d59cd9b6cb9..43f11ec28b31d764633af63e3f68c37960fcf0b2 100644 (file)
@@ -20,6 +20,7 @@ import java.util.ArrayList;
 import java.util.List;
 
 import org.aspectj.bridge.IMessage;
+import org.aspectj.lang.JoinPoint;
 import org.aspectj.util.FuzzyBoolean;
 import org.aspectj.weaver.Advice;
 import org.aspectj.weaver.ISourceContext;
@@ -204,4 +205,139 @@ public class IfPointcut extends Pointcut {
                return ret;
        }
 
+//     public static Pointcut MatchesNothing = new MatchesNothingPointcut();
+//     ??? there could possibly be some good optimizations to be done at this point
+       public static IfPointcut makeIfFalsePointcut(State state) {
+               IfPointcut ret = new IfFalsePointcut();
+               ret.state = state;
+               return ret;
+       }
+
+       private static class IfFalsePointcut extends IfPointcut {
+               
+               public IfFalsePointcut() {
+                       super(null,0);
+               }
+               
+               public Test findResidue(Shadow shadow, ExposedState state) {
+                       return Literal.FALSE; // can only get here if an earlier error occurred
+               }
+
+               public FuzzyBoolean fastMatch(FastMatchInfo type) {
+                       return FuzzyBoolean.NO;
+               }
+               
+               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) {
+               }
+
+               public Pointcut concretize1(
+                       ResolvedTypeX inAspect,
+                       IntMap bindings) {
+                       if (isDeclare(bindings.getEnclosingAdvice())) {
+                               // Enforce rule about which designators are supported in declare
+                               inAspect.getWorld().showMessage(IMessage.ERROR,
+                                 "if() pointcut designator cannot be used in declare statement",
+                                 bindings.getEnclosingAdvice().getSourceLocation(),
+                                 null);
+                               return Pointcut.makeMatchesNothing(Pointcut.CONCRETE);
+                       }
+                       return makeIfFalsePointcut(state);
+               }
+
+
+               public void write(DataOutputStream s) throws IOException {
+                       s.writeByte(Pointcut.IF_FALSE);
+               }
+               
+           public int hashCode() {
+               int result = 17;
+               return result;
+           }
+               
+           public String toString() {
+                       return "if(false)";
+               }       
+       }
+
+       public static IfPointcut makeIfTruePointcut(State state) {
+               IfPointcut ret = new IfTruePointcut();
+               ret.state = state;
+               return ret;
+       }
+
+       private static class IfTruePointcut extends IfPointcut {                
+                       
+               public IfTruePointcut() {
+                       super(null,0);
+               }
+               
+               public Test findResidue(Shadow shadow, ExposedState state) {
+                       return Literal.TRUE; // can only get here if an earlier error occurred
+               }
+
+               public FuzzyBoolean fastMatch(FastMatchInfo type) {
+                       return FuzzyBoolean.YES;
+               }
+               
+               public FuzzyBoolean match(Shadow shadow) {
+                       return FuzzyBoolean.YES;
+               }
+               
+               public FuzzyBoolean match(JoinPoint.StaticPart jpsp) {
+                       return FuzzyBoolean.YES;
+               }
+
+               public void resolveBindings(IScope scope, Bindings bindings) {
+               }
+               
+               public void resolveBindingsFromRTTI() {
+               }
+
+               public void postRead(ResolvedTypeX enclosingType) {
+               }
+
+               public Pointcut concretize1(
+                       ResolvedTypeX inAspect,
+                       IntMap bindings) {
+                       if (isDeclare(bindings.getEnclosingAdvice())) {
+                               // Enforce rule about which designators are supported in declare
+                               inAspect.getWorld().showMessage(IMessage.ERROR,
+                                 "if() pointcut designator cannot be used in declare statement",
+                                 bindings.getEnclosingAdvice().getSourceLocation(),
+                                 null);
+                               return Pointcut.makeMatchesNothing(Pointcut.CONCRETE);
+                       }
+                       return makeIfTruePointcut(state);
+               }
+
+
+               public void write(DataOutputStream s) throws IOException {
+                       s.writeByte(IF_TRUE);
+               }
+               
+           public int hashCode() {
+               int result = 37;
+               return result;
+           }
+               
+           public String toString() {
+                       return "if(true)";
+               }       
+       }
+
 }
+
index 46636313522b2c3b87d9f642236c4d03bf6e6830..31afd6039f8f21b4c0fcf1f3c7b4f8b10b380b26 100644 (file)
@@ -103,6 +103,8 @@ public abstract class Pointcut extends PatternNode {
        public static final byte CFLOW = 10;
        public static final byte WITHINCODE = 12;
        public static final byte HANDLER = 13;
+       public static final byte IF_TRUE = 14;
+       public static final byte IF_FALSE = 15;
        
        public static final byte NONE = 20;
 
@@ -217,6 +219,8 @@ public abstract class Pointcut extends PatternNode {
                        case CFLOW: ret = CflowPointcut.read(s, context); break;
                        case WITHINCODE: ret = WithincodePointcut.read(s, context); break;
                        case HANDLER: ret = HandlerPointcut.read(s, context); break;
+                       case IF_TRUE: ret = IfPointcut.makeIfTruePointcut(RESOLVED); break;
+                       case IF_FALSE: ret = IfPointcut.makeIfFalsePointcut(RESOLVED); break;
                        
                        case NONE: ret = makeMatchesNothing(RESOLVED); break;
                        default:
@@ -283,7 +287,8 @@ public abstract class Pointcut extends PatternNode {
        ret.state = state;
        return ret;
     }
-    
+
        public void assertState(State state) {
                if (this.state != state) {
                        throw new BCException("expected state: " + state + " got: " + this.state);