Mercurial > hg > graal-jvmci-8
comparison graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/NodeParser.java @ 19292:906367e494ca
Truffle-DSL: fix invalid parameter order for executeWith with non-linear execution.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Wed, 11 Feb 2015 12:13:44 +0100 |
parents | f4792a544170 |
children | 91dea7a100d2 |
comparison
equal
deleted
inserted
replaced
19291:f4792a544170 | 19292:906367e494ca |
---|---|
143 } | 143 } |
144 | 144 |
145 node.getFields().addAll(parseFields(lookupTypes, members)); | 145 node.getFields().addAll(parseFields(lookupTypes, members)); |
146 node.getChildren().addAll(parseChildren(lookupTypes, members)); | 146 node.getChildren().addAll(parseChildren(lookupTypes, members)); |
147 node.getChildExecutions().addAll(parseExecutions(node.getChildren(), members)); | 147 node.getChildExecutions().addAll(parseExecutions(node.getChildren(), members)); |
148 node.setExecutableTypes(groupExecutableTypes(new ExecutableTypeMethodParser(context, node, context.getFrameTypes()).parse(members))); | 148 node.setExecutableTypes(groupExecutableTypes(new ExecutableTypeMethodParser(context, node, null, context.getFrameTypes()).parse(members))); |
149 | 149 |
150 initializeExecutableTypes(node); | 150 initializeExecutableTypes(node); |
151 initializeImportGuards(node, lookupTypes, members); | 151 initializeImportGuards(node, lookupTypes, members); |
152 | 152 |
153 if (node.hasErrors()) { | 153 if (node.hasErrors()) { |
400 filteredChildren.add(0, child); | 400 filteredChildren.add(0, child); |
401 encounteredNames.add(child.getName()); | 401 encounteredNames.add(child.getName()); |
402 } | 402 } |
403 } | 403 } |
404 | 404 |
405 for (NodeChildData child : filteredChildren) { | |
406 List<String> executeWithStrings = ElementUtils.getAnnotationValueList(String.class, child.getMessageAnnotation(), "executeWith"); | |
407 AnnotationValue executeWithValue = ElementUtils.getAnnotationValue(child.getMessageAnnotation(), "executeWith"); | |
408 List<NodeChildData> executeWith = new ArrayList<>(); | |
409 for (String executeWithString : executeWithStrings) { | |
410 | |
411 if (child.getName().equals(executeWithString)) { | |
412 child.addError(executeWithValue, "The child node '%s' cannot be executed with itself.", executeWithString); | |
413 continue; | |
414 } | |
415 | |
416 NodeChildData found = null; | |
417 boolean before = true; | |
418 for (NodeChildData resolveChild : filteredChildren) { | |
419 if (resolveChild == child) { | |
420 before = false; | |
421 continue; | |
422 } | |
423 if (resolveChild.getName().equals(executeWithString)) { | |
424 found = resolveChild; | |
425 break; | |
426 } | |
427 } | |
428 | |
429 if (found == null) { | |
430 child.addError(executeWithValue, "The child node '%s' cannot be executed with '%s'. The child node was not found.", child.getName(), executeWithString); | |
431 continue; | |
432 } else if (!before) { | |
433 child.addError(executeWithValue, "The child node '%s' cannot be executed with '%s'. The node %s is executed after the current node.", child.getName(), executeWithString, | |
434 executeWithString); | |
435 continue; | |
436 } | |
437 executeWith.add(found); | |
438 } | |
439 child.setExecuteWith(executeWith); | |
440 if (child.getNodeData() == null) { | |
441 continue; | |
442 } | |
443 } | |
444 | |
445 return filteredChildren; | 405 return filteredChildren; |
446 } | 406 } |
447 | 407 |
448 private List<NodeExecutionData> parseExecutions(List<NodeChildData> children, List<? extends Element> elements) { | 408 private List<NodeExecutionData> parseExecutions(List<NodeChildData> children, List<? extends Element> elements) { |
449 if (children == null) { | 409 if (children == null) { |
502 if (childIndex == -1) { | 462 if (childIndex == -1) { |
503 continue; | 463 continue; |
504 } | 464 } |
505 if (!skipShortCircuit) { | 465 if (!skipShortCircuit) { |
506 NodeChildData child = children.get(childIndex); | 466 NodeChildData child = children.get(childIndex); |
507 if (shortCircuits.contains(NodeExecutionData.createShortCircuitId(child, currentArgumentIndex - childIndex))) { | 467 if (shortCircuits.contains(NodeExecutionData.createIndexedName(child, currentArgumentIndex - childIndex))) { |
508 skipShortCircuit = true; | 468 skipShortCircuit = true; |
509 continue; | 469 continue; |
510 } | 470 } |
511 } else { | 471 } else { |
512 skipShortCircuit = false; | 472 skipShortCircuit = false; |
529 break; | 489 break; |
530 } | 490 } |
531 } | 491 } |
532 int varArgsIndex = varArg ? Math.abs(childIndex - i) : -1; | 492 int varArgsIndex = varArg ? Math.abs(childIndex - i) : -1; |
533 NodeChildData child = children.get(childIndex); | 493 NodeChildData child = children.get(childIndex); |
534 boolean shortCircuit = shortCircuits.contains(NodeExecutionData.createShortCircuitId(child, varArgsIndex)); | 494 boolean shortCircuit = shortCircuits.contains(NodeExecutionData.createIndexedName(child, varArgsIndex)); |
535 executions.add(new NodeExecutionData(child, varArgsIndex, shortCircuit)); | 495 executions.add(new NodeExecutionData(child, varArgsIndex, shortCircuit)); |
536 } | 496 } |
537 return executions; | 497 return executions; |
538 } | 498 } |
539 | 499 |
636 } | 596 } |
637 return groupedTypes; | 597 return groupedTypes; |
638 } | 598 } |
639 | 599 |
640 private void initializeChildren(NodeData node) { | 600 private void initializeChildren(NodeData node) { |
601 initializeExecuteWith(node); | |
602 | |
641 for (NodeChildData child : node.getChildren()) { | 603 for (NodeChildData child : node.getChildren()) { |
642 TypeMirror nodeType = child.getNodeType(); | 604 TypeMirror nodeType = child.getNodeType(); |
643 NodeData fieldNodeData = parseChildNodeData(node, ElementUtils.fromTypeMirror(nodeType)); | 605 NodeData fieldNodeData = parseChildNodeData(node, child, ElementUtils.fromTypeMirror(nodeType)); |
644 | 606 |
645 child.setNode(fieldNodeData); | 607 child.setNode(fieldNodeData); |
646 if (fieldNodeData == null || fieldNodeData.hasErrors()) { | 608 if (fieldNodeData == null || fieldNodeData.hasErrors()) { |
647 child.addError("Node type '%s' is invalid or not a subclass of Node.", ElementUtils.getQualifiedName(nodeType)); | 609 child.addError("Node type '%s' is invalid or not a subclass of Node.", ElementUtils.getQualifiedName(nodeType)); |
648 } else if (!ElementUtils.typeEquals(fieldNodeData.getTypeSystem().getTemplateType().asType(), (node.getTypeSystem().getTemplateType().asType()))) { | 610 } else if (!ElementUtils.typeEquals(fieldNodeData.getTypeSystem().getTemplateType().asType(), (node.getTypeSystem().getTemplateType().asType()))) { |
658 } | 620 } |
659 } | 621 } |
660 } | 622 } |
661 } | 623 } |
662 | 624 |
663 private NodeData parseChildNodeData(NodeData parentNode, TypeElement originalTemplateType) { | 625 private static void initializeExecuteWith(NodeData node) { |
626 for (NodeChildData child : node.getChildren()) { | |
627 List<String> executeWithStrings = ElementUtils.getAnnotationValueList(String.class, child.getMessageAnnotation(), "executeWith"); | |
628 AnnotationValue executeWithValue = ElementUtils.getAnnotationValue(child.getMessageAnnotation(), "executeWith"); | |
629 List<NodeExecutionData> executeWith = new ArrayList<>(); | |
630 for (String executeWithString : executeWithStrings) { | |
631 if (child.getName().equals(executeWithString)) { | |
632 child.addError(executeWithValue, "The child node '%s' cannot be executed with itself.", executeWithString); | |
633 continue; | |
634 } | |
635 NodeExecutionData found = null; | |
636 boolean before = true; | |
637 for (NodeExecutionData resolveChild : node.getChildExecutions()) { | |
638 if (resolveChild.getChild() == child) { | |
639 before = false; | |
640 continue; | |
641 } | |
642 if (resolveChild.getIndexedName().equals(executeWithString)) { | |
643 found = resolveChild; | |
644 break; | |
645 } | |
646 } | |
647 | |
648 if (found == null) { | |
649 child.addError(executeWithValue, "The child node '%s' cannot be executed with '%s'. The child node was not found.", child.getName(), executeWithString); | |
650 continue; | |
651 } else if (!before) { | |
652 child.addError(executeWithValue, "The child node '%s' cannot be executed with '%s'. The node %s is executed after the current node.", child.getName(), executeWithString, | |
653 executeWithString); | |
654 continue; | |
655 } | |
656 executeWith.add(found); | |
657 } | |
658 child.setExecuteWith(executeWith); | |
659 } | |
660 } | |
661 | |
662 private NodeData parseChildNodeData(NodeData parentNode, NodeChildData child, TypeElement originalTemplateType) { | |
664 TypeElement templateType = ElementUtils.fromTypeMirror(context.reloadTypeElement(originalTemplateType)); | 663 TypeElement templateType = ElementUtils.fromTypeMirror(context.reloadTypeElement(originalTemplateType)); |
665 | 664 |
666 if (ElementUtils.findAnnotationMirror(processingEnv, originalTemplateType, GeneratedBy.class) != null) { | 665 if (ElementUtils.findAnnotationMirror(processingEnv, originalTemplateType, GeneratedBy.class) != null) { |
667 // generated nodes should not get called again. | 666 // generated nodes should not get called again. |
668 return null; | 667 return null; |
678 List<? extends Element> members = processingEnv.getElementUtils().getAllMembers(templateType); | 677 List<? extends Element> members = processingEnv.getElementUtils().getAllMembers(templateType); |
679 NodeData node = parseNodeData(templateType, lookupTypes); | 678 NodeData node = parseNodeData(templateType, lookupTypes); |
680 if (node.hasErrors()) { | 679 if (node.hasErrors()) { |
681 return node; | 680 return node; |
682 } | 681 } |
683 node.setExecutableTypes(groupExecutableTypes(new ExecutableTypeMethodParser(context, node, createAllowedChildFrameTypes(parentNode)).parse(members))); | 682 node.setExecutableTypes(groupExecutableTypes(new ExecutableTypeMethodParser(context, node, child, createAllowedChildFrameTypes(parentNode)).parse(members))); |
684 node.setFrameType(parentNode.getFrameType()); | 683 node.setFrameType(parentNode.getFrameType()); |
685 return node; | 684 return node; |
686 } | 685 } |
687 | 686 |
688 private List<TypeMirror> createAllowedChildFrameTypes(NodeData parentNode) { | 687 private List<TypeMirror> createAllowedChildFrameTypes(NodeData parentNode) { |
1286 for (NodeExecutionData execution : node.getChildExecutions()) { | 1285 for (NodeExecutionData execution : node.getChildExecutions()) { |
1287 if (!execution.isShortCircuit()) { | 1286 if (!execution.isShortCircuit()) { |
1288 continue; | 1287 continue; |
1289 } | 1288 } |
1290 shortCircuitExecutions.add(execution); | 1289 shortCircuitExecutions.add(execution); |
1291 String valueName = execution.getShortCircuitId(); | 1290 String valueName = execution.getIndexedName(); |
1292 List<ShortCircuitData> availableCircuits = groupedShortCircuits.get(valueName); | 1291 List<ShortCircuitData> availableCircuits = groupedShortCircuits.get(valueName); |
1293 | 1292 |
1294 if (availableCircuits == null || availableCircuits.isEmpty()) { | 1293 if (availableCircuits == null || availableCircuits.isEmpty()) { |
1295 node.addError("@%s method for short cut value '%s' required.", ShortCircuit.class.getSimpleName(), valueName); | 1294 node.addError("@%s method for short cut value '%s' required.", ShortCircuit.class.getSimpleName(), valueName); |
1296 valid = false; | 1295 valid = false; |
1342 specializations.addAll(node.getSpecializations()); | 1341 specializations.addAll(node.getSpecializations()); |
1343 for (SpecializationData specialization : specializations) { | 1342 for (SpecializationData specialization : specializations) { |
1344 List<ShortCircuitData> assignedShortCuts = new ArrayList<>(shortCircuitExecutions.size()); | 1343 List<ShortCircuitData> assignedShortCuts = new ArrayList<>(shortCircuitExecutions.size()); |
1345 | 1344 |
1346 for (NodeExecutionData shortCircuit : shortCircuitExecutions) { | 1345 for (NodeExecutionData shortCircuit : shortCircuitExecutions) { |
1347 List<ShortCircuitData> availableShortCuts = groupedShortCircuits.get(shortCircuit.getShortCircuitId()); | 1346 List<ShortCircuitData> availableShortCuts = groupedShortCircuits.get(shortCircuit.getIndexedName()); |
1348 | 1347 |
1349 ShortCircuitData genericShortCircuit = null; | 1348 ShortCircuitData genericShortCircuit = null; |
1350 ShortCircuitData compatibleShortCircuit = null; | 1349 ShortCircuitData compatibleShortCircuit = null; |
1351 for (ShortCircuitData circuit : availableShortCuts) { | 1350 for (ShortCircuitData circuit : availableShortCuts) { |
1352 if (circuit.isGeneric()) { | 1351 if (circuit.isGeneric()) { |