comparison graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/NodeParser.java @ 18806:b9cf6f3150ea

Truffle-DSL: make node id renaming a fixed point algorithm; relax warning condition for multiple execute methods; fix warning condition for multiple execute methods has displayed unproblematic execute methods.
author Christian Humer <christian.humer@gmail.com>
date Fri, 09 Jan 2015 16:04:37 +0100
parents 941761f6b736
children d2ec5f50dcd0
comparison
equal deleted inserted replaced
18805:121748e43a01 18806:b9cf6f3150ea
524 } 524 }
525 return executions; 525 return executions;
526 } 526 }
527 527
528 private void initializeExecutableTypes(NodeData node) { 528 private void initializeExecutableTypes(NodeData node) {
529 List<ExecutableTypeData> genericExecutes = node.findGenericExecutableTypes(context, 0);
530 List<ExecutableTypeData> allExecutes = node.getExecutableTypes(); 529 List<ExecutableTypeData> allExecutes = node.getExecutableTypes();
531 530
532 Set<String> inconsistentFrameTypes = new HashSet<>(); 531 Set<String> inconsistentFrameTypes = new HashSet<>();
533 TypeMirror frameType = null; 532 TypeMirror frameType = null;
534 Set<Integer> evaluatedCounts = new HashSet<>(); 533 Set<Integer> evaluatedCounts = new HashSet<>();
559 Collections.sort(inconsistentFrameTypesList); 558 Collections.sort(inconsistentFrameTypesList);
560 node.addError("Invalid inconsistent frame types %s found for the declared execute methods. The frame type must be identical for all execute methods.", inconsistentFrameTypesList); 559 node.addError("Invalid inconsistent frame types %s found for the declared execute methods. The frame type must be identical for all execute methods.", inconsistentFrameTypesList);
561 } 560 }
562 node.setFrameType(frameType); 561 node.setFrameType(frameType);
563 562
564 int nonFinalCount = 0; 563 int totalGenericCount = 0;
565 int voidCount = 0; 564 int totalVoidCount = 0;
566 for (ExecutableTypeData executableTypeData : genericExecutes) { 565 for (Integer evaluatedCount : evaluatedCounts) {
567 if (!executableTypeData.getMethod().getModifiers().contains(Modifier.FINAL)) { 566 List<ExecutableTypeData> genericExecutes = node.findGenericExecutableTypes(context, evaluatedCount);
568 nonFinalCount++; 567 int genericCount = 0;
569 } 568 int voidCount = 0;
570 if (ElementUtils.isVoid(executableTypeData.getReturnType().getType())) { 569 for (ExecutableTypeData executableTypeData : genericExecutes) {
571 voidCount++; 570 if (!executableTypeData.getMethod().getModifiers().contains(Modifier.FINAL)) {
572 } 571 if (ElementUtils.isVoid(executableTypeData.getReturnType().getType())) {
572 voidCount++;
573 } else {
574 genericCount++;
575 }
576 }
577 }
578 // multiple generic execute
579 if (evaluatedCount == 0) {
580 if (voidCount > 1) {
581 List<String> methodSignatures = new ArrayList<>();
582 for (ExecutableTypeData type : genericExecutes) {
583 if (type.getType().isVoid()) {
584 methodSignatures.add(type.createReferenceName());
585 }
586 }
587 node.addWarning("Multiple accessible and overridable generic execute methods found %s. Remove all but one or mark all but one as final.", methodSignatures);
588 } else if (genericCount > 1) {
589 List<String> methodSignatures = new ArrayList<>();
590 for (ExecutableTypeData type : genericExecutes) {
591 if (!type.getType().isVoid()) {
592 methodSignatures.add(type.createReferenceName());
593 }
594 }
595 node.addWarning("Multiple accessible and overridable generic execute methods found %s. Remove all but one or mark all but one as final.", methodSignatures);
596 }
597 }
598 totalGenericCount += genericCount;
599 totalVoidCount += voidCount;
573 } 600 }
574 601
575 // no generic executes 602 // no generic executes
576 if (nonFinalCount == 0 && voidCount == 0) { 603 if (totalGenericCount + totalVoidCount == 0) {
577 node.addError("No accessible and overridable generic execute method found. Generic execute methods usually have the " 604 node.addError("No accessible and overridable generic execute method found. Generic execute methods usually have the "
578 + "signature 'public abstract {Type} execute(VirtualFrame)' and must not throw any checked exceptions."); 605 + "signature 'public abstract {Type} execute(VirtualFrame)' and must not throw any checked exceptions.");
579 } 606 }
580 607
581 // multiple generic execute
582 if (voidCount > 1 || (nonFinalCount - voidCount) > 1) {
583 List<String> methodSignatures = new ArrayList<>();
584 for (ExecutableTypeData type : genericExecutes) {
585 methodSignatures.add(type.createReferenceName());
586 }
587 node.addWarning("Multiple accessible and overridable generic execute methods found %s. Remove all but one or mark all but one as final.", methodSignatures);
588 }
589 } 608 }
590 609
591 private static Map<Integer, List<ExecutableTypeData>> groupExecutableTypes(List<ExecutableTypeData> executableTypes) { 610 private static Map<Integer, List<ExecutableTypeData>> groupExecutableTypes(List<ExecutableTypeData> executableTypes) {
592 Map<Integer, List<ExecutableTypeData>> groupedTypes = new TreeMap<>(); 611 Map<Integer, List<ExecutableTypeData>> groupedTypes = new TreeMap<>();
593 for (ExecutableTypeData type : executableTypes) { 612 for (ExecutableTypeData type : executableTypes) {
905 } 924 }
906 signatures.add(ElementUtils.firstLetterUpperCase(name)); 925 signatures.add(ElementUtils.firstLetterUpperCase(name));
907 } 926 }
908 } 927 }
909 928
910 renameDuplicateIds(signatures); 929 while (renameDuplicateIds(signatures)) {
930 // fix point
931 }
932
911 for (int i = 0; i < specializations.size(); i++) { 933 for (int i = 0; i < specializations.size(); i++) {
912 specializations.get(i).setId(signatures.get(i)); 934 specializations.get(i).setId(signatures.get(i));
913 } 935 }
914 } 936 }
915 937
916 private static void renameDuplicateIds(List<String> signatures) { 938 private static boolean renameDuplicateIds(List<String> signatures) {
939 boolean changed = false;
917 Map<String, Integer> counts = new HashMap<>(); 940 Map<String, Integer> counts = new HashMap<>();
918 for (String s1 : signatures) { 941 for (String s1 : signatures) {
919 Integer count = counts.get(s1); 942 Integer count = counts.get(s1);
920 if (count == null) { 943 if (count == null) {
921 count = 0; 944 count = 0;
925 } 948 }
926 949
927 for (String s : counts.keySet()) { 950 for (String s : counts.keySet()) {
928 int count = counts.get(s); 951 int count = counts.get(s);
929 if (count > 1) { 952 if (count > 1) {
953 changed = true;
930 int number = 0; 954 int number = 0;
931 for (ListIterator<String> iterator = signatures.listIterator(); iterator.hasNext();) { 955 for (ListIterator<String> iterator = signatures.listIterator(); iterator.hasNext();) {
932 String s2 = iterator.next(); 956 String s2 = iterator.next();
933 if (s.equals(s2)) { 957 if (s.equals(s2)) {
934 iterator.set(s2 + number); 958 iterator.set(s2 + number);
935 number++; 959 number++;
936 } 960 }
937 } 961 }
938 } 962 }
939 } 963 }
964 return changed;
940 } 965 }
941 966
942 private void initializeGuards(List<? extends Element> elements, NodeData node) { 967 private void initializeGuards(List<? extends Element> elements, NodeData node) {
943 Map<String, List<ExecutableElement>> potentialGuards = new HashMap<>(); 968 Map<String, List<ExecutableElement>> potentialGuards = new HashMap<>();
944 for (SpecializationData specialization : node.getSpecializations()) { 969 for (SpecializationData specialization : node.getSpecializations()) {