function traverseReturns(ASTNode, context, onReturn) {
  const nodeType = ASTNode.type;

  if (nodeType === 'ReturnStatement') {
    onReturn(ASTNode.argument, () => {});
    return;
  }

  if (nodeType === 'ArrowFunctionExpression' && ASTNode.expression) {
    onReturn(ASTNode.body, () => {});
    return;
  }

  /* TODO: properly warn on React.forwardRefs having typo properties
  if (astUtil.isCallExpression(ASTNode)) {
    const callee = ASTNode.callee;
    const pragma = pragmaUtil.getFromContext(context);
    if (
      callee.type === 'MemberExpression'
      && callee.object.type === 'Identifier'
      && callee.object.name === pragma
      && callee.property.type === 'Identifier'
      && callee.property.name === 'forwardRef'
      && ASTNode.arguments.length > 0
    ) {
      return enterFunc(ASTNode.arguments[0]);
    }
    return;
  }
  */

  if (
    nodeType !== 'FunctionExpression'
    && nodeType !== 'FunctionDeclaration'
    && nodeType !== 'ArrowFunctionExpression'
    && nodeType !== 'MethodDefinition'
  ) {
    return;
  }

  traverse(ASTNode.body, {
    enter(node) {
      const breakTraverse = () => {
        this.break();
      };
      switch (node.type) {
        case 'ReturnStatement':
          this.skip();
          onReturn(node.argument, breakTraverse);
          return;
        case 'BlockStatement':
        case 'IfStatement':
        case 'ForStatement':
        case 'WhileStatement':
        case 'SwitchStatement':
        case 'SwitchCase':
          return;
        default:
          this.skip();
      }
    },
  });
}
Helper function for traversing "returns" (return statements or the
returned expression in the case of an arrow function) of a function

@param {ASTNode} ASTNode The AST node being checked
@param {Context} context The context of `ASTNode`.
@param {(returnValue: ASTNode, breakTraverse: () => void) => void} onReturn
  Function to execute for each returnStatement found
@returns {undefined}