Mercurial > hg > graal-compiler
comparison graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethod.java @ 16755:bd28da642eea
Truffle-DSL: Several new features implemented:
Implementation of a new code generation layout which shares code between generated nodes.
Declaration order of specializations is now used as specialization order.
Specializations do no longer perform fallthrough on respecialization, they now always respecialize from the first specialization.
Implemented support for contains relations between specializations.
Improved reachability error messages.
Preliminary support for @Implies.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Mon, 11 Aug 2014 15:53:05 +0200 |
parents | 856c2c294f84 |
children |
comparison
equal
deleted
inserted
replaced
16754:55fd5be68a52 | 16755:bd28da642eea |
---|---|
34 /** | 34 /** |
35 * Note: this class has a natural ordering that is inconsistent with equals. | 35 * Note: this class has a natural ordering that is inconsistent with equals. |
36 */ | 36 */ |
37 public class TemplateMethod extends MessageContainer implements Comparable<TemplateMethod> { | 37 public class TemplateMethod extends MessageContainer implements Comparable<TemplateMethod> { |
38 | 38 |
39 public static final int NO_NATURAL_ORDER = -1; | |
40 | |
39 private String id; | 41 private String id; |
40 private final Template template; | 42 private final Template template; |
43 private final int naturalOrder; | |
41 private final MethodSpec specification; | 44 private final MethodSpec specification; |
42 private final ExecutableElement method; | 45 private final ExecutableElement method; |
43 private final AnnotationMirror markerAnnotation; | 46 private final AnnotationMirror markerAnnotation; |
44 private ActualParameter returnType; | 47 private ActualParameter returnType; |
45 private List<ActualParameter> parameters; | 48 private List<ActualParameter> parameters; |
46 | 49 |
47 public TemplateMethod(String id, Template template, MethodSpec specification, ExecutableElement method, AnnotationMirror markerAnnotation, ActualParameter returnType, | 50 public TemplateMethod(String id, int naturalOrder, Template template, MethodSpec specification, ExecutableElement method, AnnotationMirror markerAnnotation, ActualParameter returnType, |
48 List<ActualParameter> parameters) { | 51 List<ActualParameter> parameters) { |
49 this.template = template; | 52 this.template = template; |
50 this.specification = specification; | 53 this.specification = specification; |
54 this.naturalOrder = naturalOrder; | |
51 this.method = method; | 55 this.method = method; |
52 this.markerAnnotation = markerAnnotation; | 56 this.markerAnnotation = markerAnnotation; |
53 this.returnType = returnType; | 57 this.returnType = returnType; |
54 this.parameters = new ArrayList<>(); | 58 this.parameters = new ArrayList<>(); |
55 for (ActualParameter param : parameters) { | 59 for (ActualParameter param : parameters) { |
58 newParam.setMethod(this); | 62 newParam.setMethod(this); |
59 } | 63 } |
60 this.id = id; | 64 this.id = id; |
61 } | 65 } |
62 | 66 |
67 public int getNaturalOrder() { | |
68 return naturalOrder; | |
69 } | |
70 | |
63 public TemplateMethod(TemplateMethod method) { | 71 public TemplateMethod(TemplateMethod method) { |
64 this(method.id, method.template, method.specification, method.method, method.markerAnnotation, method.returnType, method.parameters); | 72 this(method.id, method.naturalOrder, method.template, method.specification, method.method, method.markerAnnotation, method.returnType, method.parameters); |
65 getMessages().addAll(method.getMessages()); | 73 getMessages().addAll(method.getMessages()); |
66 } | 74 } |
67 | 75 |
68 public TemplateMethod(TemplateMethod method, ExecutableElement executable) { | 76 public TemplateMethod(TemplateMethod method, ExecutableElement executable) { |
69 this(method.id, method.template, method.specification, executable, method.markerAnnotation, method.returnType, method.parameters); | 77 this(method.id, method.naturalOrder, method.template, method.specification, executable, method.markerAnnotation, method.returnType, method.parameters); |
70 getMessages().addAll(method.getMessages()); | 78 getMessages().addAll(method.getMessages()); |
71 } | 79 } |
72 | 80 |
73 public void setParameters(List<ActualParameter> parameters) { | 81 public void setParameters(List<ActualParameter> parameters) { |
74 this.parameters = parameters; | 82 this.parameters = parameters; |
172 } | 180 } |
173 allParameters.addAll(getParameters()); | 181 allParameters.addAll(getParameters()); |
174 return Collections.unmodifiableList(allParameters); | 182 return Collections.unmodifiableList(allParameters); |
175 } | 183 } |
176 | 184 |
177 public boolean canBeAccessedByInstanceOf(ProcessorContext context, TypeMirror type) { | 185 public boolean canBeAccessedByInstanceOf(TypeMirror type) { |
178 TypeMirror methodType = Utils.findNearestEnclosingType(getMethod()).asType(); | 186 TypeMirror methodType = Utils.findNearestEnclosingType(getMethod()).asType(); |
179 return Utils.isAssignable(context, type, methodType) || Utils.isAssignable(context, methodType, type); | 187 return Utils.isAssignable(type, methodType) || Utils.isAssignable(methodType, type); |
180 } | 188 } |
181 | 189 |
182 public ExecutableElement getMethod() { | 190 public ExecutableElement getMethod() { |
183 return method; | 191 return method; |
184 } | 192 } |
304 throw new IllegalStateException("Cannot compare two methods with different type systems."); | 312 throw new IllegalStateException("Cannot compare two methods with different type systems."); |
305 } | 313 } |
306 | 314 |
307 List<TypeMirror> signature1 = getSignatureTypes(this); | 315 List<TypeMirror> signature1 = getSignatureTypes(this); |
308 List<TypeMirror> signature2 = getSignatureTypes(compareMethod); | 316 List<TypeMirror> signature2 = getSignatureTypes(compareMethod); |
309 if (signature1.size() != signature2.size()) { | |
310 return signature2.size() - signature1.size(); | |
311 } | |
312 | 317 |
313 int result = 0; | 318 int result = 0; |
314 for (int i = 1; i < signature1.size(); i++) { | 319 for (int i = 0; i < Math.max(signature1.size(), signature2.size()); i++) { |
315 TypeMirror t1 = signature1.get(i); | 320 TypeMirror t1 = i < signature1.size() ? signature1.get(i) : null; |
316 TypeMirror t2 = signature2.get(i); | 321 TypeMirror t2 = i < signature2.size() ? signature2.get(i) : null; |
317 | 322 result = compareParameter(typeSystem, t1, t2); |
318 int typeResult = compareParameter(typeSystem, t1, t2); | 323 if (result != 0) { |
319 if (result == 0) { | 324 break; |
320 result = typeResult; | 325 } |
321 } else if (typeResult != 0 && Math.signum(result) != Math.signum(typeResult)) { | |
322 // We cannot define an order. | |
323 return 0; | |
324 } | |
325 } | |
326 if (result == 0 && signature1.size() > 0) { | |
327 result = compareParameter(typeSystem, signature1.get(0), signature2.get(0)); | |
328 } | 326 } |
329 | 327 |
330 return result; | 328 return result; |
331 } | 329 } |
332 | 330 |
333 private static int compareParameter(TypeSystemData data, TypeMirror signature1, TypeMirror signature2) { | 331 protected static int compareParameter(TypeSystemData data, TypeMirror signature1, TypeMirror signature2) { |
332 if (signature1 == null) { | |
333 return 1; | |
334 } else if (signature2 == null) { | |
335 return -1; | |
336 } | |
337 | |
334 if (Utils.typeEquals(signature1, signature2)) { | 338 if (Utils.typeEquals(signature1, signature2)) { |
335 return 0; | 339 return 0; |
336 } | 340 } |
337 | 341 |
338 int index1 = data.findType(signature1); | 342 int index1 = data.findType(signature1); |
339 int index2 = data.findType(signature2); | 343 int index2 = data.findType(signature2); |
340 if (index1 != -1 && index2 != -1) { | 344 if (index1 != -1 && index2 != -1) { |
341 return index1 - index2; | 345 return index1 - index2; |
342 } | 346 } |
343 | 347 |
348 // TODO this version if subclass of should be improved. | |
344 if (signature1.getKind() == TypeKind.DECLARED && signature2.getKind() == TypeKind.DECLARED) { | 349 if (signature1.getKind() == TypeKind.DECLARED && signature2.getKind() == TypeKind.DECLARED) { |
345 TypeElement element1 = Utils.fromTypeMirror(signature1); | 350 TypeElement element1 = Utils.fromTypeMirror(signature1); |
346 TypeElement element2 = Utils.fromTypeMirror(signature2); | 351 TypeElement element2 = Utils.fromTypeMirror(signature2); |
347 | 352 |
348 if (Utils.getDirectSuperTypes(element1).contains(element2)) { | 353 if (Utils.getDirectSuperTypes(element1).contains(element2)) { |
354 return Utils.getSimpleName(signature1).compareTo(Utils.getSimpleName(signature2)); | 359 return Utils.getSimpleName(signature1).compareTo(Utils.getSimpleName(signature2)); |
355 } | 360 } |
356 | 361 |
357 public static List<TypeMirror> getSignatureTypes(TemplateMethod method) { | 362 public static List<TypeMirror> getSignatureTypes(TemplateMethod method) { |
358 List<TypeMirror> types = new ArrayList<>(); | 363 List<TypeMirror> types = new ArrayList<>(); |
359 types.add(method.getReturnType().getType()); | |
360 for (ActualParameter param : method.getSignatureParameters()) { | 364 for (ActualParameter param : method.getSignatureParameters()) { |
361 types.add(param.getType()); | 365 types.add(param.getType()); |
362 } | 366 } |
363 return types; | 367 return types; |
364 } | 368 } |