@@ -0,0 +1,19 @@ | |||
interface Generic1<T extends Number> { | |||
public void foo(T p); | |||
} | |||
interface Generic2<T extends Number, Y extends Number> extends Generic1<T> { | |||
public void foo2(Y p); | |||
} | |||
public class Test<Y extends Number> implements Generic2<Y,Y>{ | |||
public void foo2(Y p) { } | |||
public void foo(Y p) { } | |||
public static void main(String []argv) { | |||
Test<Integer> t = new Test<Integer>(); | |||
t.foo(7); | |||
t.foo2(9); | |||
} | |||
} |
@@ -0,0 +1,19 @@ | |||
class Generic1<T extends Number> { | |||
public void foo(T p) { } | |||
} | |||
class Generic2<T extends Number, Y extends Number> extends Generic1<T> { | |||
public void foo2(Y p) {} | |||
} | |||
public class Test2<Y extends Number> extends Generic2<Y,Y>{ | |||
public void foo2(Y p) { } | |||
public void foo(Y p) { } | |||
public static void main(String []argv) { | |||
Test2<Integer> t = new Test2<Integer>(); | |||
t.foo(7); | |||
t.foo2(9); | |||
} | |||
} |
@@ -0,0 +1,8 @@ | |||
public privileged aspect TestAspect { | |||
pointcut TestInheritance(Test test) : target(test) && execution (* Generic1.*(..)); | |||
after (Test test) : TestInheritance(test) { | |||
System.err.println("Aspects:"+thisJoinPoint); | |||
} | |||
} | |||
@@ -0,0 +1,8 @@ | |||
public privileged aspect TestAspect2 { | |||
pointcut TestInheritance(Test2 test) : target(test) && execution (* Generic1.*(..)); | |||
after (Test2 test) : TestInheritance(test) { | |||
System.err.println("Aspects:"+thisJoinPoint); | |||
} | |||
} | |||
@@ -22,6 +22,8 @@ public class Ajc151Tests extends org.aspectj.testing.XMLBasedAjcTestCase { | |||
public void testMemberTypesInGenericTypes_pr122458_2() { runTest("member types in generic types - 2");} | |||
public void testNPEOnDeclareAnnotation_pr123695() { runTest("Internal nullptr exception with complex declare annotation");} | |||
public void testHasMemberPackageProblem_pr124105() { runTest("hasMember problems with packages");} | |||
public void testDifferentNumbersofTVars_pr124803() { runTest("generics and different numbers of type variables");} | |||
public void testDifferentNumbersofTVars_pr124803_2() { runTest("generics and different numbers of type variables - classes");} | |||
///////////////////////////////////////// | |||
public static Test suite() { |
@@ -22,5 +22,27 @@ | |||
</compile> | |||
</ajc-test> | |||
<ajc-test dir="bugs151/pr124803" title="generics and different numbers of type variables"> | |||
<compile files="Test.java,TestAspect.java" options="-1.5 -showWeaveInfo"> | |||
<message kind="weave" text="Join point 'method-execution(void Test.foo(java.lang.Number))' in Type 'Test' (Test.java:12) advised by after advice from 'TestAspect' (TestAspect.java:4)"/> | |||
</compile> | |||
<run class="Test"> | |||
<stderr> | |||
<line text="Aspects:execution(void Test.foo(Number))"/> | |||
</stderr> | |||
</run> | |||
</ajc-test> | |||
<ajc-test dir="bugs151/pr124803" title="generics and different numbers of type variables - classes"> | |||
<compile files="Test2.java,TestAspect2.java" options="-1.5 -showWeaveInfo"> | |||
<message kind="weave" text="Join point 'method-execution(void Test2.foo(java.lang.Number))' in Type 'Test2' (Test2.java:12) advised by after advice from 'TestAspect2' (TestAspect2.java:4)"/> | |||
<message kind="weave" text="Join point 'method-execution(void Generic1.foo(java.lang.Number))' in Type 'Generic1' (Test2.java:2) advised by after advice from 'TestAspect2' (TestAspect2.java:4) [with runtime test]"/> | |||
</compile> | |||
<run class="Test2"> | |||
<stderr> | |||
<line text="Aspects:execution(void Test2.foo(Number))"/> | |||
</stderr> | |||
</run> | |||
</ajc-test> | |||
</suite> |
@@ -386,7 +386,28 @@ public class ReferenceType extends ResolvedType { | |||
UnresolvedType[] paramTypes = getTypesForMemberParameterization(); | |||
parameterizedInterfaces = new ResolvedType[delegateInterfaces.length]; | |||
for (int i = 0; i < delegateInterfaces.length; i++) { | |||
parameterizedInterfaces[i] = delegateInterfaces[i].parameterizedWith(paramTypes); | |||
// We may have to subset the set of parametertypes if the implemented interface | |||
// needs less than this type does. (pr124803) | |||
// wonder if this could be done with getMemberParameterizationMap() like it is in getSuperclass()?? Something like: | |||
// parameterizedInterfaces[i] = delegateInterfaces[i].parameterize(getMemberParameterizationMap()).resolve(world); | |||
TypeVariable[] tvarsOnImplementedInterface = delegateInterfaces[i].getTypeVariables(); | |||
TypeVariable[] tvarsOnThisGenericType = this.genericType.getTypeVariables(); | |||
ResolvedType parameterizedInterface = null; | |||
if (tvarsOnImplementedInterface!=null && tvarsOnThisGenericType!=null) { | |||
if (tvarsOnImplementedInterface.length<tvarsOnThisGenericType.length) { | |||
// implemented interface is something like 'Generic<T>' where thisGenericType is something like 'Generic<T,Y>' | |||
// we need to subset the type parameters based on their name | |||
UnresolvedType[] subsetParameterTypes = new ResolvedType[tvarsOnImplementedInterface.length]; | |||
for (int j = 0; j < subsetParameterTypes.length; j++) { | |||
subsetParameterTypes[j] = findTypeParameterInList(tvarsOnImplementedInterface[j].getName(),tvarsOnThisGenericType,paramTypes); | |||
} | |||
parameterizedInterface = delegateInterfaces[i].parameterizedWith(subsetParameterTypes); | |||
} | |||
} | |||
if (parameterizedInterface==null) parameterizedInterface = delegateInterfaces[i].parameterizedWith(paramTypes); | |||
parameterizedInterfaces[i] = parameterizedInterface; | |||
} | |||
return parameterizedInterfaces; | |||
} else if (isRawType()){ | |||
@@ -410,6 +431,21 @@ public class ReferenceType extends ResolvedType { | |||
return delegate.getDeclaredInterfaces(); | |||
} | |||
/** | |||
* Locates the named type variable in the list of those on this generic type and returns | |||
* the type parameter from the second list supplied. Returns null if it can't be found | |||
*/ | |||
private UnresolvedType findTypeParameterInList(String name, TypeVariable[] tvarsOnThisGenericType, UnresolvedType[] paramTypes) { | |||
int position = -1; | |||
for (int i = 0; i < tvarsOnThisGenericType.length; i++) { | |||
TypeVariable tv = tvarsOnThisGenericType[i]; | |||
if (tv.getName().equals(name)) position = i; | |||
} | |||
if (position == -1 ) return null; | |||
return paramTypes[position]; | |||
} | |||
/** | |||
* It is possible this type has multiple type variables but the interface we are about to parameterize | |||
* only uses a subset - this method determines the subset to use by looking at the type variable names |