private static boolean reorderIf()

in src/org/jetbrains/java/decompiler/modules/decompiler/IfHelper.java [403:609]


  private static boolean reorderIf(IfStatement ifstat) {
    if (ifstat.iftype == IfStatement.IFTYPE_IFELSE) {
      return false;
    }

    boolean ifdirect, elsedirect;
    boolean noifstat = false, noelsestat;
    boolean ifdirectpath = false, elsedirectpath = false;

    Statement parent = ifstat.getParent();
    Statement from = parent.type == StatementType.SEQUENCE ? parent : ifstat;

    Statement next = getNextStatement(from);

    if (ifstat.getIfstat() == null) {
      noifstat = true;

      ifdirect = ifstat.getIfEdge().getType() == EdgeType.FINALLY_EXIT ||
                 MergeHelper.isDirectPath(from, ifstat.getIfEdge().getDestination());
    }
    else {
      List<StatEdge> lstSuccs = ifstat.getIfstat().getAllSuccessorEdges();
      ifdirect = !lstSuccs.isEmpty() && lstSuccs.get(0).getType() == EdgeType.FINALLY_EXIT ||
                 hasDirectEndEdge(ifstat.getIfstat(), from);
    }

    Statement last = parent.type == StatementType.SEQUENCE ? parent.getStats().getLast() : ifstat;
    noelsestat = (last == ifstat);

    elsedirect = !last.getAllSuccessorEdges().isEmpty() && last.getAllSuccessorEdges().get(0).getType() == EdgeType.FINALLY_EXIT ||
                 hasDirectEndEdge(last, from);

    if (!noelsestat && existsPath(ifstat, ifstat.getAllSuccessorEdges().get(0).getDestination())) {
      return false;
    }

    if (!ifdirect && !noifstat) {
      ifdirectpath = existsPath(ifstat, next);
    }

    if (!elsedirect && !noelsestat) {
      SequenceStatement sequence = (SequenceStatement)parent;

      for (int i = sequence.getStats().size() - 1; i >= 0; i--) {
        Statement sttemp = sequence.getStats().get(i);
        if (sttemp == ifstat) {
          break;
        }
        else if (existsPath(sttemp, next)) {
          elsedirectpath = true;
          break;
        }
      }
    }

    if ((ifdirect || ifdirectpath) && (elsedirect || elsedirectpath) && !noifstat && !noelsestat) {  // if - then - else

      SequenceStatement sequence = (SequenceStatement)parent;

      // build and cut the new else statement
      List<Statement> lst = new ArrayList<>();
      for (int i = sequence.getStats().size() - 1; i >= 0; i--) {
        Statement sttemp = sequence.getStats().get(i);
        if (sttemp == ifstat) {
          break;
        }
        else {
          lst.add(0, sttemp);
        }
      }

      Statement stelse;
      if (lst.size() == 1) {
        stelse = lst.get(0);
      }
      else {
        stelse = new SequenceStatement(lst);
        stelse.setAllParent();
      }

      ifstat.removeSuccessor(ifstat.getAllSuccessorEdges().get(0));
      for (Statement st : lst) {
        sequence.getStats().removeWithKey(st.id);
      }

      StatEdge elseedge = new StatEdge(EdgeType.REGULAR, ifstat.getFirst(), stelse);
      ifstat.getFirst().addSuccessor(elseedge);
      ifstat.setElsestat(stelse);
      ifstat.setElseEdge(elseedge);

      ifstat.getStats().addWithKey(stelse, stelse.id);
      stelse.setParent(ifstat);

      //			if(next.type != Statement.TYPE_DUMMYEXIT && (ifdirect || elsedirect)) {
      //	 			StatEdge breakedge = new StatEdge(StatEdge.TYPE_BREAK, ifstat, next);
      //				sequence.addLabeledEdge(breakedge);
      //				ifstat.addSuccessor(breakedge);
      //			}

      ifstat.iftype = IfStatement.IFTYPE_IFELSE;
    }
    else if (ifdirect && (!elsedirect || (noifstat && !noelsestat))) {  // if - then

      // negate the if condition
      IfExprent statexpr = ifstat.getHeadexprent();
      statexpr.setCondition(new FunctionExprent(FunctionExprent.FUNCTION_BOOL_NOT, statexpr.getCondition(), null));

      if (noelsestat) {
        StatEdge ifedge = ifstat.getIfEdge();
        StatEdge elseedge = ifstat.getAllSuccessorEdges().get(0);

        if (noifstat) {
          ifstat.getFirst().removeSuccessor(ifedge);
          ifstat.removeSuccessor(elseedge);

          ifedge.setSource(ifstat);
          elseedge.setSource(ifstat.getFirst());

          ifstat.addSuccessor(ifedge);
          ifstat.getFirst().addSuccessor(elseedge);

          ifstat.setIfEdge(elseedge);
        }
        else {
          Statement ifbranch = ifstat.getIfstat();
          SequenceStatement newseq = new SequenceStatement(Arrays.asList(ifstat, ifbranch));

          ifstat.getFirst().removeSuccessor(ifedge);
          ifstat.getStats().removeWithKey(ifbranch.id);
          ifstat.setIfstat(null);

          ifstat.removeSuccessor(elseedge);
          elseedge.setSource(ifstat.getFirst());
          ifstat.getFirst().addSuccessor(elseedge);

          ifstat.setIfEdge(elseedge);

          ifstat.getParent().replaceStatement(ifstat, newseq);
          newseq.setAllParent();

          ifstat.addSuccessor(new StatEdge(EdgeType.REGULAR, ifstat, ifbranch));
        }
      }
      else {

        SequenceStatement sequence = (SequenceStatement)parent;

        // build and cut the new else statement
        List<Statement> lst = new ArrayList<>();
        for (int i = sequence.getStats().size() - 1; i >= 0; i--) {
          Statement sttemp = sequence.getStats().get(i);
          if (sttemp == ifstat) {
            break;
          }
          else {
            lst.add(0, sttemp);
          }
        }

        Statement stelse;
        if (lst.size() == 1) {
          stelse = lst.get(0);
        }
        else {
          stelse = new SequenceStatement(lst);
          stelse.setAllParent();
        }

        ifstat.removeSuccessor(ifstat.getAllSuccessorEdges().get(0));
        for (Statement st : lst) {
          sequence.getStats().removeWithKey(st.id);
        }

        if (noifstat) {
          StatEdge ifedge = ifstat.getIfEdge();

          ifstat.getFirst().removeSuccessor(ifedge);
          ifedge.setSource(ifstat);
          ifstat.addSuccessor(ifedge);
        }
        else {
          Statement ifbranch = ifstat.getIfstat();

          ifstat.getFirst().removeSuccessor(ifstat.getIfEdge());
          ifstat.getStats().removeWithKey(ifbranch.id);

          ifstat.addSuccessor(new StatEdge(EdgeType.REGULAR, ifstat, ifbranch));

          sequence.getStats().addWithKey(ifbranch, ifbranch.id);
          ifbranch.setParent(sequence);
        }

        StatEdge newifedge = new StatEdge(EdgeType.REGULAR, ifstat.getFirst(), stelse);
        ifstat.getFirst().addSuccessor(newifedge);
        ifstat.setIfstat(stelse);
        ifstat.setIfEdge(newifedge);

        ifstat.getStats().addWithKey(stelse, stelse.id);
        stelse.setParent(ifstat);
      }
    }
    else {
      return false;
    }

    return true;
  }