code: @Override
    public boolean shouldTraverse(NodeTraversal nodeTraversal, Node n, Node parent) {
      // We automatically traverse a hoisted function body when that function
      // is first referenced, so that the reference lists are in the right order.
      //
      // TODO(nicksantos): Maybe generalize this to a continuation mechanism
      // like in RemoveUnusedCode.
      if (NodeUtil.isHoistedFunctionDeclaration(n)) {
        Node nameNode = n.getFirstChild();
        Var functionVar = nodeTraversal.getScope().getVar(nameNode.getString());
        checkNotNull(functionVar);
        if (finishedFunctionTraverse.contains(functionVar)) {
          return false;
        }
        startedFunctionTraverse.add(functionVar);
      }
  
      // If node is a new basic block, put on basic block stack
      if (isBlockBoundary(n, parent)) {
        blockStack.add(new BasicBlock(peek(blockStack), n));
      }
  
      // Add the second x before the first one in "let [x] = x;". VariableReferenceCheck
      // relies on reference order to give a warning.
      if ((n.isDefaultValue() || n.isDestructuringLhs()) && n.hasTwoChildren()) {
        Scope scope = nodeTraversal.getScope();
        nodeTraversal.traverseInnerNode(n.getSecondChild(), n, scope);
        nodeTraversal.traverseInnerNode(n.getFirstChild(), n, scope);
        return false;
      }
      return true;
    }
docs: Updates block stack.