Mercurial > hg > graal-compiler
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 } |