import gov.nasa.jpf.Config;
import gov.nasa.jpf.annotation.MJI;
-// TODO: DIRTY HACKS!
-import java.lang.reflect.TypeVariable;
-import sun.reflect.generics.factory.CoreReflectionFactory;
-import sun.reflect.generics.factory.GenericsFactory;
-import sun.reflect.generics.repository.ClassRepository;
-import sun.reflect.generics.scope.ClassScope;
-
/**
* MJI NativePeer class for java.lang.Class library abstraction
*/
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: DIRTY HACKS!
- 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
// classes are initialized (they already might be)
return MJIEnv.NULL;
}
}
+
+ // TODO: Fix for Groovy's model-checking
+ private static int getParameterizedTypeImplObj(String className, String[] parameterizedTypes, String ownerType,
+ MJIEnv env, int objRef, int superObjRef) {
+
+ 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
+ ei.setReferenceField("rawType", superObjRef);
+
+ // actualTypeArguments
+ int[] types = new int[parameterizedTypes.length];
+ for(int j = 0; j < parameterizedTypes.length; j++) {
+ types[j] = getTypeVariableImplObject(env, objRef, parameterizedTypes[j]);
+ }
+ 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
+ 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;
+ }
+
+ 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;
+ }
+
+ @MJI
+ public int getGenericSuperclass____Ljava_lang_reflect_Type_2 (MJIEnv env, int robj){
+ ClassInfo ci = env.getReferredClassInfo( robj);
+ ClassInfo sci = ci.getSuperClass();
+ if (sci != null) {
+ String[] typeVars = sci.getGenericTypeVariableNames();
+ // Not a generic class
+ if (typeVars.length == 0) {
+ return sci.getClassObjectRef();
+ }
+ String className = sci.getName();
+ String ownerType = Types.getOwnerClassName(className);
+ int gRef = getParameterizedTypeImplObj(className, typeVars, ownerType, env, ci.getClassObjectRef(),
+ sci.getClassObjectRef());
+
+ return gRef;
+ } else {
+ return MJIEnv.NULL;
+ }
+ }
+
+ @MJI
+ public int getGenericInterfaces_____3Ljava_lang_reflect_Type_2 (MJIEnv env, int robj) {
+ // TODO: Need to add ParameterizedTypeImpl
+ ClassInfo ci = env.getReferredClassInfo(robj);
+ int aref = MJIEnv.NULL;
+ ThreadInfo ti = env.getThreadInfo();
+
+ // contrary to the API doc, this only returns the interfaces directly
+ // implemented by this class, not it's bases
+ // <2do> this is not exactly correct, since the interfaces should be ordered
+ Set<ClassInfo> interfaces = ci.getInterfaceClassInfos();
+ aref = env.newObjectArray("Ljava/lang/Class;", interfaces.size());
+
+ int i=0;
+ for (ClassInfo ifc: interfaces){
+ env.setReferenceArrayElement(aref, i++, ifc.getClassObjectRef());
+ }
+
+ return aref;
+ }
+
+ @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,
return ci.getClassObjectRef();
}
- // TODO: DIRTY HACKS!
- /*int createTypeVariableObject (MJIEnv env, ClassInfo objectCi, MethodInfo mi) {
- // NOTE - we rely on Constructor and Method peers being initialized
- if (mi.isCtor()){
- return JPF_java_lang_reflect_Constructor.createConstructorObject(env, objectCi, mi);
- } else {
- return JPF_java_lang_reflect_Method.createMethodObject(env, objectCi, mi);
- }
- }
-
- // accessor for factory
- private GenericsFactory getFactory() {
- // create scope and factory
- return CoreReflectionFactory.make(this, ClassScope.make(this));
- }
-
- @MJI
- public int getTypeParameters_____3Ljava_lang_reflect_TypeVariable_2 (MJIEnv env, int objRef){
- ClassInfo tci = getInitializedClassInfo(env, TYPEVARIABLE_CLASSNAME);
- if (tci == null) {
- env.repeatInvocation();
- return MJIEnv.NULL;
- }
- // Get the object and the type parameters
- ClassInfo ci = env.getReferredClassInfo(objRef);
- String signature = ci.getType();
- ClassRepository genericInfo = ClassRepository.make(signature, getFactory());
- TypeVariable[] typeVariables = (TypeVariable[]) genericInfo.getTypeParameters();
-
- int aref = env.newObjectArray("Ljava/lang/reflect/TypeVariable;", typeVariables.length);
-
- for(int i=0, j=0; i<typeVariables.length; i++){
- if (typeVariables[i] != null) {
- int mref = env.newObject(ci);
- env.setReferenceArrayElement(aref,j++,mref);
- }
- }
-
- return aref;
- }*/
- // TODO: DIRTY HACKS!
-
@MJI
public boolean desiredAssertionStatus____Z (MJIEnv env, int robj) {
ClassInfo ci = env.getReferredClassInfo(robj);