First attempt to add getGenericParameterTypes() and getGenericReturnType(); So far...
authorrtrimana <rtrimana@uci.edu>
Thu, 13 Jun 2019 23:47:25 +0000 (16:47 -0700)
committerrtrimana <rtrimana@uci.edu>
Thu, 13 Jun 2019 23:47:25 +0000 (16:47 -0700)
examples/Reflection.java
src/main/gov/nasa/jpf/vm/MethodInfo.java
src/main/gov/nasa/jpf/vm/Types.java
src/peers/gov/nasa/jpf/vm/JPF_java_lang_reflect_Method.java

index ac04e04..4619e4b 100644 (file)
@@ -3,58 +3,62 @@ import java.lang.reflect.Type;
 import java.lang.reflect.TypeVariable;
 
 import java.util.List;
+import java.util.Map;
 import java.util.ArrayList;
 
 public class Reflection {
 
-       class Generic<T,E> {
+       class Generic<TUVW,ABCD,KLM,NOP> {
        
        }
 
        class SampleClass {
           private String sampleField;
 
-          public String getSampleField() {
-                 return sampleField;
-          }
-
-          /*public List<String> setSampleField(List<String> listString, 
+          public Generic<Integer,String,Double,Short> setSampleField(List<String> listString, Map<Integer,String> mapString,
+                               Generic<Integer,String,Double,Short> test,
                                String sampleField, int one, short two, double three, Object obj) {
                  this.sampleField = sampleField; 
-                 return listString;
+                 return test;
+          }
+          
+          /*
+          public String getSampleField() {
+                 return sampleField;
           }
           
           public void setSampleField(String sampleField) {
              this.sampleField = sampleField;
-          }*/
+          }
           
           public List<String> setSampleField(List<String> listString) {
                  return listString;
-          }
+          }*/
        }
 
    public static void main(String[] args) {
 
       Method[] methods = SampleClass.class.getMethods();
-      /*Type[] parameters = methods[1].getGenericParameterTypes();
+      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[6].getParameterTypes();
+      System.out.println();
+      Class[] parameterTypes = methods[0].getParameterTypes();
       for(Class parameterType: parameterTypes){
          System.out.println(parameterType.getName());   
  
       }
       System.out.println();
-      TypeVariable[] typeParameters = Generic.class.getTypeParameters();
+      /*TypeVariable[] typeParameters = Generic.class.getTypeParameters();
       for(TypeVariable typeVar: typeParameters){
          System.out.println(typeVar);   
  
       }
-      /*System.out.println();
-      Type returnType = methods[1].getGenericReturnType();
-      System.out.println(returnType);*/
+      System.out.println();*/
+      Type returnType = methods[0].getGenericReturnType();
+      System.out.println(returnType);
    }
 }
 
index a4880c7..a5a83bb 100644 (file)
@@ -502,7 +502,15 @@ public class MethodInfo extends InfoObject implements GenericSignatureHolder  {
   public String[] getArgumentTypeNames () {
     return Types.getArgumentTypeNames(signature);
   }
-  
+
+  // TODO: Fix for Groovy's model-checking
+  public String[] getArgumentGenericTypeNames () {
+    // To accommodate methods that do not have generic types
+    if (genericSignature == "")
+      return getArgumentTypeNames();
+    return Types.getArgumentTypeNames(genericSignature);
+  }
+
   public int getArgumentsSize () {
     if (argSize < 0) {
       argSize = Types.getArgumentsSize(signature);
@@ -579,6 +587,11 @@ public class MethodInfo extends InfoObject implements GenericSignatureHolder  {
   public String getReturnTypeName () {
     return Types.getReturnTypeName(signature);
   }
+
+  // TODO: Fix for Groovy's model-checking
+  public String getGenericReturnTypeName () {
+    return Types.getGenericReturnTypeName(signature);
+  }
   
   public String getSourceFileName () {
     if (ci != null) {
index ee64f70..c5b2f7f 100644 (file)
@@ -73,6 +73,9 @@ public class Types {
     return args;
   }
 
+  // TODO: Fix for Groovy's model-checking
+  // TODO: We return the generic type name whenever possible (the one between '<' and '>')
+  // TODO: To do this we fixed the implementation of getTypeLength
   public static String[] getArgumentTypeNames (String signature) {
     int len = signature.length();
 
@@ -95,7 +98,7 @@ public class Types {
     
     return typeNames;
   }
-  
+
   public static String dequalify (String typeName){
     int idx = typeName.lastIndexOf('.');
     if (idx > 0) {
@@ -585,6 +588,11 @@ public class Types {
     int i = signature.indexOf(')');
     return getTypeName(signature.substring(i+1));
   }
+
+  public static String getGenericReturnTypeName (String signature){
+    int i = signature.indexOf(')');
+    return getTypeName(signature.substring(i+1));
+  }
   
   public static String getTypeSignature (String type, boolean asDotNotation) {
     String  t = null;
@@ -906,9 +914,16 @@ public class Types {
 
     int len1 = len-1;
     if (signature.charAt(len1) == ';') {
-      return signature.substring(1, len1).replace('/', '.');
+      // TODO: Fix for Groovy's model-checking
+      // TODO: Cleaning up the generic type part inside '<' and '>'
+      return signature.substring(1, len1).replace('/', '.').
+              replaceAll(";L", ", ").
+              replace("<L","<").
+              replace(";>", ">");
     }
 
+
+
     throw new JPFException("invalid type string: " + signature);
   }
 
@@ -1091,6 +1106,15 @@ public class Types {
     case 'L':
 
       int semicolon = signature.indexOf(';', idx);
+      // TODO: Fix for Groovy's model-checking
+      // Check if this is a generic!
+      if (signature.substring(idx,semicolon).indexOf('<') != -1) {
+        int generic = signature.indexOf('>', semicolon);
+        if (generic != -1) {
+          // Advance one character past the ';'
+          semicolon = generic + 1;
+        }
+      }
 
       if (semicolon == -1) {
         throw new JPFException("invalid type signature: " +
index 964968d..2f485e1 100644 (file)
@@ -115,17 +115,54 @@ public class JPF_java_lang_reflect_Method extends NativePeer {
   }
 
   // TODO: Fix for Groovy's model-checking
+  // TODO: We haven't been able to show the parameterized types
+  static int getGenericParameterTypes( MJIEnv env, 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);
+      }
+
+      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]);
+    }
+
+    return aRef;
+  }
+
   @MJI
   public int getGenericParameterTypes_____3Ljava_lang_reflect_Type_2 (MJIEnv env, int objRef){
-    //return getGenericParameterTypes(env, getMethodInfo(env, objRef));
-    return getParameterTypes_____3Ljava_lang_Class_2 (env, objRef);
+    return getGenericParameterTypes(env, getMethodInfo(env, objRef));
   }
 
   @MJI
   public int getGenericReturnType____Ljava_lang_reflect_Type_2 (MJIEnv env, int objRef){
-    return getReturnType____Ljava_lang_Class_2(env, objRef);
+    MethodInfo mi = getMethodInfo(env, objRef);
+    ThreadInfo ti = env.getThreadInfo();
+
+    ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(mi.getReturnTypeName());
+    if (!ci.isRegistered()) {
+      ci.registerClass(ti);
+    }
+
+    return ci.getClassObjectRef();
   }
   // TODO: Fix for Groovy's model-checking
+  // TODO: We haven't been able to show the parameterized types
   
   int getExceptionTypes(MJIEnv env, MethodInfo mi) {
     ThreadInfo ti = env.getThreadInfo();