Bug 153464 - negated annotation type pattern fails
Summary: negated annotation type pattern fails
Status: NEW
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: 1.5.2   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: aspectj inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-08-10 12:31 EDT by Wes Isberg CLA
Modified: 2008-08-22 16:12 EDT (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Wes Isberg CLA 2006-08-10 12:31:03 EDT
!within(@Annot *) works to exclude annotated classes, but within(!@Annot *) does not, though permitted syntactically in the AspectJ 5 developers guide.

 http://www.eclipse.org/aspectj/doc/released/adk15notebook/annotations-pointcuts-and-advice.html#type-patterns

(Taken from excellent user-list email "Combination of Class Annotation and Method Annotation matching" by Takao Nakaguchi.)

--------------------------------------------------

package ajsandbox;

public class AnnotTest {
    public static aspect TestAspect {
        // works - Derived.func() omitted
        //declare warning : execution(@Annot * *(..)) && !within(@Annot *): "hi!";
        
        // fails - Derived.func() not omitted
        declare warning : execution(@Annot * *(..)) && within(!@Annot *)
            : "unexpected warning";
    }

    @interface Annot {
    };

    class Base {
        void func() {
        }
    }

    @Annot
    class Derived extends Base {
        // ok! and ng!
        @Annot
        void func() {
        }
    }

    class NoAnnotClass {
        // ng!
        @Annot
        void func() {
        }
    }
}
Comment 1 Andrew Clement CLA 2006-09-25 10:55:05 EDT
interesting program.

The reason this pointcut 

execution(@Annot * *(..)) && within(!@Annot *)

matches against the first type is because of the use of an inner type.

class AnnotTest {
  @Annot
  class Derived extends Base {
    @Annot void func() { }
  }
}

the method-execution of func() does kind of occur 'within' a non-annotated type, the AnnotTest type.  If we annotate AnnotTest like this:

@Annot
class AnnotTest {
  @Annot
  class Derived extends Base {
    @Annot void func() { }
  }
}

then the pointcut no longer matches.

So we have to think about the difference between: "!within(@Annot *)" and "within(!Annot *)".  The first says "match join points that are not within an @Annot annotated type", the second says "match joinpoints that are within a non-@Annot annotated type".
Comment 2 Andrew Clement CLA 2006-09-25 10:57:36 EDT
testcase is committed but commented out