You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

102 lines
2.4 KiB

4 years ago
  1. var assert = require('assert');
  2. var recast = require('recast');
  3. var types = recast.types;
  4. var PathVisitor = types.PathVisitor;
  5. var n = types.namedTypes;
  6. var b = types.builders;
  7. function Visitor() {
  8. PathVisitor.apply(this, arguments);
  9. }
  10. Visitor.prototype = Object.create(PathVisitor.prototype);
  11. Visitor.prototype.constructor = Visitor;
  12. /**
  13. * Visits a template literal, replacing it with a series of string
  14. * concatenations. For example, given:
  15. *
  16. * ```js
  17. * `1 + 1 = ${1 + 1}`
  18. * ```
  19. *
  20. * The following output will be generated:
  21. *
  22. * ```js
  23. * "1 + 1 = " + (1 + 1)
  24. * ```
  25. *
  26. * @param {NodePath} path
  27. * @returns {AST.Literal|AST.BinaryExpression}
  28. */
  29. Visitor.prototype.visitTemplateLiteral = function(path) {
  30. var node = path.node;
  31. var replacement = b.literal(node.quasis[0].value.cooked);
  32. for (var i = 1, length = node.quasis.length; i < length; i++) {
  33. replacement = b.binaryExpression(
  34. '+',
  35. b.binaryExpression(
  36. '+',
  37. replacement,
  38. node.expressions[i - 1]
  39. ),
  40. b.literal(node.quasis[i].value.cooked)
  41. );
  42. }
  43. return replacement;
  44. };
  45. /**
  46. * Visits the path wrapping a TaggedTemplateExpression node, which has the form
  47. *
  48. * ```js
  49. * htmlEncode `<span id=${id}>${text}</span>`
  50. * ```
  51. *
  52. * @param {NodePath} path
  53. * @returns {AST.CallExpression}
  54. */
  55. Visitor.prototype.visitTaggedTemplateExpression = function(path) {
  56. var node = path.node;
  57. var args = [];
  58. var strings = b.callExpression(
  59. b.functionExpression(
  60. null,
  61. [],
  62. b.blockStatement([
  63. b.variableDeclaration(
  64. 'var',
  65. [
  66. b.variableDeclarator(
  67. b.identifier('strings'),
  68. b.arrayExpression(node.quasi.quasis.map(function(quasi) {
  69. return b.literal(quasi.value.cooked);
  70. }))
  71. )
  72. ]
  73. ),
  74. b.expressionStatement(b.assignmentExpression(
  75. '=',
  76. b.memberExpression(b.identifier('strings'), b.identifier('raw'), false),
  77. b.arrayExpression(node.quasi.quasis.map(function(quasi) {
  78. return b.literal(quasi.value.raw);
  79. }))
  80. )),
  81. b.returnStatement(b.identifier('strings'))
  82. ])
  83. ),
  84. []
  85. );
  86. args.push(strings);
  87. args.push.apply(args, node.quasi.expressions);
  88. return b.callExpression(
  89. node.tag,
  90. args
  91. );
  92. };
  93. Visitor.visitor = new Visitor();
  94. module.exports = Visitor;