A clean implementation for getTypeParameters' native method version.
[jpf-core.git] / src / peers / gov / nasa / jpf / vm / JPF_java_lang_Class.java
index c76ecb8d139cc5281bfd54752d59f527202b5c46..8ace89649bd8d992b6594377dbaf47bec18e4f13 100644 (file)
@@ -26,7 +26,6 @@ import java.util.Set;
 import gov.nasa.jpf.Config;
 import gov.nasa.jpf.annotation.MJI;
 
-
 /**
  * MJI NativePeer class for java.lang.Class library abstraction
  */
@@ -35,6 +34,8 @@ public class JPF_java_lang_Class extends NativePeer {
   static final String FIELD_CLASSNAME = "java.lang.reflect.Field";
   static final String METHOD_CLASSNAME = "java.lang.reflect.Method";
   static final String CONSTRUCTOR_CLASSNAME = "java.lang.reflect.Constructor";
+  // TODO: Fix for Groovy's model-checking
+  static final String TYPEVARIABLE_CLASSNAME = "java.lang.reflect.TypeVariable";
   
   public static boolean init (Config conf){
     // we create Method and Constructor objects, so we better make sure these
@@ -107,6 +108,40 @@ public class JPF_java_lang_Class extends NativePeer {
       return MJIEnv.NULL;
     }
   }
+
+  // TODO: Fix for Groovy's model-checking
+  @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");
+    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;
+  }
   
   @MJI
   public int getAnnotation__Ljava_lang_Class_2__Ljava_lang_annotation_Annotation_2 (MJIEnv env, int robj,