docs: function isControlTransfer(stmt, path, control = "break") {
      const { [control]: type } = {
        break: "BreakStatement",
        continue: "ContinueStatement"
      };
      if (!type) {
        throw new Error("Can only handle break and continue statements");
      }
      const checker = `is${type}`;
  
      if (stmt[checker]()) {
        return _isControlTransfer(stmt, path);
      }
  
      let isTransferred = false;
      let result = {
        [control]: false,
        bail: false
      };
  
      stmt.traverse({
        [type](cPath) {
          // if we already detected a break/continue statement,
          if (isTransferred) return;
  
          result = _isControlTransfer(cPath, path);
  
          if (result.bail || result[control]) {
            isTransferred = true;
          }
        }
      });
  
      return result;
  
      function _isControlTransfer(cPath, path) {
        const label = cPath.get("label");
  
        if (label.node !== null) {
          // labels are fn scoped and not accessible by inner functions
          // path is the switch statement
          if (!isSameFunctionScope(path, cPath)) {
            // we don't have to worry about this break statement
            return {
              break: false,
              bail: false
            };
          }
  
          // here we handle the break labels
          // if they are outside switch, we bail out
          // if they are within the case, we keep them
          let labelPath;
          if (path.scope.getLabel) {
            labelPath = getLabel(label.node.name, path);
          } else {
            labelPath = path.scope.getBinding(label.node.name).path;
          }
          const _isAncestor = isAncestor(labelPath, path);
  
          return {
            bail: _isAncestor,
            [control]: _isAncestor
          };
        }
  
        // set the flag that it is indeed breaking
        let isCTransfer = true;
  
        // this flag is to capture
        // switch(0) { case 0: while(1) if (x) break; }
        let possibleRunTimeControlTransfer = false;
  
        // and compute if it's breaking the correct thing
        let parent = cPath.parentPath;
  
        while (parent !== stmt.parentPath) {
          // loops and nested switch cases
          if (parent.isLoop() || parent.isSwitchCase()) {
            // invalidate all the possible runtime breaks captured
            // while (1) { if (x) break; }
            possibleRunTimeControlTransfer = false;
  
            // and set that it's not breaking our switch statement
            isCTransfer = false;
            break;
          }
          //
          // this is a special case and depends on
          // the fact that SwitchStatement is handled in the
          // exit hook of the traverse
          //
          // switch (0) {
          //   case 0: if (x) break;
          // }
          //
          // here `x` is runtime only.
          // in this case, we need to bail out. So we depend on exit hook
          // of switch so that, it would have visited the IfStatement first
          // before the SwitchStatement and would have removed the
          // IfStatement if it was a compile time determined
          //
          if (parent.isIfStatement()) {
            possibleRunTimeControlTransfer = true;
          }
          parent = parent.parentPath;
        }
  
        return {
          [control]: possibleRunTimeControlTransfer || isCTransfer,
          bail: possibleRunTimeControlTransfer
        };
      }
    }