public class Reflection {
+ class GenericShort<TUVW,ABCD> {
+ }
+
class Generic<TUVW,ABCD,KLM,NOP> {
}
}
System.out.println();*/
- TypeVariable[] typeParameters = Generic.class.getTypeParameters();
+ TypeVariable[] typeParameters = GenericShort.class.getTypeParameters();
//TypeVariable[] typeParameters = SampleClass.class.getTypeParameters();
for(TypeVariable typeVar: typeParameters){
System.out.println(typeVar);
*/
public class TypeVariableImpl<D extends GenericDeclaration>
extends LazyReflectiveObjectGenerator implements TypeVariable<D> {
-//public class TypeVariableImpl {
+
D genericDeclaration;
private String name;
- private Type[] bounds;
- private FieldTypeSignature[] boundASTs;
- //private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0];
// constructor is private to enforce access through static factory
private TypeVariableImpl(D decl, String n, FieldTypeSignature[] bs,
super(f);
genericDeclaration = decl;
name = n;
- boundASTs = bs;
}
// Accessors
public DirectCallStackFrame createRunStartStackFrame (ThreadInfo ti, MethodInfo miRun){
return null;
}
+
+ // TODO: Fix for Groovy's model-checking
+ public String[] getGenericTypeVariableNames () {
+ // To accommodate methods that do not have generic types
+ if (genericSignature == null)
+ return new String[0];
+ return Types.getGenericTypeVariableNames(genericSignature);
+ }
}
// TODO: Fix for Groovy's model-checking
public String[] getArgumentGenericTypeNames () {
// To accommodate methods that do not have generic types
- if (genericSignature == "")
+ if (genericSignature == null)
return getArgumentTypeNames();
return Types.getArgumentTypeNames(genericSignature);
}
throw new JPFException("invalid method declaration: " + methodDecl);
}
+
+ public static String[] getGenericTypeVariableNames(String signature) {
+ int pos = 0;
+ int opening = 0;
+ ArrayList<String> typeVarNames = new ArrayList<>();
+
+ while (pos < signature.length()) {
+ if (pos > 0) {
+ // Start from ';' if this is not the first type variable name
+ opening = signature.indexOf(';', pos);
+ // Break if this is the end of the type variable names
+ if (signature.charAt(opening + 1) == '>')
+ break;
+ }
+ int colon = signature.indexOf(':', pos);
+ String typeVarName = signature.substring(opening + 1, colon);
+ typeVarNames.add(typeVarName);
+ pos = colon + 1;
+ }
+
+ String[] arrTypeVarNames = new String[typeVarNames.size()];
+ typeVarNames.toArray(arrTypeVarNames);
+
+ return arrTypeVarNames;
+ }
}
}
// TODO: Fix for Groovy's model-checking
- // TODO: THIS NEEDS TO BE SUBSTITUTED BY THE PROPER METHODS! VERY DIRTY RIGHT NOW!
@MJI
public int getTypeParameters_____3Ljava_lang_reflect_TypeVariable_2 (MJIEnv env, int robj){
+ // Get the ClassInfo for this class
+ ClassInfo tci = env.getReferredClassInfo(robj);
+ String[] typeVars = tci.getGenericTypeVariableNames();
+
+ // Return with null if this is not a generic class
+ if (typeVars.length == 0) {
+ int aRef = env.newObjectArray("Ljava/lang/reflect/TypeVariable;", 0);
+ return aRef;
+ }
+ // Now create a TypeVariableImpl object for every type variable name; get the ClassInfo for TypeVariableImpl
ClassLoaderInfo cli = env.getSystemClassLoaderInfo();
ClassInfo ci = cli.getResolvedClassInfo("sun.reflect.generics.reflectiveObjects.TypeVariableImpl");
- //ClassInfo rci = cli.getResolvedClassInfo("sun.reflect.generics.reflectiveObjects.Test");
- // TODO: Need to 1) Just create the object of TypeVariableImpl, 2) Declare class type and name only, 3) Return the
- // object reference back to the caller
- int tvRef = env.newObject(ci);
- ElementInfo ei = env.getModifiableElementInfo(tvRef);
-
- ClassInfo tci = env.getReferredClassInfo( robj);
- //ei.setReferenceField("genericDeclaration", env.newObject(tci.getName() + ".class"));
- ei.setReferenceField("name", env.newString("TUVW"));
- int aRef = env.newObjectArray("Ljava/lang/reflect/TypeVariable;", 1);
- for (int i = 0; i < 1; i++) {
- env.setReferenceArrayElement(aRef, i, tvRef);
+ int[] var = new int[typeVars.length];
+
+ for(int i = 0; i < typeVars.length; i++) {
+ int typeVarRef = env.newObject(ci);
+ ElementInfo ei = env.getModifiableElementInfo(typeVarRef);
+ ei.setReferenceField("genericDeclaration", tci.getClassObjectRef());
+ ei.setReferenceField("name", env.newString(typeVars[i]));
+ var[i] = typeVarRef;
+ }
+ int aRef = env.newObjectArray("Ljava/lang/reflect/TypeVariable;", typeVars.length);
+
+ // Set references for every array element
+ for (int i = 0; i < typeVars.length; i++) {
+ env.setReferenceArrayElement(aRef, i, var[i]);
}
return aRef;