/** * 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()); // -1 probably means it is a reference to a type variable on the outer generic type (see // pr129566) if (rank != -1) { retVal[i] = paramTypes[rank]; } else { retVal[i] = tParms[i]; } } else { retVal[i] = tParms[i]; } } return retVal; }
@Override protected void setUp() throws Exception { super.setUp(); world = new BcelWorld(); javaLangClass = (ReferenceType) world.resolve(UnresolvedType.forName("java/lang/Class")); javaLangObject = (ReferenceType) world.resolve(UnresolvedType.OBJECT); extendsClass = new BoundedReferenceType(javaLangClass, true, world); superClass = new BoundedReferenceType(javaLangClass, false, world); extendsWithExtras = new BoundedReferenceType( javaLangClass, true, world, new ReferenceType[] { (ReferenceType) world.resolve(UnresolvedType.forName("java/util/List")) }); }
public void testCanBeParameterizedRegularMethod() { BcelWorld world = new BcelWorld(); ResolvedType javaLangClass = world.resolve(UnresolvedType.forName("java/lang/Class")); ResolvedMember[] methods = javaLangClass.getDeclaredMethods(); ResolvedMember getAnnotations = null; for (int i = 0; i < methods.length; i++) { if (methods[i].getName().equals("getAnnotations")) { getAnnotations = methods[i]; break; } } if (getAnnotations != null) { // so can run on non-Java 5 // System.out.println("got it"); assertFalse(getAnnotations.canBeParameterized()); } }
public void testCanBeParameterizedMethodInGenericType() { BcelWorld world = new BcelWorld(); world.setBehaveInJava5Way(true); ResolvedType javaUtilList = world.resolve(UnresolvedType.forName("java.util.List")); javaUtilList = javaUtilList.getGenericType(); if (javaUtilList == null) return; // for < 1.5 ResolvedMember[] methods = javaUtilList.getDeclaredMethods(); ResolvedMember add = null; for (int i = 0; i < methods.length; i++) { if (methods[i].getName().equals("add")) { add = methods[i]; break; } } if (add != null) { // so can run on non-Java 5 // System.out.println("got it"); assertTrue(add.canBeParameterized()); } }
public static ReferenceType fromTypeX(UnresolvedType tx, World world) { ReferenceType rt = new ReferenceType(tx.getErasureSignature(), world); rt.typeKind = tx.typeKind; return rt; }
/** Create a reference type for a generic type */ public ReferenceType(UnresolvedType genericType, World world) { super(genericType.getSignature(), world); typeKind = TypeKind.GENERIC; }