From 9530ffc869c8b7768131e093593200126918ee28 Mon Sep 17 00:00:00 2001 From: rtrimana Date: Fri, 21 Jun 2019 11:03:21 -0700 Subject: [PATCH] Adding ParameterizedTypeImpl to getGenericSuperclass method. --- examples/Reflection.java | 9 ++- src/main/gov/nasa/jpf/vm/Types.java | 2 + .../gov/nasa/jpf/vm/JPF_java_lang_Class.java | 66 ++++++++++++++++++- .../jpf/vm/JPF_java_lang_reflect_Method.java | 4 +- 4 files changed, 74 insertions(+), 7 deletions(-) diff --git a/examples/Reflection.java b/examples/Reflection.java index 538bcd1..d8f6e44 100644 --- a/examples/Reflection.java +++ b/examples/Reflection.java @@ -12,7 +12,7 @@ public class Reflection { class GenericShort { } - class Generic { + class Generic extends GenericShort { } @@ -42,7 +42,7 @@ public class Reflection { public static void main(String[] args) { - Method[] methods = SampleClass.class.getMethods(); + /*Method[] methods = SampleClass.class.getMethods(); // Method[] methods = Class.class.getMethods(); Method method = null; for(Method meth : methods) { @@ -55,7 +55,10 @@ public class Reflection { for (int i = 0; i < parameters.length; i++) { System.out.println(parameters[i]); } - System.out.println(); + System.out.println();*/ + Type superCls = Generic.class.getGenericSuperclass(); + //Type superCls = String.class.getGenericSuperclass(); + System.out.println(superCls); /*Class[] parameterTypes = methods[0].getParameterTypes(); for(Class parameterType: parameterTypes){ System.out.println(parameterType.getName()); diff --git a/src/main/gov/nasa/jpf/vm/Types.java b/src/main/gov/nasa/jpf/vm/Types.java index 6c34925..90e7f54 100644 --- a/src/main/gov/nasa/jpf/vm/Types.java +++ b/src/main/gov/nasa/jpf/vm/Types.java @@ -1248,6 +1248,8 @@ public class Types { } public static boolean isGenericSignature(String signature) { + if (signature == null || signature.equals("")) + return false; int opening = signature.indexOf('<'); return (opening != -1); } diff --git a/src/peers/gov/nasa/jpf/vm/JPF_java_lang_Class.java b/src/peers/gov/nasa/jpf/vm/JPF_java_lang_Class.java index ccc9815..cdc5dd7 100644 --- a/src/peers/gov/nasa/jpf/vm/JPF_java_lang_Class.java +++ b/src/peers/gov/nasa/jpf/vm/JPF_java_lang_Class.java @@ -108,13 +108,75 @@ public class JPF_java_lang_Class extends NativePeer { } // 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){ - // TODO: Need to add ParameterizedTypeImpl ClassInfo ci = env.getReferredClassInfo( robj); ClassInfo sci = ci.getSuperClass(); if (sci != null) { - return sci.getClassObjectRef(); + 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; } diff --git a/src/peers/gov/nasa/jpf/vm/JPF_java_lang_reflect_Method.java b/src/peers/gov/nasa/jpf/vm/JPF_java_lang_reflect_Method.java index 48aff58..fa6ceee 100644 --- a/src/peers/gov/nasa/jpf/vm/JPF_java_lang_reflect_Method.java +++ b/src/peers/gov/nasa/jpf/vm/JPF_java_lang_reflect_Method.java @@ -141,7 +141,7 @@ public class JPF_java_lang_reflect_Method extends NativePeer { for(int j = 0; j < parameterizedTypes.length; j++) { if (Types.isTypeParameter(parameterizedTypes[j], methodGenericSig) || Types.isTypeParameter(parameterizedTypes[j], classGenericSig)) { - types[j] = getTypeVariableImplObject(env, objRef, mi, parameterizedTypes[j]); + types[j] = getTypeVariableImplObject(env, objRef, parameterizedTypes[j]); } else { ClassInfo pci = cli.getResolvedClassInfo(parameterizedTypes[j]); if (!pci.isRegistered()) { @@ -172,7 +172,7 @@ public class JPF_java_lang_reflect_Method extends NativePeer { return paramTypeRef; } - private static int getTypeVariableImplObject(MJIEnv env, int objRef, MethodInfo mi, String parameterizedType) { + private static int getTypeVariableImplObject(MJIEnv env, int objRef, String parameterizedType) { ClassLoaderInfo cli = env.getSystemClassLoaderInfo(); ClassInfo ci = cli.getResolvedClassInfo("sun.reflect.generics.reflectiveObjects.TypeVariableImpl"); -- 2.34.1