public Statement visit()

in src/main/java/net/hydromatic/linq4j/expressions/OptimizeVisitor.java [306:363]


  public Statement visit(ConditionalStatement conditionalStatement,
      List<Node> list) {
    // if (false) { <-- remove branch
    // } if (true) { <-- stop here
    // } else if (...)
    // } else {...}
    boolean optimal = true;
    for (int i = 0; i < list.size() - 1 && optimal; i += 2) {
      Boolean always = always((Expression) list.get(i));
      if (always == null) {
        continue;
      }
      if (i == 0 && always) {
        // when the very first test is always true, just return its statement
        return (Statement) list.get(1);
      }
      optimal = false;
    }
    if (optimal) {
      // Nothing to optimize
      return super.visit(conditionalStatement, list);
    }
    List<Node> newList = new ArrayList<Node>(list.size());
    // Iterate over all the tests, except the latest "else"
    for (int i = 0; i < list.size() - 1; i += 2) {
      Expression test = (Expression) list.get(i);
      Node stmt = list.get(i + 1);
      Boolean always = always(test);
      if (always == null) {
        newList.add(test);
        newList.add(stmt);
        continue;
      }
      if (always) {
        // No need to verify other tests
        newList.add(stmt);
        break;
      }
    }
    // We might have dangling "else", however if we have just single item
    // it means we have if (false) else if(false) else if (true) {...} code.
    // Then we just return statement from true branch
    if (list.size() == 1) {
      return (Statement) list.get(0);
    }
    // Add "else" from original list
    if (newList.size() % 2 == 0 && list.size() % 2 == 1) {
      Node elseBlock = list.get(list.size() - 1);
      if (newList.isEmpty()) {
        return (Statement) elseBlock;
      }
      newList.add(elseBlock);
    }
    if (newList.isEmpty()) {
      return EMPTY_STATEMENT;
    }
    return super.visit(conditionalStatement, newList);
  }