--- /dev/null
+import java.util.*;
+
+public aspect AfterReturningListOfSomething {
+
+ // returning(List<?>) matches List, List<String>, List<?>, ...
+
+ List rawList(List l) { return l;}
+ List listOfString(List<String> ls) { return ls; }
+ List listOfSomething(List<?> ls) { return ls; }
+ List listOfSomethingExtends(List<? extends Number> ln) { return ln; }
+ List listOfSomethingSuper(List<? super Double> ln) { return ln; }
+
+ // try a couple of nested variations too
+ Map<List<String>,List<List<Float>>> mapit(Map<List<String>,List<List<Float>>> m) { return m;}
+ HashSet<Double> setOf(HashSet<Double> sd) { return sd; }
+
+ public static void main(String[] args) {
+ AfterReturningListOfSomething a = AfterReturningListOfSomething.aspectOf();
+ a.rawList(null);
+ a.listOfString(null);
+ a.listOfSomething(null);
+ a.listOfSomethingExtends(null);
+ a.listOfSomethingSuper(null);
+ a.mapit(null);
+ a.setOf(null);
+ }
+
+ after() returning(List<?> aList) : execution(* *(..)) {
+ System.out.println("List<?> matches " + thisJoinPointStaticPart);
+ }
+
+ after() returning(Map<?,?> aMap) : execution(* *(..)) {
+ System.out.println("wild map matches " + thisJoinPointStaticPart);
+ }
+ @org.aspectj.lang.annotation.SuppressAjWarnings
+ after() returning(HashMap<List<?>,List<List<?>>> aMap) : execution(* *(..)) {
+ System.out.println("nested wild map does not match " + thisJoinPointStaticPart);
+ }
+
+ after() returning(Map<List<String>,List<List<Float>>> aMap) : execution(* *(..)) {
+ System.out.println("exact wild map matches " + thisJoinPointStaticPart);
+ }
+
+ after() returning(Set<Double> aSet) : execution(* *(..)) {
+ System.out.println("super type exact matches " + thisJoinPointStaticPart);
+ }
+
+ after() returning(Set<?> aSet) : execution(* *(..)) {
+ System.out.println("super wild type matches " + thisJoinPointStaticPart);
+ }
+}
\ No newline at end of file
--- /dev/null
+import java.util.*;
+
+public aspect AfterReturningListOfSomethingExtends {
+
+ // returning(List<? extends Number) matches List<Number>, List<Double>, not List<String>
+ // matches List, List<?> with unchecked warning
+
+ List rawList(List l) { return l; }
+ List<String> listOfString(List<String> ls) { return ls; }
+ List<Number> listOfNumber(List<Number> ln) { return ln; }
+ List<Double> listOfDouble(List<Double> ld) { return ld; }
+ List<?> listOfSomething(List<?> ls) { return ls; }
+ List<? extends Number> listOfSomethingExtends(List<? extends Number> ln) { return ln; }
+ List<? super Double> listOfSomethingSuper(List<? super Double> ln) { return ln; }
+
+ public static void main(String[] args) {
+ AfterReturningListOfSomethingExtends a = AfterReturningListOfSomethingExtends.aspectOf();
+ a.rawList(new ArrayList());
+ a.listOfString(null);
+ a.listOfNumber(null);
+ a.listOfDouble(null);
+ a.listOfSomething(new ArrayList());
+ a.listOfSomethingExtends(null);
+ a.listOfSomethingSuper(null);
+ }
+
+ after() returning(List<? extends Number> ln) : execution(* *(..)) {
+ System.out.println("List<? extends Number> matches " + thisJoinPointStaticPart);
+ }
+
+}
\ No newline at end of file
--- /dev/null
+import java.util.*;
+
+public aspect AfterReturningListOfSomethingSuper {
+
+ /*
+ * - returning(List<? super Number>) matches List<Object>, List<Number>
+ * does not match List<Double>
+ * matches List, List<?> with unchecked warning
+ * matches List<? super Number>
+ * matches List<? extends Number> with unchecked warning
+ */
+
+ List rawList(List l) { return l; }
+ List<Object> listOfObject(List<Object> ls) { return ls; }
+ List<Number> listOfNumber(List<Number> ln) { return ln; }
+ List<Double> listOfDouble(List<Double> ld) { return ld; }
+ List<?> listOfSomething(List<?> ls) { return ls; }
+ List<? super Number> listOfSomethingSuper(List<? super Number> ln) {return ln; }
+ List<? extends Number> listOfSomethingExtendsNumber(List<? extends Number> ln) { return ln; }
+
+ public static void main(String[] args) {
+ AfterReturningListOfSomethingSuper a = AfterReturningListOfSomethingSuper.aspectOf();
+ a.rawList(new ArrayList());
+ a.listOfObject(null);
+ a.listOfNumber(null);
+ a.listOfDouble(null);
+ a.listOfSomething(new ArrayList());
+ a.listOfSomethingSuper(null);
+ a.listOfSomethingExtendsNumber(new ArrayList<Double>());
+ }
+
+ after() returning(List<? super Number> ln) : execution(* *(..)) {
+ System.out.println("List<? super Number> matches " + thisJoinPointStaticPart);
+ }
+
+}
\ No newline at end of file
--- /dev/null
+import java.util.*;
+/**
+ * - returning(List<String>) matches List<String> but not List<Number>
+ * - returning(List<String>) matches List with unchecked warning
+ * - returning(List<String>) matches List<?> with unchecked warning
+ * - returning(List<String>) matches List<T> with unchecked warning
+ * - returning(List<String>) matches List<T extends String> (String is final)
+ */
+public aspect AfterReturningParameterized {
+
+ public static void main(String[] args) {
+ List<String> ls = new ArrayList<String>();
+// ls.add("one");
+// ls.add("two");
+// ls.add("three");
+
+ Generic<String> g = new Generic<String>();
+ g.foo(ls);
+ g.bar(ls);
+ g.tada(ls);
+ g.afar(new ArrayList<Number>());
+ g.something(ls);
+
+ MustBeString<String> mbs = new MustBeString<String>();
+ mbs.listit(ls);
+ }
+
+ after() returning(List<String> ls) : call(* *(..)) {
+ System.out.println("returning(List<String> matched at " + thisJoinPointStaticPart);
+ ls.add("four");
+ String s = ls.get(0);
+ }
+
+}
+
+class Generic<T> {
+
+ List<T> foo(List<T> lt) {
+ return lt;
+ }
+
+ List<String> bar(List<String> ls) {
+ return ls;
+ }
+
+ List tada(List l) {
+ return l;
+ }
+
+ List<Number> afar(List<Number> ln) {
+ return ln;
+ }
+
+ List<?> something(List<?> ls) {
+ return ls;
+ }
+}
+
+class MustBeString<T extends String> {
+
+ List<T> listit(List<T> lt) {
+ return lt;
+ }
+
+}
\ No newline at end of file
--- /dev/null
+import java.util.*;
+
+public aspect AfterReturningParameterizedWithWildcards {
+
+ /*
+ * - returning(List<Double>) matches List, List<?>, List<? extends Number> with unchecked warning
+ * matches List<Double>, List<? extends Double> ok (since Double is final)
+ */
+
+ after() returning(List<Double> ld) : call(* *(..)) {
+ System.out.println("List<Double> matched at " + thisJoinPointStaticPart);
+ }
+
+ public static void main(String[] args) {
+ C c = new C();
+ List<Double> ld = new ArrayList<Double>();
+ c.rawList(ld);
+ c.listOfSomething(ld);
+ c.listOfSomeNumber(ld);
+ c.listOfDouble(ld);
+ c.listOfSomeDouble(ld);
+ c.listOfString(new ArrayList<String>());
+ }
+}
+
+class C {
+
+ List rawList(List l) { return l;}
+
+ List<?> listOfSomething(List<?> ls) { return ls; }
+
+ List<? extends Number> listOfSomeNumber(List<? extends Number> ln) { return ln; }
+
+ List<Double> listOfDouble(List<Double> ld) { return ld; }
+
+ List<? extends Double> listOfSomeDouble(List<? extends Double> ld) { return ld; }
+
+ List<String> listOfString(List<String> ls) { return ls; }
+
+}
\ No newline at end of file
--- /dev/null
+import java.util.*;
+/**
+ * - returning(List) matches List, List<T>, List<String>
+ */
+public aspect AfterReturningRawType {
+
+ after() returning(List l) : call(* *(..)) {
+ System.out.println("returning(List) match at " + thisJoinPointStaticPart);
+ }
+
+ public static void main(String[] args) {
+ Generic<Double> g = new Generic<Double>();
+ g.foo(new ArrayList<Double>());
+ g.bar(new ArrayList<String>());
+ g.tada(new ArrayList());
+ g.tada(new ArrayList<String>());
+ g.tada(new ArrayList<Double>());
+ }
+
+}
+
+class Generic<T> {
+
+ List<T> foo(List<T> lt) {
+ return lt;
+ }
+
+ List<String> bar(List<String> ls) {
+ return ls;
+ }
+
+ List tada(List l) {
+ return l;
+ }
+
+
+}
\ No newline at end of file
--- /dev/null
+public aspect AfterThrowing {
+
+ // since a generic type may not be a subtype of throwable, this is always an
+ // error.
+
+ after() throwing(java.util.List<String> ls) : execution(* *(..)){
+
+ }
+
+}
\ No newline at end of file
runTest("generic wildcards in signature matching");
}
+ public void testAfterThrowing() {
+ runTest("after throwing with parameterized throw type");
+ }
+
+ public void testAfterReturningWithRawType() {
+ runTest("after returning with raw type and generic / parameterized sigs");
+ }
+
+ public void testAfterReturningParameterizedType() {
+ runTest("after returning with parameterized type and generic / parameterized sigs");
+ }
+
+ public void testAfterReturningParameterizedAndWildcards() {
+ runTest("after returning with parameterized type and wildcards");
+ }
+
+ public void testAfterReturningWithWildcardVar() {
+ runTest("after returning with generic wildcard");
+ }
+
+ public void testAfterReturningWithWildcardExtendsVar() {
+ runTest("after returning with generic wildcard extends");
+ }
+
+ public void testAfterReturningWithWildcardSuperVar() {
+ runTest("after returning with generic wildcard super");
+ }
+
// --- helpers
// Check the signature attribute on a class is correct
<ajc-test dir="java5/generics/pointcuts" title="args with parameterized type and wildcards">
<compile files="ArgsParameterizedWithWildcards.aj" options="-1.5">
+ <message kind="warning" line="10" text="unchecked match of List<Double> with List when argument is an instance of List"/>
<message kind="warning" line="10" text="unchecked match of List<Double> with List<? extends Double> when argument is an instance of List"/>
<message kind="warning" line="10" text="unchecked match of List<Double> with List<? extends Number> when argument is an instance of List"/>
<message kind="warning" line="10" text="unchecked match of List<Double> with List<?> when argument is an instance of List"/>
</compile>
</ajc-test>
-
<!-- end of generics and pointcuts tests -->
+
+ <ajc-test dir="java5/generics/afterAdvice" title="after throwing with parameterized throw type">
+ <compile files="AfterThrowing.aj" options="-1.5">
+ <message kind="error" line="6" text="cannot convert from List<String> to Throwable"/>
+ </compile>
+ </ajc-test>
+
+
+ <ajc-test dir="java5/generics/afterAdvice" title="after returning with raw type and generic / parameterized sigs">
+ <compile files="AfterReturningRawType.aj" options="-1.5">
+ </compile>
+ <run class="AfterReturningRawType">
+ <stdout>
+ <line text="returning(List) match at call(List Generic.foo(List))"/>
+ <line text="returning(List) match at call(List Generic.bar(List))"/>
+ <line text="returning(List) match at call(List Generic.tada(List))"/>
+ <line text="returning(List) match at call(List Generic.tada(List))"/>
+ <line text="returning(List) match at call(List Generic.tada(List))"/>
+ </stdout>
+ </run>
+ </ajc-test>
+
+ <ajc-test dir="java5/generics/afterAdvice" title="after returning with parameterized type and generic / parameterized sigs">
+ <compile files="AfterReturningParameterized.aj" options="-1.5">
+ <message kind="warning" line="28" text="unchecked match of List<String> with List"/>
+ </compile>
+ <run class="AfterReturningParameterized">
+ <stdout>
+ <line text="returning(List<String> matched at call(List Generic.foo(List))"/>
+ <line text="returning(List<String> matched at call(List Generic.bar(List))"/>
+ <line text="returning(List<String> matched at call(List Generic.tada(List))"/>
+ <line text="returning(List<String> matched at call(List Generic.something(List))"/>
+ <line text="returning(List<String> matched at call(List MustBeString.listit(List))"/>
+ </stdout>
+ </run>
+ </ajc-test>
+ <ajc-test dir="java5/generics/afterAdvice" title="after returning with parameterized type and wildcards">
+ <compile files="AfterReturningParameterizedWithWildcards.aj" options="-1.5">
+ <message kind="warning" line="10" text="unchecked match of List<Double> with List when argument is an instance of List"/>
+ <message kind="warning" line="10" text="unchecked match of List<Double> with List<? extends Double> when argument is an instance of List"/>
+ <message kind="warning" line="10" text="unchecked match of List<Double> with List<? extends Number> when argument is an instance of List"/>
+ <message kind="warning" line="10" text="unchecked match of List<Double> with List<?> when argument is an instance of List"/>
+ </compile>
+ <run class="AfterReturningParameterizedWithWildcards">
+ <stdout>
+ <line text="List<Double> matched at call(List C.rawList(List))"/>
+ <line text="List<Double> matched at call(List C.listOfSomething(List))"/>
+ <line text="List<Double> matched at call(List C.listOfSomeNumber(List))"/>
+ <line text="List<Double> matched at call(List C.listOfDouble(List))"/>
+ <line text="List<Double> matched at call(List C.listOfSomeDouble(List))"/>
+ </stdout>
+ </run>
+ </ajc-test>
+
+ <ajc-test dir="java5/generics/afterAdvice" title="after returning with generic wildcard">
+ <compile files="AfterReturningListOfSomething.aj" options="-1.5">
+ </compile>
+ <run class="AfterReturningListOfSomething">
+ <stdout>
+ <line text="List<?> matches execution(List AfterReturningListOfSomething.rawList(List))"/>
+ <line text="List<?> matches execution(List AfterReturningListOfSomething.listOfString(List))"/>
+ <line text="List<?> matches execution(List AfterReturningListOfSomething.listOfSomething(List))"/>
+ <line text="List<?> matches execution(List AfterReturningListOfSomething.listOfSomethingExtends(List))"/>
+ <line text="List<?> matches execution(List AfterReturningListOfSomething.listOfSomethingSuper(List))"/>
+ <line text="wild map matches execution(Map AfterReturningListOfSomething.mapit(Map))"/>
+ <line text="exact wild map matches execution(Map AfterReturningListOfSomething.mapit(Map))"/>
+ <line text="super type exact matches execution(HashSet AfterReturningListOfSomething.setOf(HashSet))"/>
+ <line text="super wild type matches execution(HashSet AfterReturningListOfSomething.setOf(HashSet))"/>
+ </stdout>
+ </run>
+ </ajc-test>
+
+ <ajc-test dir="java5/generics/afterAdvice" title="after returning with generic wildcard extends">
+ <compile files="AfterReturningListOfSomethingExtends.aj" options="-1.5">
+ <message kind="warning" line="27" text="unchecked match of List<? extends Number> with List"/>
+ <message kind="warning" line="27" text="unchecked match of List<? extends Number> with List<?>"/>
+ </compile>
+ <run class="AfterReturningListOfSomethingExtends">
+ <stdout>
+ <line text="List<? extends Number> matches execution(List AfterReturningListOfSomethingExtends.rawList(List))"/>
+ <line text="List<? extends Number> matches execution(List AfterReturningListOfSomethingExtends.listOfNumber(List))"/>
+ <line text="List<? extends Number> matches execution(List AfterReturningListOfSomethingExtends.listOfDouble(List))"/>
+ <line text="List<? extends Number> matches execution(List AfterReturningListOfSomethingExtends.listOfSomething(List))"/>
+ <line text="List<? extends Number> matches execution(List AfterReturningListOfSomethingExtends.listOfSomethingExtends(List))"/>
+ </stdout>
+ </run>
+ </ajc-test>
+
+ <ajc-test dir="java5/generics/afterAdvice" title="after returning with generic wildcard super">
+ <compile files="AfterReturningListOfSomethingSuper.aj" options="-1.5">
+ <message kind="warning" line="32" text="unchecked match of List<? super Number> with List"/>
+ <message kind="warning" line="32" text="unchecked match of List<? super Number> with List<?>"/>
+ <message kind="warning" line="32" text="unchecked match of List<? super Number> with List<? extends Number>"/>
+ </compile>
+ <run class="AfterReturningListOfSomethingSuper">
+ <stdout>
+ <line text="List<? super Number> matches execution(List AfterReturningListOfSomethingSuper.rawList(List))"/>
+ <line text="List<? super Number> matches execution(List AfterReturningListOfSomethingSuper.listOfObject(List))"/>
+ <line text="List<? super Number> matches execution(List AfterReturningListOfSomethingSuper.listOfNumber(List))"/>
+ <line text="List<? super Number> matches execution(List AfterReturningListOfSomethingSuper.listOfSomething(List))"/>
+ <line text="List<? super Number> matches execution(List AfterReturningListOfSomethingSuper.listOfSomethingSuper(List))"/>
+ <line text="List<? super Number> matches execution(List AfterReturningListOfSomethingSuper.listOfSomethingExtendsNumber(List))"/>
+ </stdout>
+ </run>
+ </ajc-test>
<!-- ============================================================== -->
<!-- End of generics tests -->
<!-- ============================================================== -->