summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tests/java5/generics/pointcuts/CallWithBridgeMethods.aj77
-rw-r--r--tests/src/org/aspectj/systemtest/ajc150/GenericsTests.java4
-rw-r--r--tests/src/org/aspectj/systemtest/ajc150/ajc150.xml12
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/DeclareAnnotation.java2
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/KindedPointcut.java30
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/SignaturePattern.java10
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/WithincodePointcut.java2
-rw-r--r--weaver/testsrc/org/aspectj/weaver/patterns/SignaturePatternTestCase.java2
8 files changed, 114 insertions, 25 deletions
diff --git a/tests/java5/generics/pointcuts/CallWithBridgeMethods.aj b/tests/java5/generics/pointcuts/CallWithBridgeMethods.aj
new file mode 100644
index 000000000..7701a840b
--- /dev/null
+++ b/tests/java5/generics/pointcuts/CallWithBridgeMethods.aj
@@ -0,0 +1,77 @@
+/**
+ *
+ * Each method T m(T1,...Tn) throws S1,...Sm is translated to a method with the same name
+ * whose return type, argument types, and thrown types are the erasures of the corresponding
+ * types in the original method. In addition, if a method m of a class or interface C is
+ * inherited in a subclass D, a bridge method might need to be generated in D. The rules are
+ * as follows:
+ *
+ * If C.m is directly overridden by a method D.m in D, and the erasure of the return type or
+ * argument types of D.m differs from the erasure of the corresponding types in C.m, a bridge
+ * method needs to be generated.
+ *
+ */
+
+
+public aspect CallWithBridgeMethods {
+
+ void bar() {
+ SubGeneric rawType = new SubGeneric();
+ Generic rawVariableOfSuperType = rawType;
+ rawVariableOfSuperType.foo("hi"); // this call we go to the bridge method..., but
+ // appears in the bytecode as Generic.foo(Object)
+ rawType.foo("hi"); // this call will go to the bridge method, and
+ // appears in the bytecode as SubGeneric.foo(Object)
+ }
+
+ declare warning : call(* SubGeneric.foo(..)) && within(SubGeneric)
+ : "should not match call in bridge method";
+
+ declare warning : call(* SubGeneric.foo(Object))
+ : "should match call to bridge method on L23, this is a real call!";
+
+ declare warning : execution(* SubGeneric.foo(Object)) && within(SubGeneric)
+ : "but whilst you can call it, it doesn't execute!";
+}
+
+
+class Generic<T> {
+
+ public T foo(T someObject) {
+ return someObject;
+ }
+
+}
+
+class SubGeneric<N extends Number> extends Generic<N> {
+
+ public N foo(N someNumber) {
+ return someNumber;
+ }
+
+ // "bridge" method is:
+// public Object foo(Object someObject) {
+// Number n = (Number)someObject;
+// return foo(n);
+// }
+
+}
+
+class SubSubGeneric<N extends Number> extends SubGeneric<N> {
+
+ // inherits bridge method from super
+
+ // NO bridge method generated (this is in contrast to the statements in the Bracha paper).
+ // "Adding Generics to the Java Programming Language, Public Draft Specification v2.0",
+ // Bracha et. al, June 23, 2003.
+
+}
+
+
+class SubGenericWithSameErasure<T> extends Generic<T> {
+
+ // NO bridge method generated (this is in contrast to the statements in the Bracha paper).
+ // "Adding Generics to the Java Programming Language, Public Draft Specification v2.0",
+ // Bracha et. al, June 23, 2003.
+
+} \ No newline at end of file
diff --git a/tests/src/org/aspectj/systemtest/ajc150/GenericsTests.java b/tests/src/org/aspectj/systemtest/ajc150/GenericsTests.java
index ceb186381..bedf1d55d 100644
--- a/tests/src/org/aspectj/systemtest/ajc150/GenericsTests.java
+++ b/tests/src/org/aspectj/systemtest/ajc150/GenericsTests.java
@@ -442,6 +442,10 @@ public class GenericsTests extends XMLBasedAjcTestCase {
public void testCallOverrideMatchingWithGenericMembers() {
runTest("call with overriding of inherited generic members");
}
+
+ public void testCallWithBridgeMethods() {
+ runTest("call with bridge methods");
+ }
public void testGetAndSetPointcutErrors() {
runTest("get and set with various parameterizations and generic types - errors");
diff --git a/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml b/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml
index 05a3db703..16dcc7a75 100644
--- a/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml
+++ b/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml
@@ -11,9 +11,10 @@
<ajc-test dir="java5/bridgeMethods" pr="72766" title="Ignore bridge methods">
<compile files="AspectX.aj" inpath="testcode.jar" options="-showWeaveInfo">
- <message kind="warning" line="7" text="pointcut did not match on the method call to a bridge method."/>
- <message kind="warning" line="7" text="does not match because declaring type is Number"/>
+ <!-- <message kind="warning" line="7" text="pointcut did not match on the method call to a bridge method."/>
+ <message kind="warning" line="7" text="does not match because declaring type is Number"/>-->
<message kind="weave" text="(AspectX.aj:18) advised by before advice from 'AspectX'"/>
+ <message kind="weave" text="(AspectX.aj:19) advised by before advice from 'AspectX'"/>
<message kind="weave" text="(Number.java:5) advised by before advice from 'AspectX'"/>
</compile>
</ajc-test>
@@ -2994,6 +2995,13 @@
<message kind="warning" line="87" text="parameterized match"/>
</compile>
</ajc-test>
+
+ <ajc-test dir="java5/generics/pointcuts" title="call with bridge methods">
+ <compile files="CallWithBridgeMethods.aj" options="-1.5">
+ <message kind="warning" line="23" text="should match call to bridge method on L23, this is a real call!"/>
+ </compile>
+ </ajc-test>
+
<!-- end of generics and pointcuts tests -->
diff --git a/weaver/src/org/aspectj/weaver/patterns/DeclareAnnotation.java b/weaver/src/org/aspectj/weaver/patterns/DeclareAnnotation.java
index 730b30ee5..11fe5579f 100644
--- a/weaver/src/org/aspectj/weaver/patterns/DeclareAnnotation.java
+++ b/weaver/src/org/aspectj/weaver/patterns/DeclareAnnotation.java
@@ -214,7 +214,7 @@ public class DeclareAnnotation extends Declare {
* For @constructor, @method, @field
*/
public boolean matches(ResolvedMember rm,World world) {
- return sigPattern.matches(rm,world);
+ return sigPattern.matches(rm,world,false);
}
/**
diff --git a/weaver/src/org/aspectj/weaver/patterns/KindedPointcut.java b/weaver/src/org/aspectj/weaver/patterns/KindedPointcut.java
index 199f33085..655ed1bbd 100644
--- a/weaver/src/org/aspectj/weaver/patterns/KindedPointcut.java
+++ b/weaver/src/org/aspectj/weaver/patterns/KindedPointcut.java
@@ -108,11 +108,11 @@ public class KindedPointcut extends Pointcut {
protected FuzzyBoolean matchInternal(Shadow shadow) {
if (shadow.getKind() != kind) return FuzzyBoolean.NO;
- if (!signature.matches(shadow.getSignature(), shadow.getIWorld())){
+ if (!signature.matches(shadow.getSignature(), shadow.getIWorld(),this.kind == Shadow.MethodCall)){
if(kind == Shadow.MethodCall) {
warnOnConfusingSig(shadow);
- warnOnBridgeMethod(shadow);
+ //warnOnBridgeMethod(shadow);
}
return FuzzyBoolean.NO;
}
@@ -121,18 +121,18 @@ public class KindedPointcut extends Pointcut {
}
- private void warnOnBridgeMethod(Shadow shadow) {
- if (shadow.getIWorld().getLint().noJoinpointsForBridgeMethods.isEnabled()) {
- ResolvedMember rm = shadow.getSignature().resolve(shadow.getIWorld());
- if (rm!=null) {
- int shadowModifiers = rm.getModifiers(); //shadow.getSignature().getModifiers(shadow.getIWorld());
- if (ResolvedType.hasBridgeModifier(shadowModifiers)) {
- shadow.getIWorld().getLint().noJoinpointsForBridgeMethods.signal(new String[]{},getSourceLocation(),
- new ISourceLocation[]{shadow.getSourceLocation()});
- }
- }
- }
- }
+// private void warnOnBridgeMethod(Shadow shadow) {
+// if (shadow.getIWorld().getLint().noJoinpointsForBridgeMethods.isEnabled()) {
+// ResolvedMember rm = shadow.getSignature().resolve(shadow.getIWorld());
+// if (rm!=null) {
+// int shadowModifiers = rm.getModifiers(); //shadow.getSignature().getModifiers(shadow.getIWorld());
+// if (ResolvedType.hasBridgeModifier(shadowModifiers)) {
+// shadow.getIWorld().getLint().noJoinpointsForBridgeMethods.signal(new String[]{},getSourceLocation(),
+// new ISourceLocation[]{shadow.getSourceLocation()});
+// }
+// }
+// }
+// }
public FuzzyBoolean match(JoinPoint.StaticPart jpsp) {
if (jpsp.getKind().equals(kind.getName())) {
@@ -222,7 +222,7 @@ public class KindedPointcut extends Pointcut {
signature.getAnnotationPattern());
if (nonConfusingPattern
- .matches(shadow.getSignature(), shadow.getIWorld())) {
+ .matches(shadow.getSignature(), shadow.getIWorld(),true)) {
shadow.getIWorld().getLint().unmatchedSuperTypeInCall.signal(
new String[] {
shadow.getSignature().getDeclaringType().toString(),
diff --git a/weaver/src/org/aspectj/weaver/patterns/SignaturePattern.java b/weaver/src/org/aspectj/weaver/patterns/SignaturePattern.java
index b1aad6e3b..122287329 100644
--- a/weaver/src/org/aspectj/weaver/patterns/SignaturePattern.java
+++ b/weaver/src/org/aspectj/weaver/patterns/SignaturePattern.java
@@ -121,7 +121,7 @@ public class SignaturePattern extends PatternNode {
}
}
- public boolean matches(Member joinPointSignature, World world) {
+ public boolean matches(Member joinPointSignature, World world, boolean allowBridgeMethods) {
// fail (or succeed!) fast tests...
if (joinPointSignature == null) return false;
if (kind != joinPointSignature.getKind()) return false;
@@ -130,16 +130,16 @@ public class SignaturePattern extends PatternNode {
// do the hard work then...
JoinPointSignature[] candidateMatches = joinPointSignature.getJoinPointSignatures(world);
for (int i = 0; i < candidateMatches.length; i++) {
- if (matchesExactly(candidateMatches[i],world)) return true;
+ if (matchesExactly(candidateMatches[i],world,allowBridgeMethods)) return true;
}
return false;
}
// Does this pattern match this exact signature (no declaring type mucking about
// or chasing up the hierarchy)
- private boolean matchesExactly(JoinPointSignature aMember, World inAWorld) {
- // Java5 introduces bridge methods, we don't want to match on them at all...
- if (aMember.isBridgeMethod()) {
+ private boolean matchesExactly(JoinPointSignature aMember, World inAWorld, boolean allowBridgeMethods) {
+ // Java5 introduces bridge methods, we match a call to them but nothing else...
+ if (aMember.isBridgeMethod() && !allowBridgeMethods) {
return false;
}
diff --git a/weaver/src/org/aspectj/weaver/patterns/WithincodePointcut.java b/weaver/src/org/aspectj/weaver/patterns/WithincodePointcut.java
index 94e897610..7c134a220 100644
--- a/weaver/src/org/aspectj/weaver/patterns/WithincodePointcut.java
+++ b/weaver/src/org/aspectj/weaver/patterns/WithincodePointcut.java
@@ -72,7 +72,7 @@ public class WithincodePointcut extends Pointcut {
//This will not match code in local or anonymous classes as if
//they were withincode of the outer signature
return FuzzyBoolean.fromBoolean(
- signature.matches(shadow.getEnclosingCodeSignature(), shadow.getIWorld()));
+ signature.matches(shadow.getEnclosingCodeSignature(), shadow.getIWorld(), false));
}
public FuzzyBoolean match(JoinPoint jp, JoinPoint.StaticPart encJP) {
diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/SignaturePatternTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/SignaturePatternTestCase.java
index d784afc70..935d3c262 100644
--- a/weaver/testsrc/org/aspectj/weaver/patterns/SignaturePatternTestCase.java
+++ b/weaver/testsrc/org/aspectj/weaver/patterns/SignaturePatternTestCase.java
@@ -147,7 +147,7 @@ public class SignaturePatternTestCase extends TestCase {
}
private void checkMatch(SignaturePattern p, Member member, boolean b) {
- boolean matches = p.matches(member, world);
+ boolean matches = p.matches(member, world,false);
assertEquals(p.toString() + " matches " + member.toString(), b, matches);
}