1. /**
    
  2.  * Copyright (c) Meta Platforms, Inc. and affiliates.
    
  3.  *
    
  4.  * This source code is licensed under the MIT license found in the
    
  5.  * LICENSE file in the root directory of this source tree.
    
  6.  */
    
  7. 'use strict';
    
  8. 
    
  9. function evalStringConcat(ast) {
    
  10.   switch (ast.type) {
    
  11.     case 'StringLiteral':
    
  12.     case 'Literal': // ESLint
    
  13.       return ast.value;
    
  14.     case 'BinaryExpression': // `+`
    
  15.       if (ast.operator !== '+') {
    
  16.         throw new Error('Unsupported binary operator ' + ast.operator);
    
  17.       }
    
  18.       return evalStringConcat(ast.left) + evalStringConcat(ast.right);
    
  19.     default:
    
  20.       throw new Error('Unsupported type ' + ast.type);
    
  21.   }
    
  22. }
    
  23. exports.evalStringConcat = evalStringConcat;
    
  24. 
    
  25. function evalStringAndTemplateConcat(ast, args) {
    
  26.   switch (ast.type) {
    
  27.     case 'StringLiteral':
    
  28.       return ast.value;
    
  29.     case 'BinaryExpression': // `+`
    
  30.       if (ast.operator !== '+') {
    
  31.         throw new Error('Unsupported binary operator ' + ast.operator);
    
  32.       }
    
  33.       return (
    
  34.         evalStringAndTemplateConcat(ast.left, args) +
    
  35.         evalStringAndTemplateConcat(ast.right, args)
    
  36.       );
    
  37.     case 'TemplateLiteral': {
    
  38.       let elements = [];
    
  39.       for (let i = 0; i < ast.quasis.length; i++) {
    
  40.         const elementNode = ast.quasis[i];
    
  41.         if (elementNode.type !== 'TemplateElement') {
    
  42.           throw new Error('Unsupported type ' + ast.type);
    
  43.         }
    
  44.         elements.push(elementNode.value.cooked);
    
  45.       }
    
  46.       args.push(...ast.expressions);
    
  47.       return elements.join('%s');
    
  48.     }
    
  49.     default:
    
  50.       // Anything that's not a string is interpreted as an argument.
    
  51.       args.push(ast);
    
  52.       return '%s';
    
  53.   }
    
  54. }
    
  55. exports.evalStringAndTemplateConcat = evalStringAndTemplateConcat;