Java Code Examples for com.google.javascript.rhino.IR#breakNode()

The following examples show how to use com.google.javascript.rhino.IR#breakNode() . 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: FunctionToBlockMutator.java    From astor with GNU General Public License v2.0 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.isFunction()
      || current.isExprResult()) {
    // Don't recurse into functions definitions, and expressions can't
    // contain RETURN nodes.
    return current;
  }

  if (current.isReturn()) {
    Preconditions.checkState(NodeUtil.isStatementBlock(parent));

    Node resultNode = getReplacementReturnStatement(current, resultName);
    Node breakNode = IR.breakNode(IR.labelName(labelName));

    // 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 2
Source File: Closure_132_PeepholeSubstituteAlternateSyntax_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * Replace duplicate exits in control structures.  If the node following
 * the exit node expression has the same effect as exit node, the node can
 * be replaced or removed.
 * For example:
 *   "while (a) {return f()} return f();" ==> "while (a) {break} return f();"
 *   "while (a) {throw 'ow'} throw 'ow';" ==> "while (a) {break} throw 'ow';"
 *
 * @param n An follow control exit expression (a THROW or RETURN node)
 * @return The replacement for n, or the original if no change was made.
 */
private Node tryReplaceExitWithBreak(Node n) {
  Node result = n.getFirstChild();

  // Find the enclosing control structure, if any, that a "break" would exit
  // from.
  Node breakTarget = n;
  for (;!ControlFlowAnalysis.isBreakTarget(breakTarget, null /* no label */);
      breakTarget = breakTarget.getParent()) {
    if (breakTarget.isFunction() || breakTarget.isScript()) {
      // No break target.
      return n;
    }
  }

  Node follow = ControlFlowAnalysis.computeFollowNode(breakTarget);

  // Skip pass all the finally blocks because both the break and return will
  // also trigger all the finally blocks. However, the order of execution is
  // slightly changed. Consider:
  //
  // return a() -> finally { b() } -> return a()
  //
  // which would call a() first. However, changing the first return to a
  // break will result in calling b().

  Node prefinallyFollows = follow;
  follow = skipFinallyNodes(follow);

  if (prefinallyFollows != follow) {
    // There were finally clauses
    if (!isPure(result)) {
      // Can't defer the exit
      return n;
    }
  }

  if (follow == null && (n.isThrow() || result != null)) {
    // Can't complete remove a throw here or a return with a result.
    return n;
  }

  // When follow is null, this mean the follow of a break target is the
  // end of a function. This means a break is same as return.
  if (follow == null || areMatchingExits(n, follow)) {
    Node replacement = IR.breakNode();
    n.getParent().replaceChild(n, replacement);
    this.reportCodeChange();
    return replacement;
  }

  return n;
}
 
Example 3
Source File: Closure_132_PeepholeSubstituteAlternateSyntax_s.java    From coming with MIT License 4 votes vote down vote up
/**
 * Replace duplicate exits in control structures.  If the node following
 * the exit node expression has the same effect as exit node, the node can
 * be replaced or removed.
 * For example:
 *   "while (a) {return f()} return f();" ==> "while (a) {break} return f();"
 *   "while (a) {throw 'ow'} throw 'ow';" ==> "while (a) {break} throw 'ow';"
 *
 * @param n An follow control exit expression (a THROW or RETURN node)
 * @return The replacement for n, or the original if no change was made.
 */
private Node tryReplaceExitWithBreak(Node n) {
  Node result = n.getFirstChild();

  // Find the enclosing control structure, if any, that a "break" would exit
  // from.
  Node breakTarget = n;
  for (;!ControlFlowAnalysis.isBreakTarget(breakTarget, null /* no label */);
      breakTarget = breakTarget.getParent()) {
    if (breakTarget.isFunction() || breakTarget.isScript()) {
      // No break target.
      return n;
    }
  }

  Node follow = ControlFlowAnalysis.computeFollowNode(breakTarget);

  // Skip pass all the finally blocks because both the break and return will
  // also trigger all the finally blocks. However, the order of execution is
  // slightly changed. Consider:
  //
  // return a() -> finally { b() } -> return a()
  //
  // which would call a() first. However, changing the first return to a
  // break will result in calling b().

  Node prefinallyFollows = follow;
  follow = skipFinallyNodes(follow);

  if (prefinallyFollows != follow) {
    // There were finally clauses
    if (!isPure(result)) {
      // Can't defer the exit
      return n;
    }
  }

  if (follow == null && (n.isThrow() || result != null)) {
    // Can't complete remove a throw here or a return with a result.
    return n;
  }

  // When follow is null, this mean the follow of a break target is the
  // end of a function. This means a break is same as return.
  if (follow == null || areMatchingExits(n, follow)) {
    Node replacement = IR.breakNode();
    n.getParent().replaceChild(n, replacement);
    this.reportCodeChange();
    return replacement;
  }

  return n;
}
 
Example 4
Source File: Closure_20_PeepholeSubstituteAlternateSyntax_s.java    From coming with MIT License 4 votes vote down vote up
/**
 * Replace duplicate exits in control structures.  If the node following
 * the exit node expression has the same effect as exit node, the node can
 * be replaced or removed.
 * For example:
 *   "while (a) {return f()} return f();" ==> "while (a) {break} return f();"
 *   "while (a) {throw 'ow'} throw 'ow';" ==> "while (a) {break} throw 'ow';"
 *
 * @param n An follow control exit expression (a THROW or RETURN node)
 * @return The replacement for n, or the original if no change was made.
 */
private Node tryReplaceExitWithBreak(Node n) {
  Node result = n.getFirstChild();

  // Find the enclosing control structure, if any, that a "break" would exit
  // from.
  Node breakTarget = n;
  for (;!ControlFlowAnalysis.isBreakTarget(breakTarget, null /* no label */);
      breakTarget = breakTarget.getParent()) {
    if (breakTarget.isFunction() || breakTarget.isScript()) {
      // No break target.
      return n;
    }
  }

  Node follow = ControlFlowAnalysis.computeFollowNode(breakTarget);

  // Skip pass all the finally blocks because both the break and return will
  // also trigger all the finally blocks. However, the order of execution is
  // slightly changed. Consider:
  //
  // return a() -> finally { b() } -> return a()
  //
  // which would call a() first. However, changing the first return to a
  // break will result in calling b().

  Node prefinallyFollows = follow;
  follow = skipFinallyNodes(follow);

  if (prefinallyFollows != follow) {
    // There were finally clauses
    if (!isPure(result)) {
      // Can't defer the exit
      return n;
    }
  }

  if (follow == null && (n.isThrow() || result != null)) {
    // Can't complete remove a throw here or a return with a result.
    return n;
  }

  // When follow is null, this mean the follow of a break target is the
  // end of a function. This means a break is same as return.
  if (follow == null || areMatchingExits(n, follow)) {
    Node replacement = IR.breakNode();
    n.getParent().replaceChild(n, replacement);
    this.reportCodeChange();
    return replacement;
  }

  return n;
}
 
Example 5
Source File: Closure_20_PeepholeSubstituteAlternateSyntax_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * Replace duplicate exits in control structures.  If the node following
 * the exit node expression has the same effect as exit node, the node can
 * be replaced or removed.
 * For example:
 *   "while (a) {return f()} return f();" ==> "while (a) {break} return f();"
 *   "while (a) {throw 'ow'} throw 'ow';" ==> "while (a) {break} throw 'ow';"
 *
 * @param n An follow control exit expression (a THROW or RETURN node)
 * @return The replacement for n, or the original if no change was made.
 */
private Node tryReplaceExitWithBreak(Node n) {
  Node result = n.getFirstChild();

  // Find the enclosing control structure, if any, that a "break" would exit
  // from.
  Node breakTarget = n;
  for (;!ControlFlowAnalysis.isBreakTarget(breakTarget, null /* no label */);
      breakTarget = breakTarget.getParent()) {
    if (breakTarget.isFunction() || breakTarget.isScript()) {
      // No break target.
      return n;
    }
  }

  Node follow = ControlFlowAnalysis.computeFollowNode(breakTarget);

  // Skip pass all the finally blocks because both the break and return will
  // also trigger all the finally blocks. However, the order of execution is
  // slightly changed. Consider:
  //
  // return a() -> finally { b() } -> return a()
  //
  // which would call a() first. However, changing the first return to a
  // break will result in calling b().

  Node prefinallyFollows = follow;
  follow = skipFinallyNodes(follow);

  if (prefinallyFollows != follow) {
    // There were finally clauses
    if (!isPure(result)) {
      // Can't defer the exit
      return n;
    }
  }

  if (follow == null && (n.isThrow() || result != null)) {
    // Can't complete remove a throw here or a return with a result.
    return n;
  }

  // When follow is null, this mean the follow of a break target is the
  // end of a function. This means a break is same as return.
  if (follow == null || areMatchingExits(n, follow)) {
    Node replacement = IR.breakNode();
    n.getParent().replaceChild(n, replacement);
    this.reportCodeChange();
    return replacement;
  }

  return n;
}
 
Example 6
Source File: PeepholeSubstituteAlternateSyntax.java    From astor with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Replace duplicate exits in control structures.  If the node following
 * the exit node expression has the same effect as exit node, the node can
 * be replaced or removed.
 * For example:
 *   "while (a) {return f()} return f();" ==> "while (a) {break} return f();"
 *   "while (a) {throw 'ow'} throw 'ow';" ==> "while (a) {break} throw 'ow';"
 *
 * @param n An follow control exit expression (a THROW or RETURN node)
 * @return The replacement for n, or the original if no change was made.
 */
private Node tryReplaceExitWithBreak(Node n) {
  Node result = n.getFirstChild();

  // Find the enclosing control structure, if any, that a "break" would exit
  // from.
  Node breakTarget = n;
  for (;!ControlFlowAnalysis.isBreakTarget(breakTarget, null /* no label */);
      breakTarget = breakTarget.getParent()) {
    if (breakTarget.isFunction() || breakTarget.isScript()) {
      // No break target.
      return n;
    }
  }

  Node follow = ControlFlowAnalysis.computeFollowNode(breakTarget);

  // Skip pass all the finally blocks because both the break and return will
  // also trigger all the finally blocks. However, the order of execution is
  // slightly changed. Consider:
  //
  // return a() -> finally { b() } -> return a()
  //
  // which would call a() first. However, changing the first return to a
  // break will result in calling b().

  Node prefinallyFollows = follow;
  follow = skipFinallyNodes(follow);

  if (prefinallyFollows != follow) {
    // There were finally clauses
    if (!isPure(result)) {
      // Can't defer the exit
      return n;
    }
  }

  if (follow == null && (n.isThrow() || result != null)) {
    // Can't complete remove a throw here or a return with a result.
    return n;
  }

  // When follow is null, this mean the follow of a break target is the
  // end of a function. This means a break is same as return.
  if (follow == null || areMatchingExits(n, follow)) {
    Node replacement = IR.breakNode();
    n.getParent().replaceChild(n, replacement);
    this.reportCodeChange();
    return replacement;
  }

  return n;
}