function convertToStringArrayNodeIfNeeded()

in packages/babel-plugin-fbt/src/FbtUtil.js [766:840]


function convertToStringArrayNodeIfNeeded(
  moduleName: JSModuleNameType,
  node: $ElementType<
    $PropertyType<BabelNodeCallExpression, 'arguments'>,
    number,
  >,
): BabelNodeArrayExpression {
  let initialElements;
  let didStartWithArray = false;
  switch (node.type) {
    case 'ArrayExpression':
      initialElements = nullthrows(node.elements);
      didStartWithArray = true;
      break;
    case 'CallExpression':
    case 'StringLiteral':
      initialElements = [node];
      break;

    case 'BinaryExpression': {
      initialElements = getBinaryExpressionOperands(moduleName, node);
      break;
    }
    case 'TemplateLiteral': {
      initialElements = convertTemplateLiteralToArrayElements(moduleName, node);
      break;
    }

    default:
      throw errorAt(
        node,
        `Unexpected node type: ${node.type}. ` +
          `${moduleName}()'s first argument should be a string literal, ` +
          `a construct like ${moduleName}.param() or an array of those.`,
      );
  }

  // Let's also convert the 1st level of elements of the array
  // to process nested string concatenations and template literals one last time.
  // We're not making this fully recursive since, from a syntax POV,
  // it wouldn't be elegant to allow developers to nest lots of template literals.
  return arrayExpression(
    initialElements.reduce((elements, element) => {
      if (element == null) {
        return elements;
      }
      if (
        didStartWithArray &&
        (element.type === 'BinaryExpression' ||
          (element.type === 'TemplateLiteral' && element.expressions.length))
      ) {
        throw errorAt(
          element,
          `${moduleName}(array) only supports items that are string literals, ` +
            `template literals without any expressions, or fbt constructs`,
        );
      }
      switch (element.type) {
        case 'BinaryExpression': {
          elements.push(...getBinaryExpressionOperands(moduleName, element));
          break;
        }
        case 'TemplateLiteral': {
          elements.push(
            ...convertTemplateLiteralToArrayElements(moduleName, element),
          );
          break;
        }
        default:
          elements.push(element);
      }
      return elements;
    }, []),
  );
}