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 }