public final static PrintStream out = System.out;
private final static DelegatingOutputStream delegatingErr;
private final static DelegatingOutputStream delegatingOut;
- public final static boolean DEFAULT_VERBOSE = true;//getBoolean("org.aspectj.tools.ajc.AjcTestCase.verbose",false);
+ public final static boolean DEFAULT_VERBOSE = false;//getBoolean("org.aspectj.tools.ajc.AjcTestCase.verbose",false);
public final static boolean DEFAULT_ERR_VERBOSE = getBoolean("org.aspectj.tools.ajc.AjcTestCase.verbose.err",DEFAULT_VERBOSE);
public final static boolean DEFAULT_OUT_VERBOSE = getBoolean("org.aspectj.tools.ajc.AjcTestCase.verbose.out",DEFAULT_VERBOSE);
<ajc-test dir="bugs150" title="abstract perthis in @AspectJ">
<compile files="pr121197.aj" options="-1.5"/>
</ajc-test>
+
+ <ajc-test dir="bugs150" title="different numbers of type vars">
+ <compile files="pr121575.aj" options="-1.5"/>
+ <run class="pr121575"/>
+ </ajc-test>
+
+ <ajc-test dir="java5/generics/tvars" title="different numbers of type vars - 2">
+ <compile files="Case1.aj" options="-1.5 -showWeaveInfo">
+ <message kind="weave" text="Join point 'method-execution(void MyClass.read(java.lang.String))' in Type 'MyClass' (Case1.aj:13) advised by before advice from 'MyAspect' (Case1.aj:5)"/>
+ </compile>
+ </ajc-test>
+
+ <ajc-test dir="java5/generics/tvars" title="different numbers of type vars - 3">
+ <compile files="Case2.aj" options="-1.5 -showWeaveInfo">
+ <message kind="weave" text="Join point 'method-execution(void MyClass.read(java.lang.Number))' in Type 'MyClass' (Case2.aj:13) advised by before advice from 'MyAspect' (Case2.aj:5)"/>
+ </compile>
+ </ajc-test>
+
+ <ajc-test dir="java5/generics/tvars" title="different numbers of type vars - 4">
+ <compile files="Case3.aj" options="-1.5 -showWeaveInfo">
+ <message kind="error" line="9" text="The type MyClass<T,E> must implement the inherited abstract method MyInterface<T>.read(T)"/>
+ </compile>
+ </ajc-test>
<ajc-test dir="bugs150" title="access to private ITD from nested type">
parameterizedInterfaces[i] =
parameterizedInterfaces[i].getRawType().resolve(getWorld());
} else if (parameterizedInterfaces[i].isParameterizedType()) {
- // a parameterized supertype collapses any type vars to their upper
- // bounds
- parameterizedInterfaces[i] =
- parameterizedInterfaces[i].parameterizedWith(paramTypes);
+ // a parameterized supertype collapses any type vars to their upper bounds
+ UnresolvedType[] toUseForParameterization = determineThoseTypesToUse(parameterizedInterfaces[i],paramTypes);
+ parameterizedInterfaces[i] = parameterizedInterfaces[i].parameterizedWith(toUseForParameterization);
}
}
return parameterizedInterfaces;
}
return delegate.getDeclaredInterfaces();
}
+
+ /**
+ * 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
+ * used. For example:
+ * <code>
+ * class Foo<T extends String,E extends Number> implements SuperInterface<T> {}
+ * </code>
+ * where
+ * <code>
+ * interface SuperInterface<Z> {}
+ * </code>
+ * In that example, a use of the 'Foo' raw type should know that it implements
+ * the SuperInterface<String>.
+ */
+ private UnresolvedType[] determineThoseTypesToUse(ResolvedType parameterizedInterface,UnresolvedType[] paramTypes) {
+ // What are the type parameters for the supertype?
+ UnresolvedType[] tParms = parameterizedInterface.getTypeParameters();
+ UnresolvedType[] retVal = new UnresolvedType[tParms.length];
+
+ // Go through the supertypes type parameters, if any of them is a type variable, use the
+ // real type variable on the declaring type.
+
+ // it is possibly overkill to look up the type variable - ideally the entry in the type parameter list for the
+ // interface should be the a ref to the type variable in the current type ... but I'm not 100% confident right now.
+ for (int i = 0; i < tParms.length; i++) {
+ UnresolvedType tParm = tParms[i];
+ if (tParm.isTypeVariableReference()) {
+ TypeVariableReference tvrt = (TypeVariableReference)tParm;
+ TypeVariable tv = tvrt.getTypeVariable();
+ int rank = getRank(tv.getName());
+ retVal[i]= paramTypes[rank];
+ } else {
+ retVal[i] = tParms[i];
+ }
+
+ }
+ return retVal;
+ }
+
+ /**
+ * Returns the position within the set of type variables for this type for the specified type variable name.
+ * Returns -1 if there is no type variable with the specified name.
+ */
+ private int getRank(String tvname) {
+ TypeVariable[] thisTypesTVars = getGenericType().getTypeVariables();
+ for (int i = 0; i < thisTypesTVars.length; i++) {
+ TypeVariable tv = thisTypesTVars[i];
+ if (tv.getName().equals(tvname)) return i;
+ }
+ return -1;
+ }
public ResolvedMember[] getDeclaredMethods() {
if (parameterizedMethods != null) return parameterizedMethods;