Adding ParameterizedTypeImpl to getGenericSuperclass method.
[jpf-core.git] / src / peers / gov / nasa / jpf / vm / JPF_java_lang_reflect_Method.java
index efb46e8ec1fdf8415ac5a48e4c01f5cb563095da..fa6ceee3b57261c7eace92feeb699229f9bdbe17 100644 (file)
@@ -23,6 +23,7 @@ import gov.nasa.jpf.util.MethodInfoRegistry;
 import gov.nasa.jpf.util.RunListener;
 import gov.nasa.jpf.util.RunRegistry;
 
+import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.util.ArrayList;
 
@@ -115,7 +116,7 @@ public class JPF_java_lang_reflect_Method extends NativePeer {
   }
 
   // TODO: Fix for Groovy's model-checking
-  private static int getParameterizedTypeImplObj(String signature, MJIEnv env) {
+  private static int getParameterizedTypeImplObj(String signature, MJIEnv env, int objRef, MethodInfo mi) {
 
     ThreadInfo ti = env.getThreadInfo();
     ClassLoaderInfo cli = env.getSystemClassLoaderInfo();
@@ -133,14 +134,21 @@ public class JPF_java_lang_reflect_Method extends NativePeer {
     ei.setReferenceField("rawType", gci.getClassObjectRef());
 
     // actualTypeArguments
-    String[] parameterizedTypes = Types.getParameterizedTypesFromArgumentTypeNames(signature);
+    String[] parameterizedTypes = Types.getParameterizedTypes(signature);
     int[] types = new int[parameterizedTypes.length];
+    String classGenericSig = mi.getClassInfo().getGenericSignature();
+    String methodGenericSig = mi.getGenericSignature();
     for(int j = 0; j < parameterizedTypes.length; j++) {
-      ClassInfo pci = cli.getResolvedClassInfo(parameterizedTypes[j]);
-      if (!pci.isRegistered()) {
-        pci.registerClass(ti);
+      if (Types.isTypeParameter(parameterizedTypes[j], methodGenericSig) ||
+          Types.isTypeParameter(parameterizedTypes[j], classGenericSig)) {
+        types[j] = getTypeVariableImplObject(env, objRef, parameterizedTypes[j]);
+      } else {
+        ClassInfo pci = cli.getResolvedClassInfo(parameterizedTypes[j]);
+        if (!pci.isRegistered()) {
+          pci.registerClass(ti);
+        }
+        types[j] = pci.getClassObjectRef();
       }
-      types[j] = pci.getClassObjectRef();
     }
     int aRef = env.newObjectArray("Ljava/lang/reflect/Type;", parameterizedTypes.length);
     // Set references for every array element
@@ -164,6 +172,20 @@ public class JPF_java_lang_reflect_Method extends NativePeer {
     return paramTypeRef;
   }
 
+  private static int getTypeVariableImplObject(MJIEnv env, int objRef, String parameterizedType) {
+
+    ClassLoaderInfo cli = env.getSystemClassLoaderInfo();
+    ClassInfo ci = cli.getResolvedClassInfo("sun.reflect.generics.reflectiveObjects.TypeVariableImpl");
+
+    int typeVarRef = env.newObject(ci);
+    ElementInfo ei = env.getModifiableElementInfo(typeVarRef);
+    // genericDeclaration contains this java.lang.reflect.Method object
+    ei.setReferenceField("genericDeclaration", objRef);
+    ei.setReferenceField("name", env.newString(parameterizedType));
+
+    return typeVarRef;
+  }
+
   static int getGenericParameterTypes( MJIEnv env, int objRef, MethodInfo mi) {
     ThreadInfo ti = env.getThreadInfo();
     String[] argTypeNames = mi.getArgumentGenericTypeNames();
@@ -172,7 +194,7 @@ public class JPF_java_lang_reflect_Method extends NativePeer {
     for (int i = 0; i < argTypeNames.length; i++) {
       // Change this into just the generic class type if it is a generic class
       if (Types.isGenericSignature(argTypeNames[i])) {
-        ar[i] = getParameterizedTypeImplObj(argTypeNames[i], env);
+        ar[i] = getParameterizedTypeImplObj(argTypeNames[i], env, objRef, mi);
       } else {
         ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(argTypeNames[i]);
         if (!ci.isRegistered()) {
@@ -199,12 +221,18 @@ public class JPF_java_lang_reflect_Method extends NativePeer {
     MethodInfo mi = getMethodInfo(env, objRef);
     ThreadInfo ti = env.getThreadInfo();
 
-    ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(mi.getReturnTypeName());
-    if (!ci.isRegistered()) {
-      ci.registerClass(ti);
+    int retRef;
+    if (Types.isGenericSignature(mi.getGenericReturnTypeName())) {
+      retRef = getParameterizedTypeImplObj(mi.getGenericReturnTypeName(), env, objRef, mi);
+    } else {
+      ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(mi.getReturnTypeName());
+      if (!ci.isRegistered()) {
+        ci.registerClass(ti);
+      }
+      retRef = ci.getClassObjectRef();
     }
 
-    return ci.getClassObjectRef();
+    return retRef;
   }
   // TODO: Fix for Groovy's model-checking
   // TODO: We have been able to only register the generic class and not yet the parameterized types