From a3fa2183399d94577d22734074e0e71bfb571801 Mon Sep 17 00:00:00 2001 From: Rahmadi Trimananda Date: Thu, 20 Jun 2019 17:52:49 -0700 Subject: [PATCH] Fixing the method getGenericParameterTypes to include parameterized object such as Class. --- examples/Empty.groovy | 2 +- examples/Reflection.java | 13 +++++-- src/main/gov/nasa/jpf/vm/MethodInfo.java | 4 +- src/main/gov/nasa/jpf/vm/Types.java | 9 ++++- .../gov/nasa/jpf/vm/JPF_java_lang_Class.java | 4 +- .../jpf/vm/JPF_java_lang_reflect_Method.java | 38 +++++++++++++++---- 6 files changed, 53 insertions(+), 17 deletions(-) diff --git a/examples/Empty.groovy b/examples/Empty.groovy index 93c4cc6..55d02fe 100644 --- a/examples/Empty.groovy +++ b/examples/Empty.groovy @@ -22,7 +22,7 @@ class Empty { //Empty emp = new Empty(); //int result = emp.installed(); - println result; + //println result; //println "Test" } } diff --git a/examples/Reflection.java b/examples/Reflection.java index f2bff8a..538bcd1 100644 --- a/examples/Reflection.java +++ b/examples/Reflection.java @@ -43,7 +43,14 @@ public class Reflection { public static void main(String[] args) { Method[] methods = SampleClass.class.getMethods(); - Type[] parameters = methods[3].getGenericParameterTypes(); + // Method[] methods = Class.class.getMethods(); + Method method = null; + for(Method meth : methods) { + if (meth.getName().equals("setSampleField")) { + method = meth; + } + } + Type[] parameters = method.getGenericParameterTypes(); //Type[] parameters = methods[0].getGenericParameterTypes(); for (int i = 0; i < parameters.length; i++) { System.out.println(parameters[i]); @@ -55,7 +62,7 @@ public class Reflection { } System.out.println();*/ - TypeVariable[] typeParameters = Generic.class.getTypeParameters(); + /*TypeVariable[] typeParameters = Generic.class.getTypeParameters(); //TypeVariable[] typeParameters = SampleClass.class.getTypeParameters(); for(TypeVariable typeVar: typeParameters){ System.out.println(typeVar); @@ -70,7 +77,7 @@ public class Reflection { System.out.println(); Type returnType = methods[0].getGenericReturnType(); System.out.println(returnType); - + */ } } diff --git a/src/main/gov/nasa/jpf/vm/MethodInfo.java b/src/main/gov/nasa/jpf/vm/MethodInfo.java index 7a1d48d..4176f68 100644 --- a/src/main/gov/nasa/jpf/vm/MethodInfo.java +++ b/src/main/gov/nasa/jpf/vm/MethodInfo.java @@ -509,7 +509,9 @@ public class MethodInfo extends InfoObject implements GenericSignatureHolder { // TODO: in the class file. if (genericSignature == null || genericSignature.equals("") || genericSignature.contains("<*>")) return getArgumentTypeNames(); - return Types.getArgumentTypeNames(genericSignature); + // We need to first find the start of the method parameters in the signature + String methodParameters = genericSignature.substring(genericSignature.indexOf('(')); + return Types.getArgumentTypeNames(methodParameters); } public int getArgumentsSize () { diff --git a/src/main/gov/nasa/jpf/vm/Types.java b/src/main/gov/nasa/jpf/vm/Types.java index 16ee295..6c34925 100644 --- a/src/main/gov/nasa/jpf/vm/Types.java +++ b/src/main/gov/nasa/jpf/vm/Types.java @@ -1205,7 +1205,7 @@ public class Types { } // TODO: Fix for Groovy's model-checking - public static String[] getParameterizedTypesFromArgumentTypeNames(String signature) { + public static String[] getParameterizedTypes(String signature) { int pos = signature.indexOf('<', 0); if (pos == -1) return new String[0]; @@ -1251,5 +1251,12 @@ public class Types { int opening = signature.indexOf('<'); return (opening != -1); } + + public static boolean isTypeParameter(String parameterizedType, String signature) { + if (signature == null || signature.equals("")) + return false; + String typeParamSig = parameterizedType.concat(":"); + return signature.contains(typeParamSig); + } // TODO: Fix for Groovy's model-checking } 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 8ace896..10d63c7 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 @@ -34,9 +34,7 @@ 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 // classes are initialized (they already might be) 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 5b91441..48aff58 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 @@ -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, mi, 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, MethodInfo mi, 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()) { @@ -201,7 +223,7 @@ public class JPF_java_lang_reflect_Method extends NativePeer { int retRef; if (Types.isGenericSignature(mi.getGenericReturnTypeName())) { - retRef = getParameterizedTypeImplObj(mi.getGenericReturnTypeName(), env); + retRef = getParameterizedTypeImplObj(mi.getGenericReturnTypeName(), env, objRef, mi); } else { ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(mi.getReturnTypeName()); if (!ci.isRegistered()) { -- 2.34.1