--- /dev/null
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+@Target({ElementType.METHOD})
+@interface MethodAnnotation{}
+
+@Target({ElementType.FIELD})
+@interface FieldAnnotation{}
+
+public class AndTypePattern {
+
+ public void method1() {}
+
+ @FieldAnnotation
+ int field = 1;
+
+}
+
+aspect A {
+
+ // should display an xlint message because @FieldAnnotation can't be
+ // applied to methods
+ pointcut andPointcut() : execution(@(FieldAnnotation && MethodAnnotation) * *(..));
+ declare warning : andPointcut() : "andPointcut()";
+
+}
--- /dev/null
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+@Target({ElementType.TYPE})
+@interface TypeAnnotation{}
+
+@Target({ElementType.METHOD})
+@interface MethodAnnotation{}
+
+@TypeAnnotation
+public class AnnotationDeclaringType {
+
+ public void method1() {
+ }
+
+}
+
+aspect A {
+
+ // matches the execution of any method where the declaring type
+ // has the @TypeAnnotation - should compile ok and get no xlint errors
+ pointcut pc() : execution(* (@TypeAnnotation *).*(..));
+ declare warning : pc() : "* (@TypeAnnotation *).*(..)";
+
+ // should get an xlint warning because declaring types can only
+ // have the default @Target or @Target{ElementType.TYPE} target
+ pointcut pc2() : execution(* (@MethodAnnotation *).*(..));
+ declare warning : pc2() : "* (@MethodAnnotation *).*(..)";
+}
--- /dev/null
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+@Target({ElementType.TYPE})
+@interface TypeAnnotation{}
+
+@Target({ElementType.METHOD})
+@interface MethodAnnotation{}
+
+public class AnnotationParameterType {
+
+ public void method1(MyClass m) {
+ }
+
+}
+
+@TypeAnnotation
+class MyClass {
+
+}
+
+aspect A {
+
+ // shouldn't get an xlint warning because looking method which
+ // takes an argument that has the @TypeAnnotation
+ pointcut pc() : execution(* *(@TypeAnnotation *));
+ declare warning : pc() : "* *(@TypeAnnotation *)";
+
+ // should get an xlint warning because can only have the default,
+ // or @Target{ElementType.TYPE} as an argument type
+ pointcut incorrectArgumentType() : execution(* *(@MethodAnnotation *));
+ declare warning : incorrectArgumentType() : "argument type can only have @Target{ElementType.TYPE}";
+
+}
--- /dev/null
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+@Target({ElementType.TYPE})
+@interface TypeAnnotation{}
+
+@Target({ElementType.METHOD})
+@interface MethodAnnotation{}
+
+public class AnnotationReturnType {
+
+ public MyClass method1() {
+ return new MyClass();
+ }
+
+}
+
+@TypeAnnotation
+class MyClass {
+
+}
+
+aspect A {
+
+ // shouldn't get an xlint warning because looking for a return type
+ // which has the @TypeAnnotation annotation
+ pointcut pc() : execution((@TypeAnnotation *) *(..));
+ declare warning : pc() : "(@TypeAnnotation *) *(..)";
+
+ // should get an xlint warning because can only have the default,
+ // or @Target{ElementType.TYPE} as a return type
+ pointcut incorrectReturnType() : execution((@MethodAnnotation *) *(..));
+ declare warning : incorrectReturnType() : "return type can only have @Target{ElementType.TYPE}";
+
+ // should get an xlint warning because @MethodAnnotation can never match
+ // but also get a declare warning because the @TypeAnnotation matches
+ pointcut orPointcut() : execution((@(TypeAnnotation || MethodAnnotation) *) *(..));
+ declare warning : orPointcut() : "(@(TypeAnnotation || MethodAnnotation) *) *(..)";
+
+}
--- /dev/null
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+@Target({ElementType.TYPE})
+@interface TypeAnnotation{}
+
+@Target({ElementType.METHOD})
+@interface MethodAnnotation{}
+
+public class AnnotationThrowsPattern {
+
+ public void method1() throws MyException {}
+
+ public void method2() throws MyNonAnnotatedException {}
+
+}
+
+@TypeAnnotation
+class MyException extends Exception {
+
+}
+
+class MyNonAnnotatedException extends Exception {
+
+}
+
+aspect A {
+
+ // shouldn't get xlint warnings because @TypeAnnotation is allowed
+ pointcut required() : execution(* *.*(..) throws (@TypeAnnotation *));
+ declare warning : required() : "(* *.*(..) throws (@TypeAnnotation *))";
+
+ // shouldn't get xlint warnings because @TypeAnnotation is allowed
+ pointcut forbidden() : execution(* *.*(..) throws !(@TypeAnnotation *));
+ declare warning : forbidden() : "(* *.*(..) throws !(@TypeAnnotation *))";
+
+ // should get an xlint warning here because can only have
+ // annotations with @Target{ElementType.TYPE} or the default
+ // @Target (which is everything)
+ pointcut required1() : execution(* *.*(..) throws (@MethodAnnotation *));
+ declare warning : required1() : "* *.*(..) throws (@MethodAnnotation *)";
+
+ // should get an xlint warning here because can only have
+ // annotations with @Target{ElementType.TYPE} or the default
+ // @Target (which is everything)
+ pointcut forbidden1() : execution(* *.*(..) throws !(@MethodAnnotation *));
+ declare warning : forbidden1() : "* *.*(..) throws !(@MethodAnnotation *)";
+
+}
--- /dev/null
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+@Target({ElementType.TYPE})
+@interface TypeAnnotation{}
+
+@Target({ElementType.METHOD})
+@interface MethodAnnotation{}
+
+@Target({ElementType.FIELD})
+@interface FieldAnnotation{}
+
+@interface AnyAnnotation{}
+
+public class ExactAnnotationTypePattern {
+
+ public void method1() {}
+
+ @FieldAnnotation
+ int field = 1;
+
+}
+
+aspect A {
+
+ // an xlint message should be displayed because @TypeAnnotation can only
+ // be applied to types, not methods
+ pointcut typePC() : execution(@TypeAnnotation * ExactAnnotationTypePattern.method1(..));
+ declare warning : typePC() : "blah";
+
+ // should compile as normal, since @MethodAnnotation can be applied to methods
+ pointcut methodPC() : execution(@MethodAnnotation * ExactAnnotationTypePattern.method1(..));
+ declare warning : methodPC() : "blah";
+
+ // an xlint message should be displayed because @FieldAnnotation can only
+ // be applied to fields, not methods
+ pointcut matchAll() : execution(@FieldAnnotation * *(..));
+ declare warning : matchAll() : "blah";
+
+ // should compile as normal since @FieldAnnotation can be applied to fields
+ pointcut legalFieldPC() : set(@FieldAnnotation int ExactAnnotationTypePattern.field);
+ declare warning : legalFieldPC() : "field blah";
+
+ // an xlint message should be displayed because @MethodAnnotation can
+ // only be applied to methods, not fields
+ pointcut illegalFieldPC() : set(@MethodAnnotation int *);
+ declare warning : illegalFieldPC() : "field blah blah";
+
+ // no xlint message should be displayed here because @AnyAnnotation
+ // has the default target
+ pointcut anyAnnotation() : execution(@AnyAnnotation * *(..));
+ declare warning : anyAnnotation() : "default target is allowed everywhere";
+
+}
--- /dev/null
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+@Target({ElementType.METHOD, ElementType.FIELD})
+@interface MethodAndFieldAnnotation{}
+
+@Target({ElementType.TYPE, ElementType.METHOD})
+@interface TypeAndMethodAnnotation{}
+
+
+public class MoreThanOneTargetAnnotation {
+
+ public void method1() {}
+
+ int field = 1;
+
+}
+
+aspect A {
+
+ // shouldn't get an xlint message because @MethodAndFieldAnnotation
+ // can be applied to methods and fields
+ pointcut pc1() : execution(@MethodAndFieldAnnotation * *(..));
+ declare warning : pc1() : "pc1()";
+
+ // should get an xlint message because can only have the target
+ // ElementType.TYPE as a return type
+ pointcut pc2() : execution((@MethodAndFieldAnnotation *) *(..));
+ declare warning : pc2() : "pc2()";
+
+ // shouldn't get an xlint message because can have the target
+ // ElementType.TYPE as a return type
+ pointcut pc3() : execution((@TypeAndMethodAnnotation *) *(..));
+ declare warning : pc3() : "pc3()";
+
+ // should get an xlint message because @TypeAndMethodAnnotation
+ // can only be applied to types and methods, not fields
+ pointcut pc4() : set(@TypeAndMethodAnnotation int *);
+ declare warning : pc4() : "pc4()";
+
+}
--- /dev/null
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+@Target({ElementType.TYPE})
+@interface TypeAnnotation{}
+
+@Target({ElementType.METHOD})
+@interface MethodAnnotation{}
+
+@Target({ElementType.FIELD})
+@interface FieldAnnotation{}
+
+public class OrTypePattern {
+
+ public void method1() {}
+
+ @FieldAnnotation
+ int field = 1;
+
+}
+
+aspect A {
+
+ // should display an xlint message because @FieldAnnotation can't be
+ // applied to methods
+ pointcut orPointcut() : execution(@(FieldAnnotation || MethodAnnotation) * *(..));
+ declare warning : orPointcut() : "orPointcut()";
+
+ // two xlint messages should be displayed because neither @FieldAnnotation
+ // or @TypeAnnotation can match methods
+ pointcut orPointcut2() : execution(@(FieldAnnotation || TypeAnnotation) * *(..));
+ declare warning : orPointcut2() : "orPointcut2()";
+
+}