comparison graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java @ 7530:5e3d1a68664e

applied mx eclipseformat to all Java files
author Doug Simon <doug.simon@oracle.com>
date Wed, 23 Jan 2013 16:34:57 +0100
parents 40133ce026c6
children 5f3cba05c2fa
comparison
equal deleted inserted replaced
7529:4a11124a3563 7530:5e3d1a68664e
37 import com.oracle.truffle.codegen.processor.node.NodeFieldData.ExecutionKind; 37 import com.oracle.truffle.codegen.processor.node.NodeFieldData.ExecutionKind;
38 import com.oracle.truffle.codegen.processor.node.NodeFieldData.FieldKind; 38 import com.oracle.truffle.codegen.processor.node.NodeFieldData.FieldKind;
39 import com.oracle.truffle.codegen.processor.template.*; 39 import com.oracle.truffle.codegen.processor.template.*;
40 import com.oracle.truffle.codegen.processor.typesystem.*; 40 import com.oracle.truffle.codegen.processor.typesystem.*;
41 41
42 public class NodeParser extends TemplateParser<NodeData>{ 42 public class NodeParser extends TemplateParser<NodeData> {
43 43
44 public static final List<Class<? extends Annotation>> ANNOTATIONS = Arrays.asList( 44 public static final List<Class<? extends Annotation>> ANNOTATIONS = Arrays.asList(Generic.class, GuardCheck.class, TypeSystemReference.class, ShortCircuit.class, Specialization.class,
45 Generic.class, GuardCheck.class, TypeSystemReference.class, ShortCircuit.class, Specialization.class,
46 SpecializationGuard.class, SpecializationListener.class, SpecializationThrows.class); 45 SpecializationGuard.class, SpecializationListener.class, SpecializationThrows.class);
47 46
48 private static final boolean DEBUG = false; 47 private static final boolean DEBUG = false;
49 48
50 private Map<String, NodeData> parsedNodes; 49 private Map<String, NodeData> parsedNodes;
147 146
148 List<ExecutableTypeData> executableTypes = filterExecutableTypes(new ExecutableTypeMethodParser(context, nodeData).parse(elements)); 147 List<ExecutableTypeData> executableTypes = filterExecutableTypes(new ExecutableTypeMethodParser(context, nodeData).parse(elements));
149 148
150 nodeData.setExecutableTypes(executableTypes.toArray(new ExecutableTypeData[executableTypes.size()])); 149 nodeData.setExecutableTypes(executableTypes.toArray(new ExecutableTypeData[executableTypes.size()]));
151 150
152 parsedNodes.put(Utils.getQualifiedName(type), nodeData); // node fields will resolve node types, to avoid endless loops 151 parsedNodes.put(Utils.getQualifiedName(type), nodeData); // node fields will resolve node
152 // types, to avoid endless loops
153 153
154 NodeFieldData[] fields = parseFields(nodeData, elements, typeHierarchy); 154 NodeFieldData[] fields = parseFields(nodeData, elements, typeHierarchy);
155 if (fields == null) { 155 if (fields == null) {
156 return null; 156 return null;
157 } 157 }
158 nodeData.setFields(fields); 158 nodeData.setFields(fields);
159
160 159
161 List<SpecializationData> genericSpecializations = new GenericParser(context, nodeData).parse(elements); 160 List<SpecializationData> genericSpecializations = new GenericParser(context, nodeData).parse(elements);
162 List<GuardData> guards = new GuardParser(context, nodeData, nodeData.getTypeSystem()).parse(elements); 161 List<GuardData> guards = new GuardParser(context, nodeData, nodeData.getTypeSystem()).parse(elements);
163 nodeData.setGuards(guards.toArray(new GuardData[guards.size()])); 162 nodeData.setGuards(guards.toArray(new GuardData[guards.size()]));
164 163
165 SpecializationMethodParser specializationParser = new SpecializationMethodParser(context, nodeData); 164 SpecializationMethodParser specializationParser = new SpecializationMethodParser(context, nodeData);
166 List<SpecializationData> specializations = specializationParser.parse(elements); 165 List<SpecializationData> specializations = specializationParser.parse(elements);
167 List<ShortCircuitData> shortCircuits = new ShortCircuitParser(context, nodeData).parse(elements); 166 List<ShortCircuitData> shortCircuits = new ShortCircuitParser(context, nodeData).parse(elements);
168 List<TemplateMethod> listeners = new SpecializationListenerParser(context, nodeData).parse(elements); 167 List<TemplateMethod> listeners = new SpecializationListenerParser(context, nodeData).parse(elements);
169 168
170 if (specializations == null || genericSpecializations == null || shortCircuits == null || listeners == null || guards == null) { 169 if (specializations == null || genericSpecializations == null || shortCircuits == null || listeners == null || guards == null) {
171 return null; 170 return null;
172 } 171 }
173 172
174 SpecializationData genericSpecialization = null; 173 SpecializationData genericSpecialization = null;
175 if (genericSpecializations.size() > 1) { 174 if (genericSpecializations.size() > 1) {
185 log.error(originalType, "Need a @%s method.", Generic.class.getSimpleName()); 184 log.error(originalType, "Need a @%s method.", Generic.class.getSimpleName());
186 return null; 185 return null;
187 } 186 }
188 187
189 Collections.sort(specializations, new Comparator<SpecializationData>() { 188 Collections.sort(specializations, new Comparator<SpecializationData>() {
189
190 @Override 190 @Override
191 public int compare(SpecializationData o1, SpecializationData o2) { 191 public int compare(SpecializationData o1, SpecializationData o2) {
192 return compareSpecialization(typeSystem, o1, o2); 192 return compareSpecialization(typeSystem, o1, o2);
193 } 193 }
194 }); 194 });
195 195
196 List<SpecializationData> allSpecializations = new ArrayList<>(specializations); 196 List<SpecializationData> allSpecializations = new ArrayList<>(specializations);
197 if (genericSpecialization != null) { 197 if (genericSpecialization != null) {
198 allSpecializations.add(genericSpecialization); 198 allSpecializations.add(genericSpecialization);
199 CodeExecutableElement uninitializedMethod = new CodeExecutableElement(Utils.modifiers(Modifier.PUBLIC), context.getType(void.class), "doUninitialized"); 199 CodeExecutableElement uninitializedMethod = new CodeExecutableElement(Utils.modifiers(Modifier.PUBLIC), context.getType(void.class), "doUninitialized");
200 TemplateMethod uninializedMethod = new TemplateMethod(nodeData, genericSpecialization.getSpecification(), uninitializedMethod, 200 TemplateMethod uninializedMethod = new TemplateMethod(nodeData, genericSpecialization.getSpecification(), uninitializedMethod, genericSpecialization.getMarkerAnnotation(),
201 genericSpecialization.getMarkerAnnotation(), genericSpecialization.getReturnType(), genericSpecialization.getParameters()); 201 genericSpecialization.getReturnType(), genericSpecialization.getParameters());
202 allSpecializations.add(0, new SpecializationData(uninializedMethod, false, true)); 202 allSpecializations.add(0, new SpecializationData(uninializedMethod, false, true));
203 } 203 }
204 204
205 for (SpecializationData specialization : allSpecializations) { 205 for (SpecializationData specialization : allSpecializations) {
206 specialization.setNode(nodeData); 206 specialization.setNode(nodeData);
261 } 261 }
262 262
263 boolean valid = true; 263 boolean valid = true;
264 for (ExecutableElement unusedMethod : ElementFilter.methodsIn(unusedElements)) { 264 for (ExecutableElement unusedMethod : ElementFilter.methodsIn(unusedElements)) {
265 if (unusedMethod.getModifiers().contains(Modifier.ABSTRACT)) { 265 if (unusedMethod.getModifiers().contains(Modifier.ABSTRACT)) {
266 context.getLog().error(nodeData.getTemplateType(), "The type %s must implement the inherited abstract method %s.", Utils.getSimpleName(nodeData.getTemplateType()), Utils.getReadableSignature(unusedMethod)); 266 context.getLog().error(nodeData.getTemplateType(), "The type %s must implement the inherited abstract method %s.", Utils.getSimpleName(nodeData.getTemplateType()),
267 Utils.getReadableSignature(unusedMethod));
267 valid = false; 268 valid = false;
268 } 269 }
269 } 270 }
270 271
271 return valid; 272 return valid;
371 } else { 372 } else {
372 valid = false; 373 valid = false;
373 } 374 }
374 } 375 }
375 376
376 //TODO parse getters 377 // TODO parse getters
377 if (!valid) { 378 if (!valid) {
378 return null; 379 return null;
379 } 380 }
380 381
381 NodeFieldData[] fieldArray = fields.toArray(new NodeFieldData[fields.size()]); 382 NodeFieldData[] fieldArray = fields.toArray(new NodeFieldData[fields.size()]);
382 sortByExecutionOrder(fieldArray, executionDefinition == null ? Collections.<String>emptyList() : executionDefinition, typeHierarchy); 383 sortByExecutionOrder(fieldArray, executionDefinition == null ? Collections.<String> emptyList() : executionDefinition, typeHierarchy);
383 return fieldArray; 384 return fieldArray;
384 } 385 }
385 386
386 private NodeFieldData parseField(NodeData parentNodeData, VariableElement var, Set<String> foundShortCircuits) { 387 private NodeFieldData parseField(NodeData parentNodeData, VariableElement var, Set<String> foundShortCircuits) {
387 AnnotationMirror childMirror = Utils.findAnnotationMirror(processingEnv, var, Child.class); 388 AnnotationMirror childMirror = Utils.findAnnotationMirror(processingEnv, var, Child.class);
418 if (nodeType != null) { 419 if (nodeType != null) {
419 fieldNodeData = resolveNode(Utils.fromTypeMirror(nodeType)); 420 fieldNodeData = resolveNode(Utils.fromTypeMirror(nodeType));
420 Element errorElement = Utils.typeEquals(parentNodeData.getTemplateType().asType(), var.getEnclosingElement().asType()) ? var : parentNodeData.getTemplateType(); 421 Element errorElement = Utils.typeEquals(parentNodeData.getTemplateType().asType(), var.getEnclosingElement().asType()) ? var : parentNodeData.getTemplateType();
421 422
422 if (fieldNodeData == null) { 423 if (fieldNodeData == null) {
423 //TODO redirect errors from resolve. 424 // TODO redirect errors from resolve.
424 context.getLog().error(errorElement, "Node type '%s' is invalid.", Utils.getQualifiedName(nodeType)); 425 context.getLog().error(errorElement, "Node type '%s' is invalid.", Utils.getQualifiedName(nodeType));
425 return null; 426 return null;
426 } else if (fieldNodeData.findGenericExecutableType(context) == null) { 427 } else if (fieldNodeData.findGenericExecutableType(context) == null) {
427 context.getLog().error(errorElement, "No executable generic type found for node '%s'.", Utils.getQualifiedName(nodeType)); 428 context.getLog().error(errorElement, "No executable generic type found for node '%s'.", Utils.getQualifiedName(nodeType));
428 return null; 429 return null;
429 } 430 }
430 } 431 }
431 432
432 //TODO correct handling of access elements 433 // TODO correct handling of access elements
433 if (var.getModifiers().contains(Modifier.PRIVATE) && Utils.typeEquals(var.getEnclosingElement().asType(), parentNodeData.getTemplateType().asType())) { 434 if (var.getModifiers().contains(Modifier.PRIVATE) && Utils.typeEquals(var.getEnclosingElement().asType(), parentNodeData.getTemplateType().asType())) {
434 execution = ExecutionKind.IGNORE; 435 execution = ExecutionKind.IGNORE;
435 } 436 }
436 437
437 return new NodeFieldData(fieldNodeData, var, findAccessElement(var), mirror, kind, execution); 438 return new NodeFieldData(fieldNodeData, var, findAccessElement(var), mirror, kind, execution);
450 methodName = "get" + Utils.firstLetterUpperCase(variableElement.getSimpleName().toString()); 451 methodName = "get" + Utils.firstLetterUpperCase(variableElement.getSimpleName().toString());
451 } 452 }
452 453
453 ExecutableElement getter = null; 454 ExecutableElement getter = null;
454 for (ExecutableElement method : ElementFilter.methodsIn(enclosed.getEnclosedElements())) { 455 for (ExecutableElement method : ElementFilter.methodsIn(enclosed.getEnclosedElements())) {
455 if (method.getSimpleName().toString().equals(methodName) 456 if (method.getSimpleName().toString().equals(methodName) && method.getParameters().size() == 0 && !Utils.typeEquals(method.getReturnType(), context.getType(void.class))) {
456 && method.getParameters().size() == 0
457 && !Utils.typeEquals(method.getReturnType(), context.getType(void.class))) {
458 getter = method; 457 getter = method;
459 break; 458 break;
460 } 459 }
461 } 460 }
462 461
467 } 466 }
468 } 467 }
469 468
470 private static void sortByExecutionOrder(NodeFieldData[] fields, final List<String> executionOrder, final List<TypeElement> typeHierarchy) { 469 private static void sortByExecutionOrder(NodeFieldData[] fields, final List<String> executionOrder, final List<TypeElement> typeHierarchy) {
471 Arrays.sort(fields, new Comparator<NodeFieldData>() { 470 Arrays.sort(fields, new Comparator<NodeFieldData>() {
471
472 @Override 472 @Override
473 public int compare(NodeFieldData o1, NodeFieldData o2) { 473 public int compare(NodeFieldData o1, NodeFieldData o2) {
474 // sort by execution order 474 // sort by execution order
475 int index1 = executionOrder.indexOf(o1.getName()); 475 int index1 = executionOrder.indexOf(o1.getName());
476 int index2 = executionOrder.indexOf(o2.getName()); 476 int index2 = executionOrder.indexOf(o2.getName());
487 return index1 - index2; 487 return index1 - index2;
488 } 488 }
489 }); 489 });
490 } 490 }
491 491
492 private boolean assignShortCircuitsToSpecializations(NodeData nodeData, 492 private boolean assignShortCircuitsToSpecializations(NodeData nodeData, List<SpecializationData> specializations, List<ShortCircuitData> shortCircuits) {
493 List<SpecializationData> specializations,
494 List<ShortCircuitData> shortCircuits) {
495 493
496 Map<String, List<ShortCircuitData>> groupedShortCircuits = groupShortCircuits(shortCircuits); 494 Map<String, List<ShortCircuitData>> groupedShortCircuits = groupShortCircuits(shortCircuits);
497 495
498 boolean valid = true; 496 boolean valid = true;
499 497
500 for (NodeFieldData field : nodeData.filterFields(null, ExecutionKind.SHORT_CIRCUIT)) { 498 for (NodeFieldData field : nodeData.filterFields(null, ExecutionKind.SHORT_CIRCUIT)) {
501 String valueName = field.getName(); 499 String valueName = field.getName();
502 List<ShortCircuitData> availableCircuits = groupedShortCircuits.get(valueName); 500 List<ShortCircuitData> availableCircuits = groupedShortCircuits.get(valueName);
503 501
504 if (availableCircuits == null || availableCircuits.isEmpty()) { 502 if (availableCircuits == null || availableCircuits.isEmpty()) {
505 log.error(nodeData.getTemplateType(), 503 log.error(nodeData.getTemplateType(), "@%s method for short cut value '%s' required.", ShortCircuit.class.getSimpleName(), valueName);
506 "@%s method for short cut value '%s' required.",
507 ShortCircuit.class.getSimpleName(), valueName);
508 valid = false; 504 valid = false;
509 continue; 505 continue;
510 } 506 }
511
512 507
513 boolean sameMethodName = true; 508 boolean sameMethodName = true;
514 String methodName = availableCircuits.get(0).getMethodName(); 509 String methodName = availableCircuits.get(0).getMethodName();
515 for (ShortCircuitData circuit : availableCircuits) { 510 for (ShortCircuitData circuit : availableCircuits) {
516 if (!circuit.getMethodName().equals(methodName)) { 511 if (!circuit.getMethodName().equals(methodName)) {
533 break; 528 break;
534 } 529 }
535 } 530 }
536 531
537 if (genericCircuit == null) { 532 if (genericCircuit == null) {
538 log.error(nodeData.getTemplateType(), 533 log.error(nodeData.getTemplateType(), "No generic @%s method available for short cut value '%s'.", ShortCircuit.class.getSimpleName(), valueName);
539 "No generic @%s method available for short cut value '%s'.", ShortCircuit.class.getSimpleName(), valueName);
540 valid = false; 534 valid = false;
541 continue; 535 continue;
542 } 536 }
543 537
544 for (ShortCircuitData circuit : availableCircuits) { 538 for (ShortCircuitData circuit : availableCircuits) {
604 } 598 }
605 } 599 }
606 return valid; 600 return valid;
607 } 601 }
608 602
609
610 private static boolean isGenericShortCutMethod(NodeData node, TemplateMethod method) { 603 private static boolean isGenericShortCutMethod(NodeData node, TemplateMethod method) {
611 for (NodeFieldData field : node.getFields()) { 604 for (NodeFieldData field : node.getFields()) {
612 ActualParameter parameter = method.findParameter(field.getName()); 605 ActualParameter parameter = method.findParameter(field.getName());
613 if (parameter == null) { 606 if (parameter == null) {
614 continue; 607 continue;
631 circuits.add(shortCircuit); 624 circuits.add(shortCircuit);
632 } 625 }
633 return group; 626 return group;
634 } 627 }
635 628
636
637 private TypeMirror getComponentType(TypeMirror type) { 629 private TypeMirror getComponentType(TypeMirror type) {
638 if (type instanceof ArrayType) { 630 if (type instanceof ArrayType) {
639 return getComponentType(((ArrayType) type).getComponentType()); 631 return getComponentType(((ArrayType) type).getComponentType());
640 } 632 }
641 return type; 633 return type;
649 } 641 }
650 } 642 }
651 collection.add(element); 643 collection.add(element);
652 return collection; 644 return collection;
653 } 645 }
654
655 646
656 private boolean verifySpecializationOrder(TypeSystemData typeSystem, List<SpecializationData> specializations) { 647 private boolean verifySpecializationOrder(TypeSystemData typeSystem, List<SpecializationData> specializations) {
657 for (int i = 0; i < specializations.size(); i++) { 648 for (int i = 0; i < specializations.size(); i++) {
658 SpecializationData m1 = specializations.get(i); 649 SpecializationData m1 = specializations.get(i);
659 for (int j = i + 1; j < specializations.size(); j++) { 650 for (int j = i + 1; j < specializations.size(); j++) {
679 } 670 }
680 } 671 }
681 return true; 672 return true;
682 } 673 }
683 674
684
685 private boolean verifySpecializationThrows(TypeSystemData typeSystem, List<SpecializationData> specializations) { 675 private boolean verifySpecializationThrows(TypeSystemData typeSystem, List<SpecializationData> specializations) {
686 Map<String, SpecializationData> specializationMap = new HashMap<>(); 676 Map<String, SpecializationData> specializationMap = new HashMap<>();
687 for (SpecializationData spec : specializations) { 677 for (SpecializationData spec : specializations) {
688 specializationMap.put(spec.getMethodName(), spec); 678 specializationMap.put(spec.getMethodName(), spec);
689 } 679 }
693 for (SpecializationThrowsData throwsData : sourceSpecialization.getExceptions()) { 683 for (SpecializationThrowsData throwsData : sourceSpecialization.getExceptions()) {
694 SpecializationData targetSpecialization = specializationMap.get(throwsData.getTransitionToName()); 684 SpecializationData targetSpecialization = specializationMap.get(throwsData.getTransitionToName());
695 AnnotationValue value = Utils.getAnnotationValue(throwsData.getAnnotationMirror(), "transitionTo"); 685 AnnotationValue value = Utils.getAnnotationValue(throwsData.getAnnotationMirror(), "transitionTo");
696 686
697 if (targetSpecialization == null) { 687 if (targetSpecialization == null) {
698 log.error(throwsData.getSpecialization().getMethod(), throwsData.getAnnotationMirror(), value, 688 log.error(throwsData.getSpecialization().getMethod(), throwsData.getAnnotationMirror(), value, "Specialization with name '%s' not found.", throwsData.getTransitionToName());
699 "Specialization with name '%s' not found.", throwsData.getTransitionToName());
700 valid = false; 689 valid = false;
701 } else if (compareSpecialization(typeSystem, sourceSpecialization, targetSpecialization) >= 0) { 690 } else if (compareSpecialization(typeSystem, sourceSpecialization, targetSpecialization) >= 0) {
702 log.error(throwsData.getSpecialization().getMethod(), throwsData.getAnnotationMirror(), value, 691 log.error(throwsData.getSpecialization().getMethod(), throwsData.getAnnotationMirror(), value,
703 "The order of the target specializalization must be higher than the source specialization.", throwsData.getTransitionToName()); 692 "The order of the target specializalization must be higher than the source specialization.", throwsData.getTransitionToName());
704 valid = false; 693 valid = false;
705 } 694 }
706 695
707 for (SpecializationThrowsData otherThrowsData : sourceSpecialization.getExceptions()) { 696 for (SpecializationThrowsData otherThrowsData : sourceSpecialization.getExceptions()) {
708 if (otherThrowsData != throwsData 697 if (otherThrowsData != throwsData && Utils.typeEquals(otherThrowsData.getJavaClass(), throwsData.getJavaClass())) {
709 && Utils.typeEquals(otherThrowsData.getJavaClass(), throwsData.getJavaClass())) {
710 AnnotationValue javaClassValue = Utils.getAnnotationValue(throwsData.getAnnotationMirror(), "javaClass"); 698 AnnotationValue javaClassValue = Utils.getAnnotationValue(throwsData.getAnnotationMirror(), "javaClass");
711 log.error(throwsData.getSpecialization().getMethod(), throwsData.getAnnotationMirror(), javaClassValue, 699 log.error(throwsData.getSpecialization().getMethod(), throwsData.getAnnotationMirror(), javaClassValue, "Duplicate exception type.", throwsData.getTransitionToName());
712 "Duplicate exception type.", throwsData.getTransitionToName());
713 valid = false; 700 valid = false;
714 } 701 }
715 } 702 }
716 } 703 }
717 } 704 }
718 } 705 }
719 return valid; 706 return valid;
720 } 707 }
721
722 708
723 private static int compareSpecialization(TypeSystemData typeSystem, SpecializationData m1, SpecializationData m2) { 709 private static int compareSpecialization(TypeSystemData typeSystem, SpecializationData m1, SpecializationData m2) {
724 if (m1 == m2) { 710 if (m1 == m2) {
725 return 0; 711 return 0;
726 } 712 }
765 assert !(index1 == -1 ^ index2 == -1); 751 assert !(index1 == -1 ^ index2 == -1);
766 752
767 return index1 - index2; 753 return index1 - index2;
768 } 754 }
769 755
770
771 @Override 756 @Override
772 public Class< ? extends Annotation> getAnnotationType() { 757 public Class<? extends Annotation> getAnnotationType() {
773 return null; 758 return null;
774 } 759 }
775 760
776 @Override 761 @Override
777 public List<Class< ? extends Annotation>> getTypeDelegatedAnnotationTypes() { 762 public List<Class<? extends Annotation>> getTypeDelegatedAnnotationTypes() {
778 return ANNOTATIONS; 763 return ANNOTATIONS;
779 } 764 }
780 765
781 } 766 }