Fixing a new bug: Considering parameters with Type and Type array, e.g., T and T[].
[jpf-core.git] / src / main / gov / nasa / jpf / vm / Types.java
index 948b42e512013b1b7cd88d2a0b002252e59dd8c3..30efa1fe872d11b15957bf79763e0bde5526f8ef 100644 (file)
@@ -912,6 +912,13 @@ public class Types {
       return getTypeName(signature.substring(1)) + "[]";
     }
 
+    // If it does not contain '<' and '>' then it is
+    // a Type signature, e.g., T, U, etc.
+    if (Types.isParameterWithType(signature)) {
+      // Clean the ';' character first and return the Type
+      return Types.getTypeParameter(signature.replace(";", ""));
+    }
+
     int len1 = len-1;
     if (signature.charAt(len1) == ';') {
       // TODO: Fix for Groovy's model-checking
@@ -1105,15 +1112,22 @@ public class Types {
       return 1 + getTypeLength(signature, idx + 1);
 
     case 'L':
-
+    default:
       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;
+      String currParam = signature.substring(idx,semicolon);
+      int genericStart = currParam.indexOf('<');
+      if (genericStart != -1) {
+        if (currParam.charAt(genericStart + 1) == '*') {
+          // Need to offset with idx to anticipate for array types (idx is incremented for array types)
+          semicolon = genericStart + idx + 3;
+        } else {
+          int generic = signature.indexOf('>', semicolon);
+          if (generic != -1) {
+            // Advance one character past the ';'
+            semicolon = generic + 1;
+          }
         }
       }
 
@@ -1125,7 +1139,7 @@ public class Types {
       return semicolon - idx + 1;
     }
 
-    throw new JPFException("invalid type signature");
+    //throw new JPFException("invalid type signature");
   }
 
   /**
@@ -1204,7 +1218,6 @@ public class Types {
     return arrTypeVarNames;
   }
 
-  // TODO: Fix for Groovy's model-checking
   public static String[] getParameterizedTypes(String signature) {
     int pos = signature.indexOf('<', 0);
     if (pos == -1)
@@ -1215,7 +1228,7 @@ public class Types {
       String typeVarName = "";
       int comma = signature.indexOf(',', pos);
       if (comma == -1) {
-        int closing = signature.indexOf('>', pos);
+        int closing = signature.lastIndexOf('>', signature.length());
         typeVarName = signature.substring(pos + 1, closing);
         pos = signature.length();
       } else {
@@ -1239,6 +1252,14 @@ public class Types {
       return signature.substring(0, opening);
   }
 
+  public static String getArrayClassName(String signature) {
+    int opening = signature.indexOf('[');
+    if (opening == -1)
+      return signature;
+    else
+      return signature.substring(0, opening);
+  }
+
   public static String getOwnerClassName(String signature) {
     int marker = signature.indexOf('$');
     if (marker == -1)
@@ -1254,22 +1275,75 @@ public class Types {
     return (opening != -1);
   }
 
+  public static boolean isParameterizedType(String signature) {
+    return Types.isGenericSignature(signature);
+  }
+
+  public static boolean isArraySignature(String signature) {
+    if (signature == null || signature.equals(""))
+      return false;
+    int opening = signature.indexOf('[');
+    return (opening != -1);
+  }
+
   public static boolean isTypeParameter(String parameterizedType, String signature) {
     if (signature == null || signature.equals(""))
       return false;
+    // The comparison has to be done without the "[]" part if it is an array
+    if (Types.isArraySignature(parameterizedType)) {
+      parameterizedType = Types.getArrayClassName(parameterizedType);
+    }
     String typeParamSig = parameterizedType.concat(":");
     return signature.contains(typeParamSig);
   }
 
   public static boolean isWildcardType(String signature) {
-    return (signature.startsWith("+L") || signature.equals("*"));
+    return (signature.startsWith("+L") ||
+            signature.startsWith("-L") ||
+            signature.startsWith("+")  ||
+            signature.startsWith("-")  ||
+            signature.equals("*"));
   }
 
   public static String getWildcardType(String signature) {
     if (signature.equals("*")) {
       return "java.lang.Object";
     }
-    return signature.replace("+L", "");
+    return signature.replaceAll("\\+L|-L", "");
+  }
+
+  public static boolean isParameterWithType(String signature) {
+    // Does not contain a class name
+    if (!signature.contains(".") && !signature.contains("/")) {
+      return true;
+    }
+    return false;
+  }
+
+  public static String getTypeParameter(String signature) {
+    if (signature == null || signature.equals(""))
+      return signature;
+
+    if (signature.equals("*")) {
+      return signature;
+    }
+
+    String cleanSig = signature.replaceAll("\\+|-", "");
+    if (cleanSig.length()%2 != 0) {
+      // This is probably a class, e.g., +java.lang.Class
+      return signature;
+    }
+
+    // Check if this is not a class name, e.g., +java.lang.Class
+    if (cleanSig.contains(".")) {
+      return signature;
+    }
+
+    // Just return the second half of the signature to get the Type parameter
+    int halfPos = cleanSig.length()/2;
+    //String firstHalf = cleanSig.substring(0, halfPos);
+    String secondHalf = cleanSig.substring(halfPos, cleanSig.length());
+    return secondHalf;
   }
   // TODO: Fix for Groovy's model-checking
 }