code: private static Node replaceReturns(
        Node block, String resultName, String labelName,
        boolean resultMustBeSet) {
      checkNotNull(block);
      checkNotNull(labelName);
  
      Node root = block;
  
      boolean hasReturnAtExit = false;
      int returnCount = NodeUtil.getNodeTypeReferenceCount(
          block, Token.RETURN, new NodeUtil.MatchShallowStatement());
      if (returnCount > 0) {
        hasReturnAtExit = hasReturnAtExit(block);
        // TODO(johnlenz): Simpler not to special case this,
        // and let it be optimized later.
        if (hasReturnAtExit) {
          convertLastReturnToStatement(block, resultName);
          returnCount--;
        }
  
        if (returnCount > 0) {
          // A label and breaks are needed.
  
          // Add the breaks
          replaceReturnWithBreak(block, null, resultName, labelName);
  
          // Add label
          Node name = IR.labelName(labelName).srcref(block);
          Node label = IR.label(name, block).srcref(block);
  
          Node newRoot = IR.block().srcref(block);
          newRoot.addChildToBack(label);
  
  
          // The label is now the root.
          root = newRoot;
        }
      }
  
      // If there wasn't an return at the end of the function block, and we need
      // a result, add one to the block.
      if (resultMustBeSet && !hasReturnAtExit && resultName != null) {
        addDummyAssignment(block, resultName);
      }
  
      return root;
    }
docs: Convert returns to assignments and breaks, as needed.
  For example, with a labelName of 'foo':
  {
  return a;
  }
  becomes:
  foo: {
  a;
  break foo;
  }
  or
  foo: {
  resultName = a;
  break foo;
  }
  
  @param resultMustBeSet Whether the result must always be set to a value.
  @return The node containing the transformed block, this may be different
  than the passed in node 'block'.