private NodeZipper moveUp()

in src/main/com/intellij/lang/jsgraphql/types/util/NodeMultiZipper.java [139:198]


  private NodeZipper<T> moveUp(T parent, List<NodeZipper<T>> sameParent) {
    assertNotEmpty(sameParent, () -> "expected at least one zipper");

    Map<String, List<T>> childrenMap = new HashMap<>(nodeAdapter.getNamedChildren(parent));
    Map<String, Integer> indexCorrection = new HashMap<>();

    sameParent = new ArrayList<>(sameParent);
    sameParent.sort((zipper1, zipper2) -> {
      int index1 = zipper1.getBreadcrumbs().get(0).getLocation().getIndex();
      int index2 = zipper2.getBreadcrumbs().get(0).getLocation().getIndex();
      if (index1 != index2) {
        return Integer.compare(index1, index2);
      }
      NodeZipper.ModificationType modificationType1 = zipper1.getModificationType();
      NodeZipper.ModificationType modificationType2 = zipper2.getModificationType();

      // same index can never be deleted and changed at the same time

      if (modificationType1 == modificationType2) {
        return 0;
      }

      // always first replacing the node
      if (modificationType1 == REPLACE) {
        return -1;
      }
      // and then INSERT_BEFORE before INSERT_AFTER
      return modificationType1 == NodeZipper.ModificationType.INSERT_BEFORE ? -1 : 1;
    });

    for (NodeZipper<T> zipper : sameParent) {
      NodeLocation location = zipper.getBreadcrumbs().get(0).getLocation();
      Integer ixDiff = indexCorrection.getOrDefault(location.getName(), 0);
      int ix = location.getIndex() + ixDiff;
      String name = location.getName();
      List<T> childList = new ArrayList<>(childrenMap.get(name));
      switch (zipper.getModificationType()) {
        case REPLACE:
          childList.set(ix, zipper.getCurNode());
          break;
        case DELETE:
          childList.remove(ix);
          indexCorrection.put(name, ixDiff - 1);
          break;
        case INSERT_BEFORE:
          childList.add(ix, zipper.getCurNode());
          indexCorrection.put(name, ixDiff + 1);
          break;
        case INSERT_AFTER:
          childList.add(ix + 1, zipper.getCurNode());
          indexCorrection.put(name, ixDiff + 1);
          break;
      }
      childrenMap.put(name, childList);
    }

    T newNode = nodeAdapter.withNewChildren(parent, childrenMap);
    List<Breadcrumb<T>> newBreadcrumbs = sameParent.get(0).getBreadcrumbs().subList(1, sameParent.get(0).getBreadcrumbs().size());
    return new NodeZipper<>(newNode, newBreadcrumbs, this.nodeAdapter);
  }