816 } |
816 } |
817 } |
817 } |
818 |
818 |
819 private void replaceAtMatchingUsages(Node other, Predicate<Node> filter, Node toBeDeleted) { |
819 private void replaceAtMatchingUsages(Node other, Predicate<Node> filter, Node toBeDeleted) { |
820 if (filter == null) { |
820 if (filter == null) { |
821 fail("filter cannot be null"); |
821 throw fail("filter cannot be null"); |
822 } |
822 } |
823 checkReplaceWith(other); |
823 checkReplaceWith(other); |
824 int i = 0; |
824 int i = 0; |
825 while (i < this.getUsageCount()) { |
825 int usageCount = this.getUsageCount(); |
|
826 while (i < usageCount) { |
826 Node usage = this.getUsageAt(i); |
827 Node usage = this.getUsageAt(i); |
827 if (filter.test(usage)) { |
828 if (filter.test(usage)) { |
828 replaceAtUsage(other, toBeDeleted, usage); |
829 replaceAtUsage(other, toBeDeleted, usage); |
829 this.movUsageFromEndTo(i); |
830 this.movUsageFromEndTo(i); |
|
831 usageCount--; |
830 } else { |
832 } else { |
831 ++i; |
833 ++i; |
832 } |
834 } |
833 } |
835 } |
834 } |
836 } |
835 |
837 |
836 public Node getUsageAt(int index) { |
838 private Node getUsageAt(int index) { |
837 if (index == 0) { |
839 if (index == 0) { |
838 return this.usage0; |
840 return this.usage0; |
839 } else if (index == 1) { |
841 } else if (index == 1) { |
840 return this.usage1; |
842 return this.usage1; |
841 } else { |
843 } else { |
846 public void replaceAtMatchingUsages(Node other, NodePredicate usagePredicate) { |
848 public void replaceAtMatchingUsages(Node other, NodePredicate usagePredicate) { |
847 checkReplaceWith(other); |
849 checkReplaceWith(other); |
848 replaceAtMatchingUsages(other, usagePredicate, null); |
850 replaceAtMatchingUsages(other, usagePredicate, null); |
849 } |
851 } |
850 |
852 |
|
853 private void replaceAtUsagePos(Node other, Node usage, Position pos) { |
|
854 pos.initialize(usage, other); |
|
855 maybeNotifyInputChanged(usage); |
|
856 if (other != null) { |
|
857 other.addUsage(usage); |
|
858 } |
|
859 } |
|
860 |
851 public void replaceAtUsages(InputType type, Node other) { |
861 public void replaceAtUsages(InputType type, Node other) { |
852 checkReplaceWith(other); |
862 checkReplaceWith(other); |
853 for (Node usage : usages().snapshot()) { |
863 int i = 0; |
|
864 int usageCount = this.getUsageCount(); |
|
865 if (usageCount == 0) { |
|
866 return; |
|
867 } |
|
868 usages: while (i < usageCount) { |
|
869 Node usage = this.getUsageAt(i); |
854 for (Position pos : usage.inputPositions()) { |
870 for (Position pos : usage.inputPositions()) { |
855 if (pos.getInputType() == type && pos.get(usage) == this) { |
871 if (pos.getInputType() == type && pos.get(usage) == this) { |
856 pos.set(usage, other); |
872 replaceAtUsagePos(other, usage, pos); |
|
873 this.movUsageFromEndTo(i); |
|
874 usageCount--; |
|
875 continue usages; |
857 } |
876 } |
858 } |
877 } |
|
878 i++; |
|
879 } |
|
880 if (hasNoUsages()) { |
|
881 maybeNotifyZeroUsages(this); |
859 } |
882 } |
860 } |
883 } |
861 |
884 |
862 private void maybeNotifyInputChanged(Node node) { |
885 private void maybeNotifyInputChanged(Node node) { |
863 if (graph != null) { |
886 if (graph != null) { |
908 } |
931 } |
909 |
932 |
910 public void replaceFirstInput(Node oldInput, Node newInput) { |
933 public void replaceFirstInput(Node oldInput, Node newInput) { |
911 if (nodeClass.replaceFirstInput(this, oldInput, newInput)) { |
934 if (nodeClass.replaceFirstInput(this, oldInput, newInput)) { |
912 updateUsages(oldInput, newInput); |
935 updateUsages(oldInput, newInput); |
|
936 } |
|
937 } |
|
938 |
|
939 public void replaceFirstInput(Node oldInput, Node newInput, InputType type) { |
|
940 for (Position pos : inputPositions()) { |
|
941 if (pos.getInputType() == type && pos.get(this) == oldInput) { |
|
942 pos.set(this, newInput); |
|
943 } |
913 } |
944 } |
914 } |
945 } |
915 |
946 |
916 public void clearInputs() { |
947 public void clearInputs() { |
917 assert assertFalse(isDeleted(), "cannot clear inputs of deleted node"); |
948 assert assertFalse(isDeleted(), "cannot clear inputs of deleted node"); |
1057 assertTrue(pos.isInputOptional(), "non-optional input %s cannot be null in %s (fix nullness or use @OptionalInput)", pos, this); |
1088 assertTrue(pos.isInputOptional(), "non-optional input %s cannot be null in %s (fix nullness or use @OptionalInput)", pos, this); |
1058 } else { |
1089 } else { |
1059 assertFalse(input.isDeleted(), "input was deleted %s", input); |
1090 assertFalse(input.isDeleted(), "input was deleted %s", input); |
1060 assertTrue(input.isAlive(), "input is not alive yet, i.e., it was not yet added to the graph"); |
1091 assertTrue(input.isAlive(), "input is not alive yet, i.e., it was not yet added to the graph"); |
1061 assertTrue(pos.getInputType() == InputType.Unchecked || input.isAllowedUsageType(pos.getInputType()), "invalid usage type %s %s", input, pos.getInputType()); |
1092 assertTrue(pos.getInputType() == InputType.Unchecked || input.isAllowedUsageType(pos.getInputType()), "invalid usage type %s %s", input, pos.getInputType()); |
|
1093 Class<?> expectedType = pos.getType(); |
|
1094 assertTrue(expectedType.isAssignableFrom(input.getClass()), "Invalid input type for %s: expected a %s but was a %s", pos, expectedType, input.getClass()); |
1062 } |
1095 } |
1063 } |
1096 } |
1064 return true; |
1097 return true; |
1065 } |
1098 } |
1066 |
1099 |