Browse Source

tests and fix for call pointcut matching with various generic and parameterized types

tags/V1_5_0M3
acolyer 19 years ago
parent
commit
c22c80074c

+ 106
- 0
tests/java5/generics/pointcuts/CallOverriding.aj View File

@@ -0,0 +1,106 @@
public aspect CallOverriding {
void foo() {
// make some calls!
Generic<Number> gn = new Generic<Number>();
SubGeneric<Double> sgd = new SubGeneric<Double>();
SubParameterized sp = new SubParameterized();
gn.foo(new Integer(5));
sgd.foo(new Double(5));
sp.foo("hi");
}
// 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 : call(void *.foo(Object))
: "wildcard declaring type match on erasure";
declare warning : call(void Generic.foo(Object))
: "base declaring type match on erasure";
declare warning : call(void SubGeneric.foo(Object))
: "not expecting any matches";
declare warning : call(void SubGeneric.foo(Number))
: "sub type match on erasure";
declare warning : call(void SubParameterized.foo(Object))
: "not expecting any matches";
declare warning : call(void SubParameterized.foo(String))
: "parameterized match on erasure";
}

class Generic<T> {
int x = 0;
// call (void Generic.foo(Object))
// call (void *.foo(Object))
public void foo(T someObject) {
x = 1;
}
}

class SubGeneric<N extends Number> extends Generic<N> {
int y = 0;
// call(void Generic.foo(Object))
// call( void *.foo(Object))
// call(void SubGeneric.foo(Number))
// !call(void SubGeneric.foo(Object))
public void foo(N someObject) {
y = 1;
}
}

class SubParameterized extends Generic<String> {
int y = 0;
// call(void Generic.foo(Object))
// call( void *.foo(Object))
// call(void SubParameterized.foo(String))
// !call(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;
void foo() {
ParameterizedI pi = new ParameterizedI();
pi.bar(5.0d);
}
// call(void I.bar(Object))
// call(void *.bar(Object))
// call(void ParameterizedI.bar(Double))
// !call(void ParameterizedI.bar(Object))
public void bar(Double d) {
x = 1;
}
static aspect ParameterizedChecker {
declare warning : call(void I.bar(Object)) : "erasure match on base interface";
declare warning : call(void *.bar(Object)) : "wildcard match on erasure";
declare warning : call(void ParameterizedI.bar(Double)) : "parameterized match";
declare warning : call(void ParameterizedI.bar(Object)) : "no match expected";
}
}


+ 18
- 0
tests/java5/generics/pointcuts/CallPointcutMatchingErrorCases.aj View File

@@ -0,0 +1,18 @@
public aspect CallPointcutMatchingErrorCases {
// rule 1) you can't use generic or parameterized type patterns in the declaring type position
pointcut tryExecutionGeneric() : call(* Generic<T>.*(..)); // CE L 4
pointcut tryExecutionParameterized() : call(* Generic<String>.*(..)); // CE L5
pointcut badThrows() : call(* Generic.*(..) throws Ex*<String>); // CE L6
}


class Generic<T> {
T foo = null;
T getFoo() {
return foo;
}
}

+ 80
- 0
tests/java5/generics/pointcuts/CallPointcutMatchingParamAndReturnTypes.aj View File

@@ -0,0 +1,80 @@
import java.util.*;

public aspect CallPointcutMatchingParamAndReturnTypes {
void foo() {
// make some calls!
Generic<Number> gn = new Generic(new ArrayList<String>());
new UglyBuilding().foo();
gn = new Generic<Number>(5.0d);
gn.foo();
new UglyBuilding().iSee("you");
new UglyBuilding().ic2it();
// new UglyBuilding().iSee(new Object());
}
// rule 3) a raw parameter pattern matches any parameterized type
declare warning : call(Generic.new(List))
: "raw param type matching in call ok";
declare warning : call(List UglyBuilding.foo())
: "raw return type matching in call ok";
// rule 4) A param type declared using a type variable is matched by its erasure
declare warning : call(Generic.new(Object))
: "erasure type matching in call ok";
declare warning : call(Object Generic.foo())
: "erasure type matching in call ok";
// rule 5) no join points in bridge methods - test this separately for call...
declare warning : call(void UglyBuilding.iSee(String))
: "call and parameterized method ok";
declare warning : call(* ISore.*(..))
: "call and generic interface ok";
declare warning : call(* I2.*(..))
: "call and interface control test";
// declare warning : call(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 : call(Generic.new(List<String>)) : "match on parameterized args";
declare warning : call(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; }
}

+ 14
- 14
tests/java5/generics/pointcuts/ExecutionOverriding.aj View File

@@ -31,8 +31,8 @@ public aspect ExecutionOverriding {
class Generic<T> {
int x = 0;
// withincode (void Generic.foo(Object))
// withincode (void *.foo(Object))
// execution (void Generic.foo(Object))
// execution (void *.foo(Object))
public void foo(T someObject) {
x = 1;
}
@@ -42,10 +42,10 @@ class Generic<T> {
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))
// execution(void Generic.foo(Object))
// execution( void *.foo(Object))
// execution(void SubGeneric.foo(Number))
// !execution(void SubGeneric.foo(Object))
public void foo(N someObject) {
y = 1;
}
@@ -55,10 +55,10 @@ class SubGeneric<N extends Number> extends Generic<N> {
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))
// execution(void Generic.foo(Object))
// execution( void *.foo(Object))
// execution(void SubParameterized.foo(String))
// !execution(void SubGeneric.foo(Object))
public void foo(String someObject) {
y = 1;
}
@@ -72,10 +72,10 @@ interface I<E> {
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))
// execution(void I.bar(Object))
// execution(void *.bar(Object))
// execution(void ParameterizedI.bar(Double))
// !execution(void ParameterizedI.bar(Object))
public void bar(Double d) {
x = 1;
}

+ 27
- 8
tests/src/org/aspectj/systemtest/ajc150/GenericsTests.java View File

@@ -96,7 +96,13 @@ public class GenericsTests extends XMLBasedAjcTestCase {
* - parameter as parameterized type PASS
* - no join points for bridge methods PASS
* call
* - wait till we get there!
* - no generic or parameterized declaring type patterns
* - no parameterized throws patterns
* - return type as type variable
* - return type as parameterized type
* - parameter as type variable
* - parameter as parameterized type
* - a call to a bridge method is really a call to the method being bridged... (1.4/1.5 differences here?)
*/
/* ==========================================
@@ -205,12 +211,12 @@ public class GenericsTests extends XMLBasedAjcTestCase {
// non static

public void testGenericMethodITD1() {runTest("generic method itd - 1"); } // <E> ... (List<? extends E>)
public void testGenericMethodITD2() {runTest("generic method itd - 2"); } // <E extends Number> ... (List<? extends E>) called incorrectly
public void testGenericMethodITD3() {runTest("generic method itd - 3"); } // <E> ... (List<E>,List<E>)
public void testGenericMethodITD4() {runTest("generic method itd - 4"); } // <A,B> ... (List<A>,List<B>)
public void testGenericMethodITD5() {runTest("generic method itd - 5"); } // <E> ... (List<E>,List<E>) called incorrectly
public void testGenericMethodITD6() {runTest("generic method itd - 6"); } // <E extends Number> ... (List<? extends E>)
public void testGenericMethodITD1() {runTest("generic method itd - 1");} // <E> ... (List<? extends E>)
public void testGenericMethodITD2() {runTest("generic method itd - 2");} // <E extends Number> ... (List<? extends E>) called incorrectly
public void testGenericMethodITD3() {runTest("generic method itd - 3");} // <E> ... (List<E>,List<E>)
public void testGenericMethodITD4() {runTest("generic method itd - 4");} // <A,B> ... (List<A>,List<B>)
public void testGenericMethodITD5() {runTest("generic method itd - 5");} // <E> ... (List<E>,List<E>) called incorrectly
public void testGenericMethodITD6() {runTest("generic method itd - 6");} // <E extends Number> ... (List<? extends E>)
public void testGenericMethodITD7() {runTest("generic method itd - 7"); } // <E> ... (List<E>,List<? extends E>)
public void testGenericMethodITD8() {runTest("generic method itd - 8"); } // <E> ... (List<E>,List<? extends E>) called incorrectly
public void testGenericMethodITD9() {runTest("generic method itd - 9"); } // <R extends Comparable<? super R>> ... (List<R>)
@@ -232,7 +238,7 @@ public class GenericsTests extends XMLBasedAjcTestCase {
public void testGenericCtorITD2() {runTest("generic ctor itd - 2");} // <T> new(List<T>,List<? extends T>)
public void testGenericCtorITD3() {runTest("generic ctor itd - 3");} // <T> new(List<T>,Comparator<? super T>)

// public void testGenericITFSharingTypeVariable() {
// public void testGenericITFSharingTypeVariable() {
// runTest("generic intertype field declaration, sharing type variable");
// }

@@ -424,6 +430,19 @@ public class GenericsTests extends XMLBasedAjcTestCase {
public void testExecutionOverrideMatchingWithGenericMembers() {
runTest("execution with overriding of inherited generic members");
}

public void testCallPointcutErrors() {
runTest("call with various parameterizations and generic types - errors");
}
public void testCallMatching() {
runTest("call with various parameterizations and generic types - matching");
}
public void testCallOverrideMatchingWithGenericMembers() {
runTest("call with overriding of inherited generic members");
}

public void testGetAndSetPointcutErrors() {
runTest("get and set with various parameterizations and generic types - errors");
}

+ 42
- 2
tests/src/org/aspectj/systemtest/ajc150/ajc150.xml View File

@@ -2390,7 +2390,7 @@
<compile files="GenericCtorITD1.aj" options="-1.5"/>
<run class="GenericCtorITD1"/>
</ajc-test>
<ajc-test dir="java5/generics/itds" title="generic ctor itd - 2">
<compile files="GenericCtorITD2.aj" options="-1.5"/>
<run class="GenericCtorITD2"/>
@@ -2905,7 +2905,7 @@
</compile>
</ajc-test>

<ajc-test dir="java5/generics/pointcuts" title="execution with various parameterizations and generic types - errors">
<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)"/>
@@ -2955,6 +2955,46 @@
<message kind="warning" line="5" text="execution&lt;T&gt;(* GenericInterface&lt;T extends Number&gt;.asInt(T))"/>
</compile>
</ajc-test>
<ajc-test dir="java5/generics/pointcuts" title="call with various parameterizations and generic types - errors">
<compile files="CallPointcutMatchingErrorCases.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 a call pointcut expression (use the raw type instead)"/>
<message kind="error" line="5" text="can't use parameterized type patterns for the declaring type of a call 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="call with various parameterizations and generic types - matching">
<compile files="CallPointcutMatchingParamAndReturnTypes.aj" options="-1.5">
<message kind="warning" line="7" text="raw param type matching in call ok"/>
<message kind="warning" line="8" text="raw return type matching in call ok"/>
<message kind="warning" line="9" text="erasure type matching in call ok"/>
<message kind="warning" line="10" text="erasure type matching in call ok"/>
<message kind="warning" line="11" text="call and parameterized method ok"/>
<message kind="warning" line="11" text="call and generic interface ok"/>
<message kind="warning" line="12" text="call and interface control test"/>
<message kind="warning" line="7" text="match on parameterized args"/>
<message kind="warning" line="8" text="match on parameterized return type"/>
</compile>
</ajc-test>

<ajc-test dir="java5/generics/pointcuts" title="call with overriding of inherited generic members">
<compile files="CallOverriding.aj" options="-1.5">
<message kind="warning" line="8" text="wildcard declaring type match on erasure"/>
<message kind="warning" line="9" text="wildcard declaring type match on erasure"/>
<message kind="warning" line="10" text="wildcard declaring type match on erasure"/>
<message kind="warning" line="8" text="base declaring type match on erasure"/>
<message kind="warning" line="9" text="base declaring type match on erasure"/>
<message kind="warning" line="10" text="base declaring type match on erasure"/>
<message kind="warning" line="9" text="sub type match on erasure"/>
<message kind="warning" line="10" text="parameterized match on erasure"/>
<message kind="warning" line="87" text="erasure match on base interface"/>
<message kind="warning" line="87" text="wildcard match on erasure"/>
<message kind="warning" line="87" text="parameterized match"/>
</compile>
</ajc-test>

<!-- end of generics and pointcuts tests -->
<!-- ============================================================== -->

+ 11
- 7
weaver/src/org/aspectj/weaver/ResolvedMemberImpl.java View File

@@ -267,7 +267,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
}

public boolean hasAnnotation(UnresolvedType ofType) {
// The ctors don't allow annotations to be specified ... yet - but
// The ctors don't allow annotations to be specified ... yet - but
// that doesn't mean it is an error to call this method.
// Normally the weaver will be working with subtypes of
// this type - BcelField/BcelMethod
@@ -388,7 +388,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
for (int i = 0; i < typeVariables.length; i++) {
UnresolvedType array_element = typeVariables[i];
typeVariables[i] = typeVariables[i].resolve(world);
}
}
}
if (parameterTypes!=null && parameterTypes.length>0) {
for (int i = 0; i < parameterTypes.length; i++) {
@@ -396,7 +396,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
parameterTypes[i] = parameterTypes[i].resolve(world);
}
}
returnType = returnType.resolve(world);return this;
}
@@ -601,9 +601,8 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
private ResolvedMember myErasure = null;
private boolean calculatedMyErasure = false;


/**
/**
* For ITDs, we use the default factory methods to build a resolved member, then alter a couple of characteristics
* using this method - this is safe.
*/
@@ -675,7 +674,12 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
StringBuffer sig = new StringBuffer();
UnresolvedType[] myParameterTypes = getParameterTypes();
for (int i = 0; i < myParameterTypes.length; i++) {
sig.append(myParameterTypes[i].getSignature());
UnresolvedType thisParameter = myParameterTypes[i];
if (thisParameter.isTypeVariableReference()) {
sig.append(thisParameter.getUpperBound().getSignature());
} else {
sig.append(thisParameter.getSignature());
}
}
myParameterSignatureErasure = sig.toString();
return myParameterSignatureErasure;

Loading…
Cancel
Save