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()) {