From 09229db7940a264da267d2b08e5670cad48d8ed0 Mon Sep 17 00:00:00 2001 From: Justin Ridgewell Date: Fri, 19 May 2017 14:57:15 -0400 Subject: [PATCH] Cleanup template-literals transform (#5748) Avoid `Array#shift`s and prefer `const`s when possible. --- .../src/index.js | 76 ++++++++----------- 1 file changed, 32 insertions(+), 44 deletions(-) diff --git a/packages/babel-plugin-transform-es2015-template-literals/src/index.js b/packages/babel-plugin-transform-es2015-template-literals/src/index.js index 128172fdb2..12554e9027 100644 --- a/packages/babel-plugin-transform-es2015-template-literals/src/index.js +++ b/packages/babel-plugin-transform-es2015-template-literals/src/index.js @@ -1,82 +1,70 @@ export default function ({ types: t }) { - function isString(node) { - return t.isLiteral(node) && typeof node.value === "string"; - } - - function buildBinaryExpression(left, right) { - return t.binaryExpression("+", left, right); - } - return { visitor: { TaggedTemplateExpression(path, state) { const { node } = path; - const quasi = node.quasi; - let args = []; + const { quasi } = node; - let strings = []; - let raw = []; + const strings = []; + const raws = []; for (const elem of (quasi.quasis: Array)) { - const value = elem.value.cooked == null + const { raw, cooked } = elem.value; + const value = cooked == null ? path.scope.buildUndefinedNode() - : t.stringLiteral(elem.value.cooked); - strings.push(value); - raw.push(t.stringLiteral(elem.value.raw)); - } + : t.stringLiteral(cooked); - strings = t.arrayExpression(strings); - raw = t.arrayExpression(raw); + strings.push(value); + raws.push(t.stringLiteral(raw)); + } let templateName = "taggedTemplateLiteral"; if (state.opts.loose) templateName += "Loose"; - const templateObject = state.file.addTemplateObject(templateName, strings, raw); - args.push(templateObject); + const templateObject = state.file.addTemplateObject( + templateName, + t.arrayExpression(strings), + t.arrayExpression(raws) + ); - args = args.concat(quasi.expressions); + const args = [templateObject].concat(quasi.expressions); path.replaceWith(t.callExpression(node.tag, args)); }, TemplateLiteral(path, state) { - let nodes: Array = []; - + const nodes = []; const expressions = path.get("expressions"); + let index = 0; for (const elem of (path.node.quasis: Array)) { - nodes.push(t.stringLiteral(elem.value.cooked)); + if (elem.value.cooked) { + nodes.push(t.stringLiteral(elem.value.cooked)); + } - const expr = expressions.shift(); - if (expr) { + if (index < expressions.length) { + const expr = expressions[index++]; + const node = expr.node; if (state.opts.spec && !expr.isBaseType("string") && !expr.isBaseType("number")) { - nodes.push(t.callExpression(t.identifier("String"), [expr.node])); - } else { - nodes.push(expr.node); + nodes.push(t.callExpression(t.identifier("String"), [node])); + } else if (!t.isStringLiteral(node, { value: "" })) { + nodes.push(node); } } } - // filter out empty string literals - nodes = nodes.filter((n) => !t.isLiteral(n, { value: "" })); - // since `+` is left-to-right associative // ensure the first node is a string if first/second isn't - if (!isString(nodes[0]) && !isString(nodes[1])) { + if (!t.isStringLiteral(nodes[0]) && !t.isStringLiteral(nodes[1])) { nodes.unshift(t.stringLiteral("")); } - if (nodes.length > 1) { - let root = buildBinaryExpression(nodes.shift(), nodes.shift()); - - for (const node of nodes) { - root = buildBinaryExpression(root, node); - } - - path.replaceWith(root); - } else { - path.replaceWith(nodes[0]); + let root = nodes[0]; + for (let i = 1; i < nodes.length; i++) { + root = t.binaryExpression("+", root, nodes[i]); } + + path.replaceWith(root); }, }, };