@@ -0,0 +1,30 @@ | |||
interface MyBase { void foo(); }; | |||
interface MyMarker extends MyBase { void bar(); } | |||
abstract aspect Base<A extends MyBase> { | |||
pointcut somePC() : execution(* A.*(..)); | |||
declare warning : somePC() : "a match"; | |||
} | |||
abstract aspect Middle<B extends MyBase> extends Base<B> {} | |||
aspect Sub extends Middle<MyMarker> {} | |||
class C1 implements MyBase { | |||
public void foo() {} | |||
} | |||
class C2 implements MyMarker { | |||
public void foo() {} // CW L 25 | |||
public void bar() {} // CW L 27 | |||
} |
@@ -97,6 +97,7 @@ public class Ajc152Tests extends org.aspectj.testing.XMLBasedAjcTestCase { | |||
public void testDoubleAnnotationMatching_pr138223() { runTest("Double at annotation matching (no binding)");} | |||
public void testSuperCallsInAtAspectJAdvice_pr139749() { runTest("Super calls in @AspectJ advice");} | |||
public void testNoClassCastExceptionWithPerThis_pr138286() { runTest("No ClassCastException with perThis");} | |||
public void testGenericAspectHierarchyWithBounds_pr147845() { runTest("Generic abstract aspect hierarchy with bounds"); } | |||
public void testDeclareAtMethodRelationship_pr143924() { | |||
//AsmManager.setReporting("c:/debug.txt",true,true,true,true); |
@@ -712,5 +712,12 @@ | |||
</stderr> | |||
</run> | |||
</ajc-test> | |||
<ajc-test dir="bugs152/pr147845" title="Generic abstract aspect hierarchy with bounds"> | |||
<compile files="GenericAspectHierarchy.aj" options="-1.5"> | |||
<message kind="warning" line="25" text="a match"/> | |||
<message kind="warning" line="27" text="a match"/> | |||
</compile> | |||
</ajc-test> | |||
</suite> |
@@ -219,23 +219,24 @@ public class TypeVariable { | |||
if (tvrt.hasLowerBound() != (getLowerBound() != null)) return false; | |||
if (tvrt.hasLowerBound() && tvrt.getLowerBound() != getLowerBound()) return false; | |||
// either we both have bounds, or neither of us have bounds | |||
if ((tvrt.additionalInterfaceBounds != null) != (additionalInterfaceBounds != null)) return false; | |||
ReferenceType[] tvrtBounds = tvrt.getAdditionalBounds(); | |||
if ((tvrtBounds != null) != (additionalInterfaceBounds != null)) return false; | |||
if (additionalInterfaceBounds != null) { | |||
// we both have bounds, compare | |||
if (tvrt.additionalInterfaceBounds.length != additionalInterfaceBounds.length) return false; | |||
if (tvrtBounds.length != additionalInterfaceBounds.length) return false; | |||
Set aAndNotB = new HashSet(); | |||
Set bAndNotA = new HashSet(); | |||
for (int i = 0; i < additionalInterfaceBounds.length; i++) { | |||
aAndNotB.add(additionalInterfaceBounds[i]); | |||
} | |||
for (int i = 0; i < tvrt.additionalInterfaceBounds.length; i++) { | |||
bAndNotA.add(tvrt.additionalInterfaceBounds[i]); | |||
for (int i = 0; i < tvrtBounds.length; i++) { | |||
bAndNotA.add(tvrtBounds[i]); | |||
} | |||
for (int i = 0; i < additionalInterfaceBounds.length; i++) { | |||
bAndNotA.remove(additionalInterfaceBounds[i]); | |||
} | |||
for (int i = 0; i < tvrt.additionalInterfaceBounds.length; i++) { | |||
aAndNotB.remove(tvrt.additionalInterfaceBounds[i]); | |||
for (int i = 0; i < tvrtBounds.length; i++) { | |||
aAndNotB.remove(tvrtBounds[i]); | |||
} | |||
if (! (aAndNotB.isEmpty() && bAndNotA.isEmpty()) ) return false; | |||
} |