function isReturningJSX(context, ASTnode, strict, ignoreNull) {
  const isJSXValue = (node) => {
    if (!node) {
      return false;
    }
    switch (node.type) {
      case 'ConditionalExpression':
        if (strict) {
          return isJSXValue(node.consequent) && isJSXValue(node.alternate);
        }
        return isJSXValue(node.consequent) || isJSXValue(node.alternate);
      case 'LogicalExpression':
        if (strict) {
          return isJSXValue(node.left) && isJSXValue(node.right);
        }
        return isJSXValue(node.left) || isJSXValue(node.right);
      case 'SequenceExpression':
        return isJSXValue(node.expressions[node.expressions.length - 1]);
      case 'JSXElement':
      case 'JSXFragment':
        return true;
      case 'CallExpression':
        return isCreateElement(context, node);
      case 'Literal':
        if (!ignoreNull && node.value === null) {
          return true;
        }
        return false;
      case 'Identifier': {
        const variable = variableUtil.findVariableByName(context, node, node.name);
        return isJSX(variable);
      }
      default:
        return false;
    }
  };

  let found = false;
  astUtil.traverseReturns(ASTnode, context, (node, breakTraverse) => {
    if (isJSXValue(node)) {
      found = true;
      breakTraverse();
    }
  });

  return found;
}
Check if the node is returning JSX or null

@param {Context} context The context of `ASTNode`.
@param {ASTNode} ASTnode The AST node being checked
@param {boolean} [strict] If true, in a ternary condition the node must return JSX in both cases
@param {boolean} [ignoreNull] If true, null return values will be ignored
@returns {boolean} True if the node is returning JSX or null, false if not