third_party/closure-compiler/src/src/com/google/javascript/jscomp/PeepholeFoldConstants.java
/**
   * Try to fold a AND/OR node.
   */
Try to fold a AND/OR node.
Try to fold a AND / OR node .
private Node tryFoldAndOr(Node n, Node left, Node right) {
    Node parent = n.getParent();
    Node result = null;
    Node dropped = null;
    Token type = n.getToken();
    TernaryValue leftVal = NodeUtil.getBooleanValue(left);
    if (leftVal != TernaryValue.UNKNOWN) {
      boolean lval = leftVal.toBoolean(true);
      if ((lval && type == Token.OR) || (!lval && type == Token.AND)) {
        result = left;
        dropped = right;
      } else if (!mayHaveSideEffects(left)) {
        result = right;
        dropped = left;
      } else {
        n.detachChildren();
        result = IR.comma(left, right);
        dropped = null;
      }
    } else if (parent.getToken() == type && n == parent.getFirstChild()) {
      TernaryValue rightValue = NodeUtil.getBooleanValue(right);
      if (!mayHaveSideEffects(right)) {
        if ((rightValue == TernaryValue.FALSE && type == Token.OR)
            || (rightValue == TernaryValue.TRUE && type == Token.AND)) {
          result = left;
          dropped = right;
        }
      }
    }
    if (result != null) {
      n.detachChildren();
      parent.replaceChild(n, result);
      reportChangeToEnclosingScope(result);
      if (dropped != null) {
        markFunctionsDeleted(dropped);
      }
      return result;
    } else {
      return n;
    }
  }
private Node tryFoldAndOr ( Node n , Node left , Node right ) { Node parent = n . getParent ( ) ; Node result = null ; Node dropped = null ; Token type = n . getToken ( ) ; TernaryValue leftVal = NodeUtil . getBooleanValue ( left ) ; if ( leftVal != TernaryValue . UNKNOWN ) { boolean lval = leftVal . toBoolean ( true ) ; if ( ( lval && type == Token . OR ) || ( ! lval && type == Token . AND ) ) { result = left ; dropped = right ; } else if ( ! mayHaveSideEffects ( left ) ) { result = right ; dropped = left ; } else { n . detachChildren ( ) ; result = IR . comma ( left , right ) ; dropped = null ; } } else if ( parent . getToken ( ) == type && n == parent . getFirstChild ( ) ) { TernaryValue rightValue = NodeUtil . getBooleanValue ( right ) ; if ( ! mayHaveSideEffects ( right ) ) { if ( ( rightValue == TernaryValue . FALSE && type == Token . OR ) || ( rightValue == TernaryValue . TRUE && type == Token . AND ) ) { result = left ; dropped = right ; } } } if ( result != null ) { n . detachChildren ( ) ; parent . replaceChild ( n , result ) ; reportChangeToEnclosingScope ( result ) ; if ( dropped != null ) { markFunctionsDeleted ( dropped ) ; } return result ; } else { return n ; } }
Try to fold a AND/OR node.
Try to fold a AND / OR node .
// (TRUE || x) => TRUE (also, (3 || x) => 3) // (FALSE && x) => FALSE // (FALSE || x) => x // (TRUE && x) => x // Left side may have side effects, but we know its boolean value. // e.g. true_with_sideeffects || foo() => true_with_sideeffects, foo() // or: false_with_sideeffects && foo() => false_with_sideeffects, foo() // This, combined with PeepholeRemoveDeadCode, helps reduce expressions // like "x() || false || z()". // Note: Right hand side folding is handled by // PeepholeMinimizeConditions#tryMinimizeCondition // Fold it!