diff options
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); } |