comparison graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethodParser.java @ 7679:5f3cba05c2fa

Cleanup and improved error messages.
author Christian Humer <christian.humer@gmail.com>
date Thu, 31 Jan 2013 16:21:46 +0100
parents 5e3d1a68664e
children c17ee8823d72
comparison
equal deleted inserted replaced
7573:17b6a63fe7c2 7679:5f3cba05c2fa
118 MethodSpec methodSpecification = createSpecification(method, annotation); 118 MethodSpec methodSpecification = createSpecification(method, annotation);
119 if (methodSpecification == null) { 119 if (methodSpecification == null) {
120 return null; 120 return null;
121 } 121 }
122 122
123 List<TypeDef> typeDefs = createTypeDefinitions(methodSpecification.getReturnType(), methodSpecification.getParameters());
124
123 ParameterSpec returnTypeSpec = methodSpecification.getReturnType(); 125 ParameterSpec returnTypeSpec = methodSpecification.getReturnType();
124 List<ParameterSpec> parameterSpecs = new ArrayList<>(); 126 List<ParameterSpec> parameterSpecs = new ArrayList<>();
125 parameterSpecs.addAll(methodSpecification.getParameters()); 127 parameterSpecs.addAll(methodSpecification.getParameters());
126 128
127 ActualParameter returnTypeMirror = resolveTypeMirror(returnTypeSpec, method.getReturnType(), template); 129 ActualParameter returnTypeMirror = resolveTypeMirror(returnTypeSpec, method.getReturnType(), template);
128 if (returnTypeMirror == null) { 130 if (returnTypeMirror == null) {
129 if (isEmitErrors()) { 131 if (isEmitErrors()) {
130 String expectedReturnType = createTypeSignature(returnTypeSpec, true); 132 String expectedReturnType = createTypeSignature(returnTypeSpec, typeDefs, true);
131 String actualReturnType = Utils.getSimpleName(method.getReturnType()); 133 String actualReturnType = Utils.getSimpleName(method.getReturnType());
132 134
133 String message = String.format("The provided return type \"%s\" does not match expected return type \"%s\".\nExpected signature: \n %s", actualReturnType, expectedReturnType, 135 String message = String.format("The provided return type \"%s\" does not match expected return type \"%s\".\nExpected signature: \n %s", actualReturnType, expectedReturnType,
134 createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs)); 136 createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs, typeDefs));
135 137
136 context.getLog().error(method, annotation, message); 138 context.getLog().error(method, annotation, message);
137 } 139 }
138 return null; 140 return null;
139 } 141 }
158 specification = null; 160 specification = null;
159 continue; 161 continue;
160 } else if (!specification.isOptional()) { 162 } else if (!specification.isOptional()) {
161 if (isEmitErrors()) { 163 if (isEmitErrors()) {
162 // non option type specification found -> argument missing 164 // non option type specification found -> argument missing
163 String expectedType = createTypeSignature(specification, false); 165 String expectedType = createTypeSignature(specification, typeDefs, false);
164 166
165 String message = String.format("Missing argument \"%s\".\nExpected signature: \n %s", expectedType, 167 String message = String.format("Missing argument \"%s\".\nExpected signature: \n %s", expectedType,
166 createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs)); 168 createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs, typeDefs));
167 169
168 context.getLog().error(method, message); 170 context.getLog().error(method, message);
169 } 171 }
170 return null; 172 return null;
171 } else { 173 } else {
182 specification = null; 184 specification = null;
183 continue; 185 continue;
184 } 186 }
185 187
186 if (isEmitErrors()) { 188 if (isEmitErrors()) {
187 String expectedReturnType = createTypeSignature(specification, false); 189 String expectedReturnType = createTypeSignature(specification, typeDefs, false);
188 String actualReturnType = Utils.getSimpleName(parameter.asType()) + " " + parameter.getSimpleName(); 190 String actualReturnType = Utils.getSimpleName(parameter.asType()) + " " + parameter.getSimpleName();
189 191
190 String message = String.format("The provided argument type \"%s\" does not match expected type \"%s\".\nExpected signature: \n %s", actualReturnType, expectedReturnType, 192 String message = String.format("The provided argument type \"%s\" does not match expected type \"%s\".\nExpected signature: \n %s", actualReturnType, expectedReturnType,
191 createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs)); 193 createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs, typeDefs));
192 194
193 context.getLog().error(parameter, message); 195 context.getLog().error(parameter, message);
194 } 196 }
195 return null; 197 return null;
196 } 198 }
206 if (variableIterator.hasNext()) { 208 if (variableIterator.hasNext()) {
207 parameter = variableIterator.next(); 209 parameter = variableIterator.next();
208 if (isEmitErrors()) { 210 if (isEmitErrors()) {
209 String actualReturnType = Utils.getSimpleName(parameter.asType()) + " " + parameter.getSimpleName(); 211 String actualReturnType = Utils.getSimpleName(parameter.asType()) + " " + parameter.getSimpleName();
210 String message = String.format("No argument expected but found \"%s\".\nExpected signature: \n %s", actualReturnType, 212 String message = String.format("No argument expected but found \"%s\".\nExpected signature: \n %s", actualReturnType,
211 createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs)); 213 createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs, typeDefs));
212 214
213 context.getLog().error(parameter, message); 215 context.getLog().error(parameter, message);
214 } 216 }
215 return null; 217 return null;
216 } 218 }
229 return null; 231 return null;
230 } 232 }
231 return new ActualParameter(specification, resolvedType); 233 return new ActualParameter(specification, resolvedType);
232 } 234 }
233 235
234 public static String createExpectedSignature(String methodName, ParameterSpec returnType, List<? extends ParameterSpec> parameters) { 236 protected static List<TypeDef> createTypeDefinitions(ParameterSpec returnType, List<? extends ParameterSpec> parameters) {
237 List<TypeDef> typeDefs = new ArrayList<>();
238
239 TypeMirror[] types = returnType.getAllowedTypes();
240 List<ParameterSpec> allParams = new ArrayList<>();
241 allParams.add(returnType);
242 allParams.addAll(parameters);
243
244 int defIndex = 0;
245 for (ParameterSpec spec : allParams) {
246 TypeMirror[] allowedTypes = spec.getAllowedTypes();
247 if (types != null && allowedTypes.length > 1) {
248 TypeDef foundDef = null;
249 for (TypeDef def : typeDefs) {
250 if (Arrays.equals(spec.getAllowedTypes(), def.getTypes())) {
251 foundDef = def;
252 break;
253 }
254 }
255 if (foundDef == null) {
256 foundDef = new TypeDef(types, "Types" + defIndex);
257 typeDefs.add(foundDef);
258 defIndex++;
259 }
260
261 foundDef.getParameters().add(spec);
262 }
263 }
264
265 return typeDefs;
266 }
267
268 protected static class TypeDef {
269
270 private final TypeMirror[] types;
271 private final String name;
272 private final List<ParameterSpec> parameters = new ArrayList<>();
273
274 public TypeDef(TypeMirror[] types, String name) {
275 this.types = types;
276 this.name = name;
277 }
278
279 public List<ParameterSpec> getParameters() {
280 return parameters;
281 }
282
283 public TypeMirror[] getTypes() {
284 return types;
285 }
286
287 public String getName() {
288 return name;
289 }
290 }
291
292 public static String createExpectedSignature(String methodName, ParameterSpec returnType, List<? extends ParameterSpec> parameters, List<TypeDef> typeDefs) {
235 StringBuilder b = new StringBuilder(); 293 StringBuilder b = new StringBuilder();
236 294
237 b.append(" "); 295 b.append(" ");
238 b.append(createTypeSignature(returnType, true)); 296 b.append(createTypeSignature(returnType, typeDefs, true));
239 297
240 b.append(" "); 298 b.append(" ");
241 b.append(methodName); 299 b.append(methodName);
242 b.append("("); 300 b.append("(");
243 301
248 } 306 }
249 if (specification.getCardinality() == Cardinality.MULTIPLE) { 307 if (specification.getCardinality() == Cardinality.MULTIPLE) {
250 b.append("{"); 308 b.append("{");
251 } 309 }
252 310
253 b.append(createTypeSignature(specification, false)); 311 b.append(createTypeSignature(specification, typeDefs, false));
254 312
255 if (specification.isOptional()) { 313 if (specification.isOptional()) {
256 b.append("]"); 314 b.append("]");
257 } 315 }
258 316
266 324
267 } 325 }
268 326
269 b.append(")"); 327 b.append(")");
270 328
271 TypeMirror[] types = null; 329 if (!typeDefs.isEmpty()) {
272 330 b.append("\n\n");
273 // TODO allowed types may differ so different <Any> must be generated. 331
274 if (returnType.getAllowedTypes().length > 1) { 332 String lineSep = "";
275 types = returnType.getAllowedTypes(); 333 for (TypeDef def : typeDefs) {
276 } 334 b.append(lineSep);
277 for (ParameterSpec param : parameters) { 335 b.append(" <").append(def.getName()).append(">");
278 if (param.getAllowedTypes().length > 1) { 336 b.append(" = {");
279 types = param.getAllowedTypes(); 337 String separator = "";
280 } 338 for (TypeMirror type : def.getTypes()) {
281 } 339 b.append(separator).append(Utils.getSimpleName(type));
282 if (types != null) { 340 separator = ", ";
283 b.append("\n\n "); 341 }
284 b.append("<Any> = {"); 342 b.append("}");
285 String separator = ""; 343 lineSep = "\n";
286 for (TypeMirror type : types) { 344
287 b.append(separator).append(Utils.getSimpleName(type)); 345 }
288 separator = ", ";
289 }
290 b.append("}");
291 } 346 }
292 return b.toString(); 347 return b.toString();
293 } 348 }
294 349
295 private static String createTypeSignature(ParameterSpec spec, boolean typeOnly) { 350 private static String createTypeSignature(ParameterSpec spec, List<TypeDef> typeDefs, boolean typeOnly) {
296 StringBuilder builder = new StringBuilder(); 351 StringBuilder builder = new StringBuilder();
297 if (spec.getAllowedTypes().length > 1) { 352 if (spec.getAllowedTypes().length > 1) {
298 builder.append("<Any>"); 353 TypeDef foundTypeDef = null;
354 for (TypeDef typeDef : typeDefs) {
355 if (typeDef.getParameters().contains(spec)) {
356 foundTypeDef = typeDef;
357 break;
358 }
359 }
360 if (foundTypeDef != null) {
361 builder.append("<" + foundTypeDef.getName() + ">");
362 }
299 } else if (spec.getAllowedTypes().length == 1) { 363 } else if (spec.getAllowedTypes().length == 1) {
300 builder.append(Utils.getSimpleName(spec.getAllowedTypes()[0])); 364 builder.append(Utils.getSimpleName(spec.getAllowedTypes()[0]));
301 } else { 365 } else {
302 builder.append("void"); 366 builder.append("void");
303 } 367 }