comparison graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java @ 9287:8e3a1635cc9e

Implemented @NodeChild(executeWith={...}).
author Christian Humer <christian.humer@gmail.com>
date Wed, 24 Apr 2013 21:50:03 +0200
parents 39f08ef7b5d8
children 0e4db5ee0695
comparison
equal deleted inserted replaced
9286:39f08ef7b5d8 9287:8e3a1635cc9e
308 } else if (node.needsRewrites(context)) { 308 } else if (node.needsRewrites(context)) {
309 SpecializationData specialization = specializations.get(0); 309 SpecializationData specialization = specializations.get(0);
310 GenericParser parser = new GenericParser(context, node); 310 GenericParser parser = new GenericParser(context, node);
311 MethodSpec specification = parser.createDefaultMethodSpec(specialization.getMethod(), null, true, null); 311 MethodSpec specification = parser.createDefaultMethodSpec(specialization.getMethod(), null, true, null);
312 312
313 ExecutableTypeData anyGenericReturnType = node.findAnyGenericExecutableType(context); 313 ExecutableTypeData anyGenericReturnType = node.findAnyGenericExecutableType(context, 0);
314 assert anyGenericReturnType != null; 314 assert anyGenericReturnType != null;
315 315
316 ActualParameter returnType = new ActualParameter(specification.getReturnType(), anyGenericReturnType.getType(), 0, false); 316 ActualParameter returnType = new ActualParameter(specification.getReturnType(), anyGenericReturnType.getType(), 0, false);
317 List<ActualParameter> parameters = new ArrayList<>(); 317 List<ActualParameter> parameters = new ArrayList<>();
318 for (ActualParameter specializationParameter : specialization.getParameters()) { 318 for (ActualParameter specializationParameter : specialization.getParameters()) {
320 NodeChildData child = node.findChild(parameterSpec.getName()); 320 NodeChildData child = node.findChild(parameterSpec.getName());
321 TypeData actualType; 321 TypeData actualType;
322 if (child == null) { 322 if (child == null) {
323 actualType = specializationParameter.getTypeSystemType(); 323 actualType = specializationParameter.getTypeSystemType();
324 } else { 324 } else {
325 ExecutableTypeData paramType = child.getNodeData().findAnyGenericExecutableType(context); 325 ExecutableTypeData paramType = child.findAnyGenericExecutableType(context);
326 assert paramType != null; 326 assert paramType != null;
327 actualType = paramType.getType(); 327 actualType = paramType.getType();
328 } 328 }
329 329
330 if (actualType != null) { 330 if (actualType != null) {
582 nodeData.setSplitByMethodName(splitByMethodName); 582 nodeData.setSplitByMethodName(splitByMethodName);
583 nodeData.setTypeSystem(typeSystem); 583 nodeData.setTypeSystem(typeSystem);
584 nodeData.setFields(parseFields(elements)); 584 nodeData.setFields(parseFields(elements));
585 parsedNodes.put(Utils.getQualifiedName(templateType), nodeData); 585 parsedNodes.put(Utils.getQualifiedName(templateType), nodeData);
586 // parseChildren invokes cyclic parsing. 586 // parseChildren invokes cyclic parsing.
587 nodeData.setChildren(parseChildren(templateType, elements, lookupTypes)); 587 nodeData.setChildren(parseChildren(elements, lookupTypes));
588 nodeData.setExecutableTypes(groupExecutableTypes(new ExecutableTypeMethodParser(context, nodeData).parse(elements))); 588 nodeData.setExecutableTypes(groupExecutableTypes(new ExecutableTypeMethodParser(context, nodeData).parse(elements)));
589 589
590 return nodeData; 590 return nodeData;
591 } 591 }
592 592
720 } 720 }
721 } 721 }
722 return fields; 722 return fields;
723 } 723 }
724 724
725 private List<NodeChildData> parseChildren(TypeElement templateType, List<? extends Element> elements, final List<TypeElement> typeHierarchy) { 725 private List<NodeChildData> parseChildren(List<? extends Element> elements, final List<TypeElement> typeHierarchy) {
726 Set<String> shortCircuits = new HashSet<>(); 726 Set<String> shortCircuits = new HashSet<>();
727 for (ExecutableElement method : ElementFilter.methodsIn(elements)) { 727 for (ExecutableElement method : ElementFilter.methodsIn(elements)) {
728 AnnotationMirror mirror = Utils.findAnnotationMirror(processingEnv, method, ShortCircuit.class); 728 AnnotationMirror mirror = Utils.findAnnotationMirror(processingEnv, method, ShortCircuit.class);
729 if (mirror != null) { 729 if (mirror != null) {
730 shortCircuits.add(Utils.getAnnotationValue(String.class, mirror, "value")); 730 shortCircuits.add(Utils.getAnnotationValue(String.class, mirror, "value"));
763 ExecutionKind kind = ExecutionKind.DEFAULT; 763 ExecutionKind kind = ExecutionKind.DEFAULT;
764 if (shortCircuits.contains(name)) { 764 if (shortCircuits.contains(name)) {
765 kind = ExecutionKind.SHORT_CIRCUIT; 765 kind = ExecutionKind.SHORT_CIRCUIT;
766 } 766 }
767 767
768 NodeChildData nodeChild = new NodeChildData(templateType, childMirror, name, childType, getter, cardinality, kind); 768 NodeChildData nodeChild = new NodeChildData(type, childMirror, name, childType, getter, cardinality, kind);
769 769
770 parsedChildren.add(nodeChild); 770 parsedChildren.add(nodeChild);
771 771
772 verifyNodeChild(nodeChild); 772 verifyNodeChild(nodeChild);
773 if (nodeChild.hasErrors()) { 773 if (nodeChild.hasErrors()) {
776 776
777 NodeData fieldNodeData = resolveNode(Utils.fromTypeMirror(childType)); 777 NodeData fieldNodeData = resolveNode(Utils.fromTypeMirror(childType));
778 nodeChild.setNode(fieldNodeData); 778 nodeChild.setNode(fieldNodeData);
779 if (fieldNodeData == null) { 779 if (fieldNodeData == null) {
780 nodeChild.addError("Node type '%s' is invalid or not a valid Node.", Utils.getQualifiedName(childType)); 780 nodeChild.addError("Node type '%s' is invalid or not a valid Node.", Utils.getQualifiedName(childType));
781 } else if (fieldNodeData.findGenericExecutableTypes(context).isEmpty()) {
782 nodeChild.addError("No executable generic types found for node '%s'.", Utils.getQualifiedName(type));
783 } 781 }
784 } 782 }
785 } 783 }
786 784
787 List<NodeChildData> filteredChildren = new ArrayList<>(); 785 List<NodeChildData> filteredChildren = new ArrayList<>();
791 if (!encounteredNames.contains(child.getName())) { 789 if (!encounteredNames.contains(child.getName())) {
792 filteredChildren.add(0, child); 790 filteredChildren.add(0, child);
793 encounteredNames.add(child.getName()); 791 encounteredNames.add(child.getName());
794 } 792 }
795 } 793 }
794
795 for (NodeChildData child : filteredChildren) {
796 List<String> executeWithStrings = Utils.getAnnotationValueList(String.class, child.getMessageAnnotation(), "executeWith");
797 AnnotationValue executeWithValue = Utils.getAnnotationValue(child.getMessageAnnotation(), "executeWith");
798 List<NodeChildData> executeWith = new ArrayList<>();
799 for (String executeWithString : executeWithStrings) {
800
801 if (child.getName().equals(executeWithString)) {
802 child.addError(executeWithValue, "The child node '%s' cannot be executed with itself.", executeWithString);
803 continue;
804 }
805
806 NodeChildData found = null;
807 boolean before = true;
808 for (NodeChildData resolveChild : filteredChildren) {
809 if (resolveChild == child) {
810 before = false;
811 continue;
812 }
813 if (resolveChild.getName().equals(executeWithString)) {
814 found = resolveChild;
815 break;
816 }
817 }
818
819 if (found == null) {
820 child.addError(executeWithValue, "The child node '%s' cannot be executed with '%s'. The child node was not found.", child.getName(), executeWithString);
821 continue;
822 } else if (!before) {
823 child.addError(executeWithValue, "The child node '%s' cannot be executed with '%s'. The node %s is executed after the current node.", child.getName(), executeWithString,
824 executeWithString);
825 continue;
826 }
827 executeWith.add(found);
828 }
829 child.setExecuteWith(executeWith);
830 if (child.getNodeData() == null) {
831 continue;
832 }
833
834 List<ExecutableTypeData> types = child.findGenericExecutableTypes(context);
835 if (types.isEmpty()) {
836 child.addError(executeWithValue, "No generic execute method found with %s evaluated arguments for node type %s.", executeWith.size(), Utils.getSimpleName(child.getNodeType()));
837 continue;
838 }
839 }
840
796 return filteredChildren; 841 return filteredChildren;
797 } 842 }
798 843
799 private static void verifyNodeChild(NodeChildData nodeChild) { 844 private static void verifyNodeChild(NodeChildData nodeChild) {
800 if (nodeChild.getNodeType() == null) { 845 if (nodeChild.getNodeType() == null) {
928 NodeChildData field = node.findChild(parameter.getSpecification().getName()); 973 NodeChildData field = node.findChild(parameter.getSpecification().getName());
929 if (field == null) { 974 if (field == null) {
930 continue; 975 continue;
931 } 976 }
932 ExecutableTypeData found = null; 977 ExecutableTypeData found = null;
933 List<ExecutableTypeData> executableElements = field.getNodeData().findGenericExecutableTypes(context); 978 List<ExecutableTypeData> executableElements = field.findGenericExecutableTypes(context);
934 for (ExecutableTypeData executable : executableElements) { 979 for (ExecutableTypeData executable : executableElements) {
935 if (executable.getType().equalsType(parameter.getTypeSystemType())) { 980 if (executable.getType().equalsType(parameter.getTypeSystemType())) {
936 found = executable; 981 found = executable;
937 break; 982 break;
938 } 983 }