src/com/google/javascript/jscomp/NodeUtil.java
/**
   * Safely remove children while maintaining a valid node structure.
   * In some cases, this is done by removing the parent from the AST as well.
   */
Safely remove children while maintaining a valid node structure.
In some cases, this is done by removing the parent from the AST as well.
Safely remove children while maintaining a valid node structure . In some cases this is done by removing the parent from the AST as well .
public static void removeChild(Node parent, Node node) {
    if (isTryFinallyNode(parent, node)) {
      if (NodeUtil.hasCatchHandler(getCatchBlock(parent))) {
        parent.removeChild(node);
      } else {
        node.detachChildren();
      }
    } else if (node.isCatch()) {
      Node tryNode = node.getGrandparent();
      checkState(NodeUtil.hasFinally(tryNode));
      node.detach();
    } else if (isTryCatchNodeContainer(node)) {
      Node tryNode = node.getParent();
      checkState(NodeUtil.hasFinally(tryNode));
      node.detachChildren();
    } else if (node.isBlock()) {
      node.detachChildren();
    } else if (isStatementBlock(parent)
        || isSwitchCase(node)
        || node.isMemberFunctionDef()) {
      parent.removeChild(node);
    } else if (isNameDeclaration(parent) || parent.isExprResult()) {
      if (parent.hasMoreThanOneChild()) {
        parent.removeChild(node);
      } else {
        parent.removeChild(node);
        removeChild(parent.getParent(), parent);
      }
    } else if (parent.isLabel()
        && node == parent.getLastChild()) {
      parent.removeChild(node);
      removeChild(parent.getParent(), parent);
    } else if (parent.isVanillaFor()) {
      parent.replaceChild(node, IR.empty());
    } else if (parent.isObjectPattern()) {
      parent.removeChild(node);
    } else if (parent.isArrayPattern()) {
      if (node == parent.getLastChild()) {
        parent.removeChild(node);
      } else {
        parent.replaceChild(node, IR.empty());
      }
    } else if (parent.isDestructuringLhs()) {
      parent.removeChild(node);
      if (parent.getParent().hasChildren()) {
        removeChild(parent.getParent(), parent);
      }
    } else if (parent.isRest()) {
      parent.detach();
    } else if (parent.isParamList()) {
      parent.removeChild(node);
    } else if (parent.isImport()) {
      if (node == parent.getFirstChild()) {
        parent.replaceChild(node, IR.empty());
      } else {
        throw new IllegalStateException("Invalid attempt to remove: " + node + " from " + parent);
      }
    } else {
      throw new IllegalStateException("Invalid attempt to remove node: " + node + " of " + parent);
    }
  }
public static void removeChild ( Node parent , Node node ) { if ( isTryFinallyNode ( parent , node ) ) { if ( NodeUtil . hasCatchHandler ( getCatchBlock ( parent ) ) ) { parent . removeChild ( node ) ; } else { node . detachChildren ( ) ; } } else if ( node . isCatch ( ) ) { Node tryNode = node . getGrandparent ( ) ; checkState ( NodeUtil . hasFinally ( tryNode ) ) ; node . detach ( ) ; } else if ( isTryCatchNodeContainer ( node ) ) { Node tryNode = node . getParent ( ) ; checkState ( NodeUtil . hasFinally ( tryNode ) ) ; node . detachChildren ( ) ; } else if ( node . isBlock ( ) ) { node . detachChildren ( ) ; } else if ( isStatementBlock ( parent ) || isSwitchCase ( node ) || node . isMemberFunctionDef ( ) ) { parent . removeChild ( node ) ; } else if ( isNameDeclaration ( parent ) || parent . isExprResult ( ) ) { if ( parent . hasMoreThanOneChild ( ) ) { parent . removeChild ( node ) ; } else { parent . removeChild ( node ) ; removeChild ( parent . getParent ( ) , parent ) ; } } else if ( parent . isLabel ( ) && node == parent . getLastChild ( ) ) { parent . removeChild ( node ) ; removeChild ( parent . getParent ( ) , parent ) ; } else if ( parent . isVanillaFor ( ) ) { parent . replaceChild ( node , IR . empty ( ) ) ; } else if ( parent . isObjectPattern ( ) ) { parent . removeChild ( node ) ; } else if ( parent . isArrayPattern ( ) ) { if ( node == parent . getLastChild ( ) ) { parent . removeChild ( node ) ; } else { parent . replaceChild ( node , IR . empty ( ) ) ; } } else if ( parent . isDestructuringLhs ( ) ) { parent . removeChild ( node ) ; if ( parent . getParent ( ) . hasChildren ( ) ) { removeChild ( parent . getParent ( ) , parent ) ; } } else if ( parent . isRest ( ) ) { parent . detach ( ) ; } else if ( parent . isParamList ( ) ) { parent . removeChild ( node ) ; } else if ( parent . isImport ( ) ) { if ( node == parent . getFirstChild ( ) ) { parent . replaceChild ( node , IR . empty ( ) ) ; } else { throw new IllegalStateException ( "Invalid attempt to remove: " + node + " from " + parent ) ; } } else { throw new IllegalStateException ( "Invalid attempt to remove node: " + node + " of " + parent ) ; } }
Safely remove children while maintaining a valid node structure.
Safely remove children while maintaining a valid node structure .
// A finally can only be removed if there is a catch. // Otherwise, only its children can be removed. // The CATCH can can only be removed if there is a finally clause. // The container node itself can't be removed, but the contained CATCH // can if there is a 'finally' clause // Simply empty the block.  This maintains source location and // "synthetic"-ness. // A statement in a block or a member function can simply be removed // Remove the node from the parent, so it can be reused. // This would leave an empty VAR, remove the VAR itself. // Remove the node from the parent, so it can be reused. // A LABEL without children can not be referred to, remove it. // Only Token.FOR can have an Token.EMPTY other control structure // need something for the condition. Others need to be replaced // or the structure removed. // Remove the name from the object pattern // Destructuring is empty so we should remove the node // removing the destructuring could leave an empty variable declaration node, so we would // want to remove it from the AST // Rest params can only ever have one child node // An import node must always have three child nodes. Only the first can be safely removed.