@@ -0,0 +1,91 @@ | |||
public aspect ExecutionOverriding { | |||
// if a type overrides a generic method from a supertype, changing the | |||
// signature in the process (for example, is a generic subtype with a | |||
// narrowed type variable, or extends a parameterized super class, or | |||
// implements a parameterized interface), then a type pattern of | |||
// OriginalDeclaringType.erasureOfOriginalSignature matches, and a | |||
// type pattern of *.erasureOfOriginalSignature matches, but | |||
// a type pattern OverridingType.erasureOfOriginalSignature DOES NOT | |||
// MATCH. | |||
declare warning : execution(void *.foo(Object)) | |||
: "wildcard declaring type match on erasure"; | |||
declare warning : execution(void Generic.foo(Object)) | |||
: "base declaring type match on erasure"; | |||
declare warning : execution(void SubGeneric.foo(Object)) | |||
: "not expecting any matches"; | |||
declare warning : execution(void SubGeneric.foo(Number)) | |||
: "sub type match on erasure"; | |||
declare warning : execution(void SubParameterized.foo(Object)) | |||
: "not expecting any matches"; | |||
declare warning : execution(void SubParameterized.foo(String)) | |||
: "parameterized match on erasure"; | |||
} | |||
class Generic<T> { | |||
int x = 0; | |||
// withincode (void Generic.foo(Object)) | |||
// withincode (void *.foo(Object)) | |||
public void foo(T someObject) { | |||
x = 1; | |||
} | |||
} | |||
class SubGeneric<N extends Number> extends Generic<N> { | |||
int y = 0; | |||
// withincode(void Generic.foo(Object)) | |||
// withincode( void *.foo(Object)) | |||
// withincode(void SubGeneric.foo(Number)) | |||
// !withincode(void SubGeneric.foo(Object)) | |||
public void foo(N someObject) { | |||
y = 1; | |||
} | |||
} | |||
class SubParameterized extends Generic<String> { | |||
int y = 0; | |||
// withincode(void Generic.foo(Object)) | |||
// withincode( void *.foo(Object)) | |||
// withincode(void SubParameterized.foo(String)) | |||
// !withincode(void SubGeneric.foo(Object)) | |||
public void foo(String someObject) { | |||
y = 1; | |||
} | |||
} | |||
interface I<E> { | |||
void bar(E anElement); | |||
} | |||
class ParameterizedI implements I<Double> { | |||
int x; | |||
// withincode(void I.bar(Object)) | |||
// withincode(void *.bar(Object)) | |||
// withincode(void ParameterizedI.bar(Double)) | |||
// !withincode(void ParameterizedI.bar(Object)) | |||
public void bar(Double d) { | |||
x = 1; | |||
} | |||
static aspect ParameterizedChecker { | |||
declare warning : execution(void I.bar(Object)) : "erasure match on base interface"; | |||
declare warning : execution(void *.bar(Object)) : "wildcard match on erasure"; | |||
declare warning : execution(void ParameterizedI.bar(Double)) : "parameterized match"; | |||
declare warning : execution(void ParameterizedI.bar(Object)) : "no match expected"; | |||
} | |||
} | |||
@@ -0,0 +1,18 @@ | |||
public aspect ExecutionPointcutMatchingErrorCases { | |||
// rule 1) you can't use generic or parameterized type patterns in the declaring type position | |||
pointcut tryExecutionGeneric() : execution(* Generic<T>.*(..)); // CE L 4 | |||
pointcut tryExecutionParameterized() : execution(* Generic<String>.*(..)); // CE L5 | |||
pointcut badThrows() : execution(* Generic.*(..) throws Ex*<String>); // CE L6 | |||
} | |||
class Generic<T> { | |||
T foo = null; | |||
T getFoo() { | |||
return foo; | |||
} | |||
} |
@@ -0,0 +1,68 @@ | |||
import java.util.*; | |||
public aspect ExecutionPointcutMatchingParamAndReturnTypes { | |||
// rule 3) a raw parameter pattern matches any parameterized type | |||
declare warning : execution(Generic.new(List)) | |||
: "raw param type matching in execution ok"; | |||
declare warning : execution(List UglyBuilding.foo()) | |||
: "raw return type matching in execution ok"; | |||
// rule 4) A param type declared using a type variable is matched by its erasure | |||
declare warning : execution(Generic.new(Object)) | |||
: "erasure type matching in execution ok"; | |||
declare warning : execution(Object Generic.foo()) | |||
: "erasure type matching in execution ok"; | |||
// rule 5) no join points in bridge methods | |||
declare warning : execution(void UglyBuilding.iSee(String)) | |||
: "execution and parameterized method ok"; | |||
declare warning : execution(* ISore.*(..)) | |||
: "execution and generic interface ok"; | |||
declare warning : execution(* I2.*(..)) | |||
: "execution and interface control test"; | |||
declare warning : execution(void UglyBuilding.iSee(Object)) | |||
: "should be no join points for bridge methods"; | |||
// rule 6) parameterized types in return and args can be matched exactly | |||
declare warning : execution(Generic.new(List<String>)) : "match on parameterized args"; | |||
declare warning : execution(List<Number> *(..)) : "match on parameterized return type"; | |||
} | |||
class Generic<T> { | |||
int x; | |||
public Generic(List<String> ls) { | |||
x = 5; | |||
} | |||
public Generic(T t) { | |||
x = 6; | |||
} | |||
T foo() { x = 7; return null; } | |||
} | |||
interface ISore<E> { | |||
void iSee(E anE); | |||
} | |||
interface I2 { | |||
void ic2it(); | |||
} | |||
class UglyBuilding implements ISore<String>, I2 { | |||
int y; | |||
// this class will have a bridge method with signature void iSee(Object), with a cast and call | |||
// to the method below | |||
public void iSee(String s) { | |||
y = 2; | |||
} | |||
public void ic2it() { y = 4; } | |||
List<Number> foo() { y = 1; return null; } | |||
} |
@@ -87,8 +87,14 @@ public class GenericsTests extends XMLBasedAjcTestCase { | |||
* - parameter as type variable PASS | |||
* - parameter as parameterized type PASS | |||
* - no join points within bridge methods PASS | |||
* execution | |||
* - wait till we get there! | |||
* execution PASS | |||
* - no generic or parameterized declaring type patterns PASS | |||
* - no parameterized throws patterns PASS | |||
* - return type as type variable PASS | |||
* - return type as parameterized type PASS | |||
* - parameter as type variable PASS | |||
* - parameter as parameterized type PASS | |||
* - no join points for bridge methods PASS | |||
* call | |||
* - wait till we get there! | |||
*/ | |||
@@ -372,6 +378,17 @@ public class GenericsTests extends XMLBasedAjcTestCase { | |||
runTest("execution pcd with raw signature matching"); | |||
} | |||
public void testExecutionPointcutErrors() { | |||
runTest("execution with various parameterizations and generic types - errors"); | |||
} | |||
public void testExecutionMatching() { | |||
runTest("execution with various parameterizations and generic types - matching"); | |||
} | |||
public void testExecutionOverrideMatchingWithGenericMembers() { | |||
runTest("execution with overriding of inherited generic members"); | |||
} | |||
public void testGetAndSetPointcutErrors() { | |||
runTest("get and set with various parameterizations and generic types - errors"); | |||
} |
@@ -2846,6 +2846,45 @@ | |||
</compile> | |||
</ajc-test> | |||
<ajc-test dir="java5/generics/pointcuts" title="execution with various parameterizations and generic types - errors"> | |||
<compile files="ExecutionPointcutMatchingErrorCases.aj" options="-1.5"> | |||
<message kind="warning" line="4" text="no match for this type name: T"/> | |||
<message kind="error" line="4" text="can't use parameterized type patterns for the declaring type of an execution pointcut expression (use the raw type instead)"/> | |||
<message kind="error" line="5" text="can't use parameterized type patterns for the declaring type of an execution pointcut expression (use the raw type instead)"/> | |||
<message kind="error" line="6" text="invalid throws pattern: a generic class may not be a direct or indirect subclass of Throwable"/> | |||
</compile> | |||
</ajc-test> | |||
<ajc-test dir="java5/generics/pointcuts" title="execution with various parameterizations and generic types - matching"> | |||
<compile files="ExecutionPointcutMatchingParamAndReturnTypes.aj" options="-1.5"> | |||
<message kind="warning" line="35" text="raw param type matching in execution ok"/> | |||
<message kind="warning" line="67" text="raw return type matching in execution ok"/> | |||
<message kind="warning" line="38" text="erasure type matching in execution ok"/> | |||
<message kind="warning" line="42" text="erasure type matching in execution ok"/> | |||
<message kind="warning" line="61" text="execution and parameterized method ok"/> | |||
<message kind="warning" line="61" text="execution and generic interface ok"/> | |||
<message kind="warning" line="65" text="execution and interface control test"/> | |||
<message kind="warning" line="35" text="match on parameterized args"/> | |||
<message kind="warning" line="67" text="match on parameterized return type"/> | |||
</compile> | |||
</ajc-test> | |||
<ajc-test dir="java5/generics/pointcuts" title="execution with overriding of inherited generic members"> | |||
<compile files="ExecutionOverriding.aj" options="-1.5"> | |||
<message kind="warning" line="36" text="wildcard declaring type match on erasure"/> | |||
<message kind="warning" line="49" text="wildcard declaring type match on erasure"/> | |||
<message kind="warning" line="62" text="wildcard declaring type match on erasure"/> | |||
<message kind="warning" line="36" text="base declaring type match on erasure"/> | |||
<message kind="warning" line="49" text="base declaring type match on erasure"/> | |||
<message kind="warning" line="62" text="base declaring type match on erasure"/> | |||
<message kind="warning" line="49" text="sub type match on erasure"/> | |||
<message kind="warning" line="62" text="parameterized match on erasure"/> | |||
<message kind="warning" line="79" text="erasure match on base interface"/> | |||
<message kind="warning" line="79" text="wildcard match on erasure"/> | |||
<message kind="warning" line="79" text="parameterized match"/> | |||
</compile> | |||
</ajc-test> | |||
<ajc-test dir="java5/generics/pointcuts" title="execution pcd with generic declaring type and erased parameter types"> | |||
<compile files="GenericInterface.java,ConcreteImplementingClass.java,GenericImplementingClass.java,GenericDeclaringTypeWithParameterErasure.aj" options="-1.5"> | |||
</compile> |