From 91e5ac0fddca6b8ca646a578e44ce16804af6019 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 11 Dec 2014 14:30:24 +0100 Subject: [PATCH] Make loose parser parse template strings --- acorn_loose.js | 44 ++++++++++++++++++++++++++++++++++++++++++++ test/run.js | 1 - 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/acorn_loose.js b/acorn_loose.js index 649aec6241..fe11e5b114 100644 --- a/acorn_loose.js +++ b/acorn_loose.js @@ -100,6 +100,10 @@ var re = input.slice(e.pos, pos); try { re = new RegExp(re); } catch(e) {} replace = {start: e.pos, end: pos, type: tt.regexp, value: re}; + } else if (/template/.test(msg)) { + replace = {start: e.pos, end: pos, + type: input.charAt(e.pos) == "`" ? tt.template : tt.templateContinued, + value: input.slice(e.pos + 1, pos)}; } else { replace = false; } @@ -681,6 +685,11 @@ node.callee = base; node.arguments = parseExprList(tt.parenR); base = finishNode(node, "CallExpression"); + } else if (token.type == tt.template) { + var node = startNodeAt(start); + node.tag = base; + node.quasi = parseTemplate(); + base = finishNode(node, "TaggedTemplateExpression"); } else { return base; } @@ -769,6 +778,9 @@ } return finishNode(node, "YieldExpression"); + case tt.template: + return parseTemplate(); + default: return dummyIdent(); } @@ -788,6 +800,38 @@ return finishNode(node, "NewExpression"); } + function parseTemplateElement() { + var elem = startNode(); + elem.value = token.value; + elem.tail = input.charCodeAt(token.end - 1) !== 123; // '{' + next(); + return finishNode(elem, "TemplateElement"); + } + + function parseTemplate() { + var node = startNode(); + node.expressions = []; + var curElt = parseTemplateElement(); + node.quasis = [curElt]; + while (!curElt.tail) { + var next = parseExpression(); + if (isDummy(next)) { + node.quasis[node.quasis.length - 1].tail = true; + break; + } + node.expressions.push(next); + if (token.type === tt.templateContinued) { + node.quasis.push(curElt = parseTemplateElement()); + } else { + curElt = startNode(); + curElt.value = {cooked: "", raw: ""}; + curElt.tail = true; + node.quasis.push(curElt); + } + } + return finishNode(node, "TemplateLiteral"); + } + function parseObj(isClass, isStatement) { var node = startNode(); if (isClass) { diff --git a/test/run.js b/test/run.js index e896397100..04f752dc3b 100644 --- a/test/run.js +++ b/test/run.js @@ -55,7 +55,6 @@ parse: (typeof require === "undefined" ? window.acorn : require("../acorn_loose")).parse_dammit, loose: true, filter: function (test) { - if (/`/.test(test.code)) return false; // FIXME remove this when the loose parse supports template strings var opts = test.options || {}; if (opts.loose === false) return false; return (opts.ecmaVersion || 5) <= 6;