public static void main(String[] args) {
- /*Method[] methods = SampleClass.class.getMethods();
+ Method[] methods = SampleClass.class.getMethods();
Type[] parameters = methods[0].getGenericParameterTypes();
//Type[] parameters = methods[0].getGenericParameterTypes();
for (int i = 0; i < parameters.length; i++) {
System.out.println(parameters[i]);
}
System.out.println();
- Class[] parameterTypes = methods[0].getParameterTypes();
+ /*Class[] parameterTypes = methods[0].getParameterTypes();
for(Class parameterType: parameterTypes){
System.out.println(parameterType.getName());
}
System.out.println();*/
- TypeVariable[] typeParameters = GenericShort.class.getTypeParameters();
+ /*TypeVariable[] typeParameters = GenericShort.class.getTypeParameters();
//TypeVariable[] typeParameters = SampleClass.class.getTypeParameters();
for(TypeVariable typeVar: typeParameters){
System.out.println(typeVar);
- }
+ }*/
System.out.println();
/*
Type returnType = methods[0].getGenericReturnType();
throw new JPFException("invalid method declaration: " + methodDecl);
}
+ // TODO: Fix for Groovy's model-checking
public static String[] getGenericTypeVariableNames(String signature) {
int pos = 0;
- int opening = 0;
+ int marker = 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);
+ marker = signature.indexOf(';', pos);
// Break if this is the end of the type variable names
- if (signature.charAt(opening + 1) == '>')
+ if (signature.charAt(marker + 1) == '>')
break;
}
int colon = signature.indexOf(':', pos);
- String typeVarName = signature.substring(opening + 1, colon);
+ String typeVarName = signature.substring(marker + 1, colon);
typeVarNames.add(typeVarName);
pos = colon + 1;
}
return arrTypeVarNames;
}
-
+
+ // TODO: Fix for Groovy's model-checking
+ public static String[] getParameterizedTypesFromArgumentTypeNames(String signature) {
+ int pos = signature.indexOf('<', 0);
+ if (pos == -1)
+ return new String[0];
+ ArrayList<String> typeVarNames = new ArrayList<>();
+
+ while (pos < signature.length()) {
+ String typeVarName = "";
+ int comma = signature.indexOf(',', pos);
+ if (comma == -1) {
+ int closing = signature.indexOf('>', pos);
+ typeVarName = signature.substring(pos + 1, closing);
+ pos = signature.length();
+ } else {
+ typeVarName = signature.substring(pos + 1, comma);
+ pos = comma + 1;
+ }
+ typeVarNames.add(typeVarName);
+ }
+
+ String[] arrTypeVarNames = new String[typeVarNames.size()];
+ typeVarNames.toArray(arrTypeVarNames);
+
+ return arrTypeVarNames;
+ }
+
+ public static String getGenericClassName(String signature) {
+ int opening = signature.indexOf('<');
+ if (opening == -1)
+ return signature;
+ else
+ return signature.substring(0, opening);
+ }
+
+ public static String getOwnerClassName(String signature) {
+ int marker = signature.indexOf('$');
+ if (marker == -1)
+ return null;
+ else
+ return signature.substring(0, marker);
+ }
+
+ public static boolean isGenericSignature(String signature) {
+ int opening = signature.indexOf('<');
+ return (opening != -1);
+ }
+ // TODO: Fix for Groovy's model-checking
}
}
// TODO: Fix for Groovy's model-checking
- // TODO: We have been able to only register the generic class and not yet the parameterized types
- static int getGenericParameterTypes( MJIEnv env, MethodInfo mi) {
+ private static int getParameterizedTypeImplObj(String signature, MJIEnv env) {
+
+ ThreadInfo ti = env.getThreadInfo();
+ ClassLoaderInfo cli = env.getSystemClassLoaderInfo();
+ ClassInfo ci = cli.getResolvedClassInfo("sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl");
+ // Create a new object of type ParameterizedTypeImpl
+ int paramTypeRef = env.newObject(ci);
+ ElementInfo ei = env.getModifiableElementInfo(paramTypeRef);
+ // Get field information and fill out the fields
+ // rawType field
+ String className = Types.getGenericClassName(signature);
+ ClassInfo gci = cli.getResolvedClassInfo(className);
+ if (!gci.isRegistered()) {
+ gci.registerClass(ti);
+ }
+ ei.setReferenceField("rawType", gci.getClassObjectRef());
+
+ // actualTypeArguments
+ String[] parameterizedTypes = Types.getParameterizedTypesFromArgumentTypeNames(signature);
+ int[] types = new int[parameterizedTypes.length];
+ for(int j = 0; j < parameterizedTypes.length; j++) {
+ ClassInfo pci = cli.getResolvedClassInfo(parameterizedTypes[j]);
+ if (!pci.isRegistered()) {
+ pci.registerClass(ti);
+ }
+ types[j] = pci.getClassObjectRef();
+ }
+ int aRef = env.newObjectArray("Ljava/lang/reflect/Type;", parameterizedTypes.length);
+ // Set references for every array element
+ for (int j = 0; j < parameterizedTypes.length; j++) {
+ env.setReferenceArrayElement(aRef, j, types[j]);
+ }
+ ei.setReferenceField("actualTypeArguments", aRef);
+
+ // ownerType
+ String ownerType = Types.getOwnerClassName(signature);
+ if (ownerType != null) {
+ ClassInfo oci = ClassLoaderInfo.getCurrentResolvedClassInfo(ownerType);
+ if (!oci.isRegistered()) {
+ oci.registerClass(ti);
+ }
+ ei.setReferenceField("ownerType", oci.getClassObjectRef());
+ } else {
+ ei.setReferenceField("ownerType", MJIEnv.NULL);
+ }
+
+ return paramTypeRef;
+ }
+
+ static int getGenericParameterTypes( MJIEnv env, int objRef, MethodInfo mi) {
ThreadInfo ti = env.getThreadInfo();
String[] argTypeNames = mi.getArgumentGenericTypeNames();
int[] ar = new int[argTypeNames.length];
for (int i = 0; i < argTypeNames.length; i++) {
// Change this into just the generic class type if it is a generic class
- String genericTypeName = argTypeNames[i];
- int startOfGenericParameter = argTypeNames[i].indexOf('<');
- if (startOfGenericParameter != -1) {
- genericTypeName = argTypeNames[i].substring(0, startOfGenericParameter);
- }
- ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(genericTypeName);
- if (!ci.isRegistered()) {
- ci.registerClass(ti);
+ if (Types.isGenericSignature(argTypeNames[i])) {
+ ar[i] = getParameterizedTypeImplObj(argTypeNames[i], env);
+ } else {
+ ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(argTypeNames[i]);
+ if (!ci.isRegistered()) {
+ ci.registerClass(ti);
+ }
+ ar[i] = ci.getClassObjectRef();
}
-
- ar[i] = ci.getClassObjectRef();
}
-
int aRef = env.newObjectArray("Ljava/lang/reflect/Type;", argTypeNames.length);
for (int i = 0; i < argTypeNames.length; i++) {
env.setReferenceArrayElement(aRef, i, ar[i]);
@MJI
public int getGenericParameterTypes_____3Ljava_lang_reflect_Type_2 (MJIEnv env, int objRef){
- return getGenericParameterTypes(env, getMethodInfo(env, objRef));
+ return getGenericParameterTypes(env, objRef, getMethodInfo(env, objRef));
}
@MJI