1 package org.softevo.jdynpur.eval; 2 3 import java.io.BufferedReader; 4 import java.io.File; 5 import java.io.FileInputStream; 6 import java.io.IOException; 7 import java.io.InputStreamReader; 8 import java.util.HashMap; 9 import java.util.HashSet; 10 11 public class PurityKitResultFileParser { 12 13 14 public static HashMap<String, HashMap<ExtendedMethodIdentifier,ExtendedMethodIdentifier>> parseResultFile(File file) throws IOException { 15 BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file))); 16 HashMap<String, HashMap<ExtendedMethodIdentifier,ExtendedMethodIdentifier>> result = new HashMap<String, HashMap<ExtendedMethodIdentifier,ExtendedMethodIdentifier>>(); 17 String currentLine; 18 int state = 0; 19 String className = null, methodName = null, purity = null; 20 boolean modifiesThis = false; 21 do { 22 currentLine = reader.readLine(); 23 if (currentLine != null) { 24 if (state == 0) { 25 if (currentLine.trim().equals("USER CLASSES")) { 26 state = 1; 27 } 28 } else if (state == 1) { 29 if (currentLine.trim().equals("MUTATION STATISTICS:")) { 30 break; 31 } else if (currentLine.trim().length() > 0) { 32 className = currentLine.substring(0, currentLine.indexOf(' ')).replace('.', '/'); 33 state = 2; 34 } 35 } else if (state == 2) { 36 modifiesThis = false; 37 if (currentLine.trim().equals("}")) { 38 className = null; 39 methodName = null; 40 purity = null; 41 state = 1; 42 } else { 43 methodName = currentLine; 44 state = 3; 45 } 46 } else if (state == 3) { 47 purity = currentLine; 48 state = 4; 49 } else if (state == 4) { 50 if (currentLine.trim().length() == 0) { 51 ExtendedMethodIdentifier identifier = parseMethodInformation(methodName, className, purity, modifiesThis); 52 HashMap<ExtendedMethodIdentifier,ExtendedMethodIdentifier> identifiers = result.get(className); 53 if (identifiers == null) { 54 identifiers = new HashMap<ExtendedMethodIdentifier,ExtendedMethodIdentifier>(); 55 result.put(className, identifiers); 56 } 57 identifiers.put(identifier, identifier); 58 state = 2; 59 } else if (currentLine.indexOf("\"this\":") != -1) { 60 modifiesThis = true; 61 } 62 } 63 } 64 } while (currentLine != null); 65 reader.close(); 66 return result; 67 } 68 69 private static ExtendedMethodIdentifier parseMethodInformation(String methodInformation, String className, String purity, boolean modifiesThis) { 70 boolean isStatic = methodInformation.indexOf("static") != -1; 71 String[] tokens = methodInformation.split(" "); 72 int i = 0; 73 int methodNameIndex = -1; 74 for (String token : tokens) { 75 if(token.indexOf("(") != -1) { 76 methodNameIndex = i; 77 break; 78 } 79 i++; 80 } 81 String returnType; 82 if (tokens[methodNameIndex - 1].trim().equals("[ro]")) { 83 returnType = tokens[methodNameIndex - 2]; 84 } else { 85 returnType = tokens[methodNameIndex - 1]; 86 } 87 String methodName = tokens[methodNameIndex].substring(0, tokens[methodNameIndex].indexOf('(')).replace('.', '/'); 88 if (methodName.equals(className)) { 89 methodName = "<init>"; 90 } 91 String parameterString = methodInformation.substring(methodInformation.indexOf('(') + 1, methodInformation.indexOf(')')); 92 String[] parameters = parameterString.split(","); 93 StringBuffer signatureBuffer = new StringBuffer(); 94 signatureBuffer.append("("); 95 HashSet<Integer> immutableParameters = new HashSet<Integer>(); 96 HashSet<Integer> mutableParameters = new HashSet<Integer>(); 97 if (!isStatic) { 98 if (!modifiesThis) { 99 immutableParameters.add(0); 100 } else { 101 mutableParameters.add(0); 102 } 103 i = 1; 104 } else { 105 i = 0; 106 } 107 for (String parameter : parameters) { 108 parameter = parameter.trim(); 109 if (parameter.trim().length() != 0) { 110 String[] parameterTokens = parameter.split(" "); 111 boolean isImmutable = false; 112 String type; 113 if (parameterTokens.length == 3 && parameterTokens[0].equals("[ro]")) { 114 isImmutable = true; 115 type = parameterTokens[1]; 116 } else { 117 type = parameterTokens[0]; 118 } 119 String signatureReturnType = getType(type); 120 if (signatureReturnType.startsWith("L") || signatureReturnType.startsWith("[")) { 121 if (isImmutable) { 122 immutableParameters.add(i); 123 } else { 124 mutableParameters.add(i); 125 } 126 } 127 signatureBuffer.append(signatureReturnType); 128 } 129 i++; 130 } 131 signatureBuffer.append(")"); 132 signatureBuffer.append(getType(returnType)); 133 ExtendedMethodIdentifier identifier = new ExtendedMethodIdentifier(className, methodName, signatureBuffer.toString(), 134 purity, immutableParameters, mutableParameters); 135 identifier.setStatic(isStatic); 136 return identifier; 137 } 138 139 private static String getType(String type) { 140 if (type.equals("void")) { 141 return "V"; 142 } else { 143 int dimensions = 0; 144 while (type.endsWith("[]")) { 145 type = type.substring(0, type.length() - 2); 146 dimensions++; 147 } 148 StringBuffer result = new StringBuffer(); 149 for(int i = 0; i < dimensions; i++) { 150 result.append("["); 151 } 152 if (type.equals("int")) { 153 result.append("I"); 154 } else if (type.equals("short")) { 155 result.append("S"); 156 } else if (type.equals("long")) { 157 result.append("J"); 158 } else if (type.equals("double")) { 159 result.append("D"); 160 } else if (type.equals("float")) { 161 result.append("F"); 162 } else if (type.equals("char")) { 163 result.append("C"); 164 } else if (type.equals("byte")) { 165 result.append("B"); 166 } else if (type.equals("boolean")) { 167 result.append("Z"); 168 } else { 169 result.append("L" + type.replace('.', '/') + ";"); 170 } 171 return result.toString(); 172 } 173 } 174 175 public static void main(String[] args) throws IOException { 176 parseResultFile(new File("/Users/dallmeier/tmp/aj.out")); 177 } 178 }