Java Code Examples for com.google.javascript.rhino.Token#BREAK

The following examples show how to use com.google.javascript.rhino.Token#BREAK . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: RenameLabels.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Delegate the actual processing of the node to visitLabel and
 * visitBreakOrContinue.
 *
 * {@inheritDoc}
 */
@Override
public void visit(NodeTraversal nodeTraversal, Node node, Node parent) {
  switch (node.getType()) {
    case Token.LABEL:
      visitLabel(node, parent);
      break;

    case Token.BREAK:
    case Token.CONTINUE:
      visitBreakOrContinue(node);
      break;
  }
}
 
Example 2
Source File: Closure_72_RenameLabels_s.java    From coming with MIT License 5 votes vote down vote up
/**
 * Delegate the actual processing of the node to visitLabel and
 * visitBreakOrContinue.
 *
 * {@inheritDoc}
 */
public void visit(NodeTraversal nodeTraversal, Node node, Node parent) {
  switch (node.getType()) {
    case Token.LABEL:
      visitLabel(node, parent);
      break;

    case Token.BREAK:
    case Token.CONTINUE:
      visitBreakOrContinue(node);
      break;
  }
}
 
Example 3
Source File: PeepholeRemoveDeadCode.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
/**
 * @return Whether the node is an obvious control flow exit.
 */
private boolean isExit(Node n) {
  switch (n.getType()) {
    case Token.BREAK:
    case Token.CONTINUE:
    case Token.RETURN:
    case Token.THROW:
      return true;
    default:
      return false;
  }
}
 
Example 4
Source File: Closure_72_FunctionToBlockMutator_t.java    From coming with MIT License 5 votes vote down vote up
/**
 * Replace the 'return' statement with its child expression.
 *   "return foo()" becomes "{foo(); break;}" or
 *      "{resultName = foo(); break;}"
 *   "return" becomes {break;} or "{resultName = void 0;break;}".
 */
private static Node replaceReturnWithBreak(Node current, Node parent,
    String resultName, String labelName) {

  if (current.getType() == Token.FUNCTION
      || current.getType() == Token.EXPR_RESULT) {
    // Don't recurse into functions definitions, and expressions can't
    // contain RETURN nodes.
    return current;
  }

  if (current.getType() == Token.RETURN) {
    Preconditions.checkState(NodeUtil.isStatementBlock(parent));

    Node resultNode = getReplacementReturnStatement(current, resultName);
    Node name = Node.newString(Token.LABEL_NAME, labelName);
    Node breakNode = new Node(Token.BREAK, name);

    // Replace the node in parent, and reset current to the first new child.
    breakNode.copyInformationFromForTree(current);
    parent.replaceChild(current, breakNode);
    if (resultNode != null) {
      resultNode.copyInformationFromForTree(current);
      parent.addChildBefore(resultNode, breakNode);
    }
    current = breakNode;
  } else {
    for (Node c = current.getFirstChild(); c != null; c = c.getNext()) {
      // c may be replaced.
      c = replaceReturnWithBreak(c, current, resultName, labelName);
    }
  }

  return current;
}
 
Example 5
Source File: UnreachableCodeElimination.java    From astor with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Tries to remove n if it is an unconditional branch node (break, continue,
 * or return) and the target of n is the same as the the follow of n.
 * That is, if removing n preserves the control flow. Also if n targets
 * another unconditional branch, this function will recursively try to remove
 * the target branch as well. The reason why we want to cascade this removal
 * is because we only run this pass once. If we have code such as
 *
 * break -> break -> break
 *
 * where all 3 breaks are useless, then the order of removal matters. When we
 * first look at the first break, we see that it branches to the 2nd break.
 * However, if we remove the last break, the 2nd break becomes useless and
 * finally the first break becomes useless as well.
 *
 * @return The target of this jump. If the target is also useless jump,
 *     the target of that useless jump recursively.
 */
@SuppressWarnings("fallthrough")
private Node tryRemoveUnconditionalBranching(Node n) {
  /*
   * For each unconditional branching control flow node, check to see
   * if the ControlFlowAnalysis.computeFollowNode of that node is same as
   * the branching target. If it is, the branch node is safe to be removed.
   *
   * This is not as clever as MinimizeExitPoints because it doesn't do any
   * if-else conversion but it handles more complicated switch statements
   * much more nicely.
   */

  // If n is null the target is the end of the function, nothing to do.
  if (n == null) {
     return n;
  }

  DiGraphNode<Node, Branch> gNode = cfg.getDirectedGraphNode(n);

  if (gNode == null) {
    return n;
  }

  switch (n.getType()) {
    case Token.RETURN:
      if (n.hasChildren()) {
        break;
      }
    case Token.BREAK:
    case Token.CONTINUE:

      // We are looking for a control flow changing statement that always
      // branches to the same node. If after removing it control still
      // branches to the same node, it is safe to remove.
      List<DiGraphEdge<Node,Branch>> outEdges = gNode.getOutEdges();
      if (outEdges.size() == 1 &&
          // If there is a next node, there is no chance this jump is useless.
          (n.getNext() == null || n.getNext().isFunction())) {

        Preconditions.checkState(outEdges.get(0).getValue() == Branch.UNCOND);
        Node fallThrough = computeFollowing(n);
        Node nextCfgNode = outEdges.get(0).getDestination().getValue();
        if (nextCfgNode == fallThrough) {
          removeDeadExprStatementSafely(n);
          return fallThrough;
        }
      }
  }
  return n;
}
 
Example 6
Source File: 1_ControlFlowAnalysis.java    From SimFix with GNU General Public License v2.0 4 votes vote down vote up
@Override
public boolean shouldTraverse(
    NodeTraversal nodeTraversal, Node n, Node parent) {
  astPosition.put(n, astPositionCounter++);

  switch (n.getType()) {
    case Token.FUNCTION:
      if (shouldTraverseFunctions || n == cfg.getEntry().getValue()) {
        exceptionHandler.push(n);
        return true;
      }
      return false;
    case Token.TRY:
      exceptionHandler.push(n);
      return true;
  }

  /*
   * We are going to stop the traversal depending on what the node's parent
   * is.
   *
   * We are only interested in adding edges between nodes that change control
   * flow. The most obvious ones are loops and IF-ELSE's. A statement
   * transfers control to its next sibling.
   *
   * In case of an expression tree, there is no control flow within the tree
   * even when there are short circuited operators and conditionals. When we
   * are doing data flow analysis, we will simply synthesize lattices up the
   * expression tree by finding the meet at each expression node.
   *
   * For example: within a Token.SWITCH, the expression in question does not
   * change the control flow and need not to be considered.
   */
  if (parent != null) {
    switch (parent.getType()) {
      case Token.FOR:
        // Only traverse the body of the for loop.
        return n == parent.getLastChild();

      // Skip the conditions.
      case Token.IF:
      case Token.WHILE:
      case Token.WITH:
        return n != parent.getFirstChild();
      case Token.DO:
        return n != parent.getFirstChild().getNext();
      // Only traverse the body of the cases
      case Token.SWITCH:
      case Token.CASE:
      case Token.CATCH:
      case Token.LABEL:
        return n != parent.getFirstChild();
      case Token.FUNCTION:
        return n == parent.getFirstChild().getNext().getNext();
      case Token.CONTINUE:
      case Token.BREAK:
      case Token.EXPR_RESULT:
      case Token.VAR:
      case Token.RETURN:
      case Token.THROW:
        return false;
      case Token.TRY:
        /* Just before we are about to visit the second child of the TRY node,
         * we know that we will be visiting either the CATCH or the FINALLY.
         * In other words, we know that the post order traversal of the TRY
         * block has been finished, no more exceptions can be caught by the
         * handler at this TRY block and should be taken out of the stack.
         */
        if (n == parent.getFirstChild().getNext()) {
          Preconditions.checkState(exceptionHandler.peek() == parent);
          exceptionHandler.pop();
        }
    }
  }
  return true;
}
 
Example 7
Source File: ControlFlowAnalysis.java    From astor with GNU General Public License v2.0 4 votes vote down vote up
@Override
public boolean shouldTraverse(
    NodeTraversal nodeTraversal, Node n, Node parent) {
  astPosition.put(n, astPositionCounter++);

  switch (n.getType()) {
    case Token.FUNCTION:
      if (shouldTraverseFunctions || n == cfg.getEntry().getValue()) {
        exceptionHandler.push(n);
        return true;
      }
      return false;
    case Token.TRY:
      exceptionHandler.push(n);
      return true;
  }

  /*
   * We are going to stop the traversal depending on what the node's parent
   * is.
   *
   * We are only interested in adding edges between nodes that change control
   * flow. The most obvious ones are loops and IF-ELSE's. A statement
   * transfers control to its next sibling.
   *
   * In case of an expression tree, there is no control flow within the tree
   * even when there are short circuited operators and conditionals. When we
   * are doing data flow analysis, we will simply synthesize lattices up the
   * expression tree by finding the meet at each expression node.
   *
   * For example: within a Token.SWITCH, the expression in question does not
   * change the control flow and need not to be considered.
   */
  if (parent != null) {
    switch (parent.getType()) {
      case Token.FOR:
        // Only traverse the body of the for loop.
        return n == parent.getLastChild();

      // Skip the conditions.
      case Token.IF:
      case Token.WHILE:
      case Token.WITH:
        return n != parent.getFirstChild();
      case Token.DO:
        return n != parent.getFirstChild().getNext();
      // Only traverse the body of the cases
      case Token.SWITCH:
      case Token.CASE:
      case Token.CATCH:
      case Token.LABEL:
        return n != parent.getFirstChild();
      case Token.FUNCTION:
        return n == parent.getFirstChild().getNext().getNext();
      case Token.CONTINUE:
      case Token.BREAK:
      case Token.EXPR_RESULT:
      case Token.VAR:
      case Token.RETURN:
      case Token.THROW:
        return false;
      case Token.TRY:
        /* Just before we are about to visit the second child of the TRY node,
         * we know that we will be visiting either the CATCH or the FINALLY.
         * In other words, we know that the post order traversal of the TRY
         * block has been finished, no more exceptions can be caught by the
         * handler at this TRY block and should be taken out of the stack.
         */
        if (n == parent.getFirstChild().getNext()) {
          Preconditions.checkState(exceptionHandler.peek() == parent);
          exceptionHandler.pop();
        }
    }
  }
  return true;
}
 
Example 8
Source File: ControlFlowAnalysis.java    From astor with GNU General Public License v2.0 4 votes vote down vote up
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
  switch (n.getType()) {
    case Token.IF:
      handleIf(n);
      return;
    case Token.WHILE:
      handleWhile(n);
      return;
    case Token.DO:
      handleDo(n);
      return;
    case Token.FOR:
      handleFor(n);
      return;
    case Token.SWITCH:
      handleSwitch(n);
      return;
    case Token.CASE:
      handleCase(n);
      return;
    case Token.DEFAULT_CASE:
      handleDefault(n);
      return;
    case Token.BLOCK:
    case Token.SCRIPT:
      handleStmtList(n);
      return;
    case Token.FUNCTION:
      handleFunction(n);
      return;
    case Token.EXPR_RESULT:
      handleExpr(n);
      return;
    case Token.THROW:
      handleThrow(n);
      return;
    case Token.TRY:
      handleTry(n);
      return;
    case Token.CATCH:
      handleCatch(n);
      return;
    case Token.BREAK:
      handleBreak(n);
      return;
    case Token.CONTINUE:
      handleContinue(n);
      return;
    case Token.RETURN:
      handleReturn(n);
      return;
    case Token.WITH:
      handleWith(n);
      return;
    case Token.LABEL:
      return;
    default:
      handleStmt(n);
      return;
  }
}
 
Example 9
Source File: Closure_103_ControlFlowAnalysis_t.java    From coming with MIT License 4 votes vote down vote up
@Override
public boolean shouldTraverse(
    NodeTraversal nodeTraversal, Node n, Node parent) {
  astPosition.put(n, astPositionCounter++);

  switch (n.getType()) {
    case Token.FUNCTION:
      if (shouldTraverseFunctions || n == cfg.getEntry().getValue()) {
        exceptionHandler.push(n);
        return true;
      }
      return false;
    case Token.TRY:
      exceptionHandler.push(n);
      return true;
  }

  /*
   * We are going to stop the traversal depending on what the node's parent
   * is.
   *
   * We are only interested in adding edges between nodes that change control
   * flow. The most obvious ones are loops and IF-ELSE's. A statement
   * transfers control to its next sibling.
   *
   * In case of an expression tree, there is no control flow within the tree
   * even when there are short circuited operators and conditionals. When we
   * are doing data flow analysis, we will simply synthesize lattices up the
   * expression tree by finding the meet at each expression node.
   *
   * For example: within a Token.SWITCH, the expression in question does not
   * change the control flow and need not to be considered.
   */
  if (parent != null) {
    switch (parent.getType()) {
      case Token.FOR:
        // Only traverse the body of the for loop.
        return n == parent.getLastChild();

      // Skip the conditions.
      case Token.IF:
      case Token.WHILE:
      case Token.WITH:
        return n != parent.getFirstChild();
      case Token.DO:
        return n != parent.getFirstChild().getNext();
      // Only traverse the body of the cases
      case Token.SWITCH:
      case Token.CASE:
      case Token.CATCH:
      case Token.LABEL:
        return n != parent.getFirstChild();
      case Token.FUNCTION:
        return n == parent.getFirstChild().getNext().getNext();
      case Token.CONTINUE:
      case Token.BREAK:
      case Token.EXPR_RESULT:
      case Token.VAR:
      case Token.RETURN:
      case Token.THROW:
        return false;
      case Token.TRY:
        /* Just before we are about to visit the second child of the TRY node,
         * we know that we will be visiting either the CATCH or the FINALLY.
         * In other words, we know that the post order traversal of the TRY
         * block has been finished, no more exceptions can be caught by the
         * handler at this TRY block and should be taken out of the stack.
         */
        if (n == parent.getFirstChild().getNext()) {
          Preconditions.checkState(exceptionHandler.peek() == parent);
          exceptionHandler.pop();
        }
    }
  }
  return true;
}
 
Example 10
Source File: Closure_103_ControlFlowAnalysis_s.java    From coming with MIT License 4 votes vote down vote up
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
  switch (n.getType()) {
    case Token.IF:
      handleIf(n);
      return;
    case Token.WHILE:
      handleWhile(n);
      return;
    case Token.DO:
      handleDo(n);
      return;
    case Token.FOR:
      handleFor(n);
      return;
    case Token.SWITCH:
      handleSwitch(n);
      return;
    case Token.CASE:
      handleCase(n);
      return;
    case Token.DEFAULT:
      handleDefault(n);
      return;
    case Token.BLOCK:
    case Token.SCRIPT:
      handleStmtList(n);
      return;
    case Token.FUNCTION:
      handleFunction(n);
      return;
    case Token.EXPR_RESULT:
      handleExpr(n);
      return;
    case Token.THROW:
      handleThrow(n);
      return;
    case Token.TRY:
      handleTry(n);
      return;
    case Token.CATCH:
      handleCatch(n);
      return;
    case Token.BREAK:
      handleBreak(n);
      return;
    case Token.CONTINUE:
      handleContinue(n);
      return;
    case Token.RETURN:
      handleReturn(n);
      return;
    case Token.WITH:
      handleWith(n);
      return;
    case Token.LABEL:
      return;
    default:
      handleStmt(n);
      return;
  }
}
 
Example 11
Source File: Closure_103_ControlFlowAnalysis_s.java    From coming with MIT License 4 votes vote down vote up
@Override
public boolean shouldTraverse(
    NodeTraversal nodeTraversal, Node n, Node parent) {
  astPosition.put(n, astPositionCounter++);

  switch (n.getType()) {
    case Token.FUNCTION:
      if (shouldTraverseFunctions || n == cfg.getEntry().getValue()) {
        exceptionHandler.push(n);
        return true;
      }
      return false;
    case Token.TRY:
      exceptionHandler.push(n);
      return true;
  }

  /*
   * We are going to stop the traversal depending on what the node's parent
   * is.
   *
   * We are only interested in adding edges between nodes that change control
   * flow. The most obvious ones are loops and IF-ELSE's. A statement
   * transfers control to its next sibling.
   *
   * In case of an expression tree, there is no control flow within the tree
   * even when there are short circuited operators and conditionals. When we
   * are doing data flow analysis, we will simply synthesize lattices up the
   * expression tree by finding the meet at each expression node.
   *
   * For example: within a Token.SWITCH, the expression in question does not
   * change the control flow and need not to be considered.
   */
  if (parent != null) {
    switch (parent.getType()) {
      case Token.FOR:
        // Only traverse the body of the for loop.
        return n == parent.getLastChild();

      // Skip the conditions.
      case Token.IF:
      case Token.WHILE:
      case Token.WITH:
        return n != parent.getFirstChild();
      case Token.DO:
        return n != parent.getFirstChild().getNext();
      // Only traverse the body of the cases
      case Token.SWITCH:
      case Token.CASE:
      case Token.CATCH:
      case Token.LABEL:
        return n != parent.getFirstChild();
      case Token.FUNCTION:
        return n == parent.getFirstChild().getNext().getNext();
      case Token.CONTINUE:
      case Token.BREAK:
      case Token.EXPR_RESULT:
      case Token.VAR:
      case Token.RETURN:
      case Token.THROW:
        return false;
      case Token.TRY:
        /* Just before we are about to visit the second child of the TRY node,
         * we know that we will be visiting either the CATCH or the FINALLY.
         * In other words, we know that the post order traversal of the TRY
         * block has been finished, no more exceptions can be caught by the
         * handler at this TRY block and should be taken out of the stack.
         */
        if (n == parent.getFirstChild().getNext()) {
          Preconditions.checkState(exceptionHandler.peek() == parent);
          exceptionHandler.pop();
        }
    }
  }
  return true;
}
 
Example 12
Source File: Closure_85_UnreachableCodeElimination_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * Tries to remove n if an unconditional branch node (break, continue or
 * return) if the target of n is the same as the the follow of n. That is, if
 * we remove n, the control flow remains the same. Also if n targets to
 * another unconditional branch, this function will recursively try to remove
 * the target branch as well. The reason why we want to cascade this removal
 * is because we only run this pass once. If we have code such as
 *
 * break -> break -> break
 *
 * where all 3 break's are useless. The order of removal matters. When we
 * first look at the first break, we see that it branches to the 2nd break.
 * However, if we remove the last break, the 2nd break becomes useless and
 * finally the first break becomes useless as well.
 *
 * @return The target of this jump. If the target is also useless jump,
 *     the target of that useless jump recursively.
 */
@SuppressWarnings("fallthrough")
private Node tryRemoveUnconditionalBranching(Node n) {
  /*
   * For each of the unconditional branching control flow node, check to see
   * if the ControlFlowAnalysis.computeFollowNode of that node is same as
   * the branching target. If it is, the branch node is safe to be removed.
   *
   * This is not as clever as MinimizeExitPoints because it doesn't do any
   * if-else conversion but it handles more complicated switch statements
   * much nicer.
   */

  // If n is null the target is the end of the function, nothing to do.
  if (n == null) {
     return n;
  }

  DiGraphNode<Node, Branch> gNode = curCfg.getDirectedGraphNode(n);

  if (gNode == null) {
    return n;
  }

  switch (n.getType()) {
    case Token.RETURN:
      if (n.hasChildren()) {
        break;
      }
    case Token.BREAK:
    case Token.CONTINUE:

      // We are looking for a control flow changing statement that always
      // branches to the same node. If removing it the control flow still
      // branches to that same node. It is safe to remove it.
      List<DiGraphEdge<Node,Branch>> outEdges = gNode.getOutEdges();
      if (outEdges.size() == 1 &&
          // If there is a next node, there is no chance this jump is useless.
          (n.getNext() == null || n.getNext().getType() == Token.FUNCTION)) {

        Preconditions.checkState(outEdges.get(0).getValue() == Branch.UNCOND);
        Node fallThrough = computeFollowing(n);
        Node nextCfgNode = outEdges.get(0).getDestination().getValue();
        if (nextCfgNode == fallThrough) {
          removeDeadExprStatementSafely(n);
          return fallThrough;
        }
      }
  }
  return n;
}
 
Example 13
Source File: Closure_127_UnreachableCodeElimination_s.java    From coming with MIT License 4 votes vote down vote up
/**
 * Tries to remove n if it is an unconditional branch node (break, continue,
 * or return) and the target of n is the same as the the follow of n.
 * That is, if removing n preserves the control flow. Also if n targets
 * another unconditional branch, this function will recursively try to
 * remove the target branch as well. The reason why we want to cascade this
 * removal is because we only run this pass once. If we have code such as
 *
 * break -> break -> break
 *
 * where all 3 breaks are useless, then the order of removal matters. When
 * we first look at the first break, we see that it branches to the 2nd
 * break. However, if we remove the last break, the 2nd break becomes
 * useless and finally the first break becomes useless as well.
 *
 * @returns The target of this jump. If the target is also useless jump,
 *     the target of that useless jump recursively.
 */
@SuppressWarnings("fallthrough")
private void tryRemoveUnconditionalBranching(Node n) {
  /*
   * For each unconditional branching control flow node, check to see
   * if the ControlFlowAnalysis.computeFollowNode of that node is same as
   * the branching target. If it is, the branch node is safe to be removed.
   *
   * This is not as clever as MinimizeExitPoints because it doesn't do any
   * if-else conversion but it handles more complicated switch statements
   * much more nicely.
   */

  // If n is null the target is the end of the function, nothing to do.
  if (n == null) {
     return;
  }

  DiGraphNode<Node, Branch> gNode = cfg.getDirectedGraphNode(n);

  if (gNode == null) {
    return;
  }

  switch (n.getType()) {
    case Token.RETURN:
      if (n.hasChildren()) {
        break;
      }
    case Token.BREAK:
    case Token.CONTINUE:
      // We are looking for a control flow changing statement that always
      // branches to the same node. If after removing it control still
      // branches to the same node, it is safe to remove.
      List<DiGraphEdge<Node, Branch>> outEdges = gNode.getOutEdges();
      if (outEdges.size() == 1 &&
          // If there is a next node, this jump is not useless.
          (n.getNext() == null || n.getNext().isFunction())) {

        Preconditions.checkState(
            outEdges.get(0).getValue() == Branch.UNCOND);
        Node fallThrough = computeFollowing(n);
        Node nextCfgNode = outEdges.get(0).getDestination().getValue();
        if (nextCfgNode == fallThrough) {
          removeNode(n);
        }
      }
  }
}
 
Example 14
Source File: Closure_127_UnreachableCodeElimination_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * Tries to remove n if it is an unconditional branch node (break, continue,
 * or return) and the target of n is the same as the the follow of n.
 * That is, if removing n preserves the control flow. Also if n targets
 * another unconditional branch, this function will recursively try to
 * remove the target branch as well. The reason why we want to cascade this
 * removal is because we only run this pass once. If we have code such as
 *
 * break -> break -> break
 *
 * where all 3 breaks are useless, then the order of removal matters. When
 * we first look at the first break, we see that it branches to the 2nd
 * break. However, if we remove the last break, the 2nd break becomes
 * useless and finally the first break becomes useless as well.
 *
 * @returns The target of this jump. If the target is also useless jump,
 *     the target of that useless jump recursively.
 */
@SuppressWarnings("fallthrough")
private void tryRemoveUnconditionalBranching(Node n) {
  /*
   * For each unconditional branching control flow node, check to see
   * if the ControlFlowAnalysis.computeFollowNode of that node is same as
   * the branching target. If it is, the branch node is safe to be removed.
   *
   * This is not as clever as MinimizeExitPoints because it doesn't do any
   * if-else conversion but it handles more complicated switch statements
   * much more nicely.
   */

  // If n is null the target is the end of the function, nothing to do.
  if (n == null) {
     return;
  }

  DiGraphNode<Node, Branch> gNode = cfg.getDirectedGraphNode(n);

  if (gNode == null) {
    return;
  }

  switch (n.getType()) {
    case Token.RETURN:
      if (n.hasChildren()) {
        break;
      }
    case Token.BREAK:
    case Token.CONTINUE:
      // We are looking for a control flow changing statement that always
      // branches to the same node. If after removing it control still
      // branches to the same node, it is safe to remove.
      List<DiGraphEdge<Node, Branch>> outEdges = gNode.getOutEdges();
      if (outEdges.size() == 1 &&
          // If there is a next node, this jump is not useless.
          (n.getNext() == null || n.getNext().isFunction())) {

        Preconditions.checkState(
            outEdges.get(0).getValue() == Branch.UNCOND);
        Node fallThrough = computeFollowing(n);
        Node nextCfgNode = outEdges.get(0).getDestination().getValue();
        if (nextCfgNode == fallThrough && !inFinally(n.getParent(), n)) {
          removeNode(n);
        }
      }
  }
}
 
Example 15
Source File: Closure_14_ControlFlowAnalysis_s.java    From coming with MIT License 4 votes vote down vote up
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
  switch (n.getType()) {
    case Token.IF:
      handleIf(n);
      return;
    case Token.WHILE:
      handleWhile(n);
      return;
    case Token.DO:
      handleDo(n);
      return;
    case Token.FOR:
      handleFor(n);
      return;
    case Token.SWITCH:
      handleSwitch(n);
      return;
    case Token.CASE:
      handleCase(n);
      return;
    case Token.DEFAULT_CASE:
      handleDefault(n);
      return;
    case Token.BLOCK:
    case Token.SCRIPT:
      handleStmtList(n);
      return;
    case Token.FUNCTION:
      handleFunction(n);
      return;
    case Token.EXPR_RESULT:
      handleExpr(n);
      return;
    case Token.THROW:
      handleThrow(n);
      return;
    case Token.TRY:
      handleTry(n);
      return;
    case Token.CATCH:
      handleCatch(n);
      return;
    case Token.BREAK:
      handleBreak(n);
      return;
    case Token.CONTINUE:
      handleContinue(n);
      return;
    case Token.RETURN:
      handleReturn(n);
      return;
    case Token.WITH:
      handleWith(n);
      return;
    case Token.LABEL:
      return;
    default:
      handleStmt(n);
      return;
  }
}
 
Example 16
Source File: Closure_14_ControlFlowAnalysis_s.java    From coming with MIT License 4 votes vote down vote up
@Override
public boolean shouldTraverse(
    NodeTraversal nodeTraversal, Node n, Node parent) {
  astPosition.put(n, astPositionCounter++);

  switch (n.getType()) {
    case Token.FUNCTION:
      if (shouldTraverseFunctions || n == cfg.getEntry().getValue()) {
        exceptionHandler.push(n);
        return true;
      }
      return false;
    case Token.TRY:
      exceptionHandler.push(n);
      return true;
  }

  /*
   * We are going to stop the traversal depending on what the node's parent
   * is.
   *
   * We are only interested in adding edges between nodes that change control
   * flow. The most obvious ones are loops and IF-ELSE's. A statement
   * transfers control to its next sibling.
   *
   * In case of an expression tree, there is no control flow within the tree
   * even when there are short circuited operators and conditionals. When we
   * are doing data flow analysis, we will simply synthesize lattices up the
   * expression tree by finding the meet at each expression node.
   *
   * For example: within a Token.SWITCH, the expression in question does not
   * change the control flow and need not to be considered.
   */
  if (parent != null) {
    switch (parent.getType()) {
      case Token.FOR:
        // Only traverse the body of the for loop.
        return n == parent.getLastChild();

      // Skip the conditions.
      case Token.IF:
      case Token.WHILE:
      case Token.WITH:
        return n != parent.getFirstChild();
      case Token.DO:
        return n != parent.getFirstChild().getNext();
      // Only traverse the body of the cases
      case Token.SWITCH:
      case Token.CASE:
      case Token.CATCH:
      case Token.LABEL:
        return n != parent.getFirstChild();
      case Token.FUNCTION:
        return n == parent.getFirstChild().getNext().getNext();
      case Token.CONTINUE:
      case Token.BREAK:
      case Token.EXPR_RESULT:
      case Token.VAR:
      case Token.RETURN:
      case Token.THROW:
        return false;
      case Token.TRY:
        /* Just before we are about to visit the second child of the TRY node,
         * we know that we will be visiting either the CATCH or the FINALLY.
         * In other words, we know that the post order traversal of the TRY
         * block has been finished, no more exceptions can be caught by the
         * handler at this TRY block and should be taken out of the stack.
         */
        if (n == parent.getFirstChild().getNext()) {
          Preconditions.checkState(exceptionHandler.peek() == parent);
          exceptionHandler.pop();
        }
    }
  }
  return true;
}
 
Example 17
Source File: Closure_14_ControlFlowAnalysis_t.java    From coming with MIT License 4 votes vote down vote up
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
  switch (n.getType()) {
    case Token.IF:
      handleIf(n);
      return;
    case Token.WHILE:
      handleWhile(n);
      return;
    case Token.DO:
      handleDo(n);
      return;
    case Token.FOR:
      handleFor(n);
      return;
    case Token.SWITCH:
      handleSwitch(n);
      return;
    case Token.CASE:
      handleCase(n);
      return;
    case Token.DEFAULT_CASE:
      handleDefault(n);
      return;
    case Token.BLOCK:
    case Token.SCRIPT:
      handleStmtList(n);
      return;
    case Token.FUNCTION:
      handleFunction(n);
      return;
    case Token.EXPR_RESULT:
      handleExpr(n);
      return;
    case Token.THROW:
      handleThrow(n);
      return;
    case Token.TRY:
      handleTry(n);
      return;
    case Token.CATCH:
      handleCatch(n);
      return;
    case Token.BREAK:
      handleBreak(n);
      return;
    case Token.CONTINUE:
      handleContinue(n);
      return;
    case Token.RETURN:
      handleReturn(n);
      return;
    case Token.WITH:
      handleWith(n);
      return;
    case Token.LABEL:
      return;
    default:
      handleStmt(n);
      return;
  }
}
 
Example 18
Source File: Closure_14_ControlFlowAnalysis_t.java    From coming with MIT License 4 votes vote down vote up
@Override
public boolean shouldTraverse(
    NodeTraversal nodeTraversal, Node n, Node parent) {
  astPosition.put(n, astPositionCounter++);

  switch (n.getType()) {
    case Token.FUNCTION:
      if (shouldTraverseFunctions || n == cfg.getEntry().getValue()) {
        exceptionHandler.push(n);
        return true;
      }
      return false;
    case Token.TRY:
      exceptionHandler.push(n);
      return true;
  }

  /*
   * We are going to stop the traversal depending on what the node's parent
   * is.
   *
   * We are only interested in adding edges between nodes that change control
   * flow. The most obvious ones are loops and IF-ELSE's. A statement
   * transfers control to its next sibling.
   *
   * In case of an expression tree, there is no control flow within the tree
   * even when there are short circuited operators and conditionals. When we
   * are doing data flow analysis, we will simply synthesize lattices up the
   * expression tree by finding the meet at each expression node.
   *
   * For example: within a Token.SWITCH, the expression in question does not
   * change the control flow and need not to be considered.
   */
  if (parent != null) {
    switch (parent.getType()) {
      case Token.FOR:
        // Only traverse the body of the for loop.
        return n == parent.getLastChild();

      // Skip the conditions.
      case Token.IF:
      case Token.WHILE:
      case Token.WITH:
        return n != parent.getFirstChild();
      case Token.DO:
        return n != parent.getFirstChild().getNext();
      // Only traverse the body of the cases
      case Token.SWITCH:
      case Token.CASE:
      case Token.CATCH:
      case Token.LABEL:
        return n != parent.getFirstChild();
      case Token.FUNCTION:
        return n == parent.getFirstChild().getNext().getNext();
      case Token.CONTINUE:
      case Token.BREAK:
      case Token.EXPR_RESULT:
      case Token.VAR:
      case Token.RETURN:
      case Token.THROW:
        return false;
      case Token.TRY:
        /* Just before we are about to visit the second child of the TRY node,
         * we know that we will be visiting either the CATCH or the FINALLY.
         * In other words, we know that the post order traversal of the TRY
         * block has been finished, no more exceptions can be caught by the
         * handler at this TRY block and should be taken out of the stack.
         */
        if (n == parent.getFirstChild().getNext()) {
          Preconditions.checkState(exceptionHandler.peek() == parent);
          exceptionHandler.pop();
        }
    }
  }
  return true;
}
 
Example 19
Source File: 1_ControlFlowAnalysis.java    From SimFix with GNU General Public License v2.0 4 votes vote down vote up
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
  switch (n.getType()) {
    case Token.IF:
      handleIf(n);
      return;
    case Token.WHILE:
      handleWhile(n);
      return;
    case Token.DO:
      handleDo(n);
      return;
    case Token.FOR:
      handleFor(n);
      return;
    case Token.SWITCH:
      handleSwitch(n);
      return;
    case Token.CASE:
      handleCase(n);
      return;
    case Token.DEFAULT_CASE:
      handleDefault(n);
      return;
    case Token.BLOCK:
    case Token.SCRIPT:
      handleStmtList(n);
      return;
    case Token.FUNCTION:
      handleFunction(n);
      return;
    case Token.EXPR_RESULT:
      handleExpr(n);
      return;
    case Token.THROW:
      handleThrow(n);
      return;
    case Token.TRY:
      handleTry(n);
      return;
    case Token.CATCH:
      handleCatch(n);
      return;
    case Token.BREAK:
      handleBreak(n);
      return;
    case Token.CONTINUE:
      handleContinue(n);
      return;
    case Token.RETURN:
      handleReturn(n);
      return;
    case Token.WITH:
      handleWith(n);
      return;
    case Token.LABEL:
      return;
    default:
      handleStmt(n);
      return;
  }
}
 
Example 20
Source File: 1_ControlFlowAnalysis.java    From SimFix with GNU General Public License v2.0 4 votes vote down vote up
@Override
public boolean shouldTraverse(
    NodeTraversal nodeTraversal, Node n, Node parent) {
  astPosition.put(n, astPositionCounter++);

  switch (n.getType()) {
    case Token.FUNCTION:
      if (shouldTraverseFunctions || n == cfg.getEntry().getValue()) {
        exceptionHandler.push(n);
        return true;
      }
      return false;
    case Token.TRY:
      exceptionHandler.push(n);
      return true;
  }

  /*
   * We are going to stop the traversal depending on what the node's parent
   * is.
   *
   * We are only interested in adding edges between nodes that change control
   * flow. The most obvious ones are loops and IF-ELSE's. A statement
   * transfers control to its next sibling.
   *
   * In case of an expression tree, there is no control flow within the tree
   * even when there are short circuited operators and conditionals. When we
   * are doing data flow analysis, we will simply synthesize lattices up the
   * expression tree by finding the meet at each expression node.
   *
   * For example: within a Token.SWITCH, the expression in question does not
   * change the control flow and need not to be considered.
   */
  if (parent != null) {
    switch (parent.getType()) {
      case Token.FOR:
        // Only traverse the body of the for loop.
        return n == parent.getLastChild();

      // Skip the conditions.
      case Token.IF:
      case Token.WHILE:
      case Token.WITH:
        return n != parent.getFirstChild();
      case Token.DO:
        return n != parent.getFirstChild().getNext();
      // Only traverse the body of the cases
      case Token.SWITCH:
      case Token.CASE:
      case Token.CATCH:
      case Token.LABEL:
        return n != parent.getFirstChild();
      case Token.FUNCTION:
        return n == parent.getFirstChild().getNext().getNext();
      case Token.CONTINUE:
      case Token.BREAK:
      case Token.EXPR_RESULT:
      case Token.VAR:
      case Token.RETURN:
      case Token.THROW:
        return false;
      case Token.TRY:
        /* Just before we are about to visit the second child of the TRY node,
         * we know that we will be visiting either the CATCH or the FINALLY.
         * In other words, we know that the post order traversal of the TRY
         * block has been finished, no more exceptions can be caught by the
         * handler at this TRY block and should be taken out of the stack.
         */
        if (n == parent.getFirstChild().getNext()) {
          Preconditions.checkState(exceptionHandler.peek() == parent);
          exceptionHandler.pop();
        }
    }
  }
  return true;
}