Parse and output ES6 template strings. Yikes!

This commit is contained in:
Fábio Santos
2015-09-05 22:32:57 +01:00
parent af22b9c657
commit e1cb1a0e3c
4 changed files with 79 additions and 1 deletions

View File

@@ -501,6 +501,22 @@ var AST_Destructuring = DEFNODE("Destructuring", "names is_array", {
}
});
var AST_TemplateString = DEFNODE("TemplateString", "segments", {
$documentation: "A template string literal",
$propdoc: {
segments: "[string|AST_Expression]* One or more segments. They can be the parts that are evaluated, or the raw string parts."
},
_walk: function(visitor) {
return visitor._visit(this, function(){
this.segments.forEach(function(seg, i){
if (i % 2 !== 0) {
seg._walk(visitor);
}
});
});
}
});
/* -----[ JUMPS ]----- */
var AST_Jump = DEFNODE("Jump", null, {

View File

@@ -776,6 +776,20 @@ function OutputStream(options) {
self._do_print(output);
});
DEFPRINT(AST_TemplateString, function(self, output) {
output.print("`");
for (var i = 0; i < self.segments.length; i++) {
if (typeof self.segments[i] !== "string") {
output.print("${");
self.segments[i].print(output);
output.print("}");
} else {
output.print(self.segments[i]);
}
}
output.print("`");
});
AST_Arrow.DEFMETHOD("_do_print", function(output){
var self = this;
var parent = output.parent();

View File

@@ -114,7 +114,7 @@ var WHITESPACE_CHARS = makePredicate(characters(" \u00a0\n\r\t\f\u000b\u200b\u18
var PUNC_BEFORE_EXPRESSION = makePredicate(characters("[{(,.;:"));
var PUNC_CHARS = makePredicate(characters("[]{}(),;:"));
var PUNC_CHARS = makePredicate(characters("[]{}(),;:`"));
var REGEXP_MODIFIERS = makePredicate(characters("gmsiy"));
@@ -595,6 +595,9 @@ function tokenizer($TEXT, filename, html5_comments) {
parse_error("Unexpected character '" + ch + "'");
};
next_token.next = next;
next_token.peek = peek;
next_token.context = function(nc) {
if (nc) S = nc;
return S;
@@ -805,6 +808,7 @@ function parse($TEXT, options) {
});
case "[":
case "(":
case "`":
return simple_statement();
case ";":
next();
@@ -1336,6 +1340,8 @@ function parse($TEXT, options) {
return subscripts(array_(), allow_calls);
case "{":
return subscripts(object_or_object_destructuring_(), allow_calls);
case "`":
return subscripts(template_string(), allow_calls);
}
unexpected();
}
@@ -1352,6 +1358,38 @@ function parse($TEXT, options) {
unexpected();
};
function template_string() {
var tokenizer_S = S.input, start = S.token, segments = [], segment = "", ch;
while ((ch = tokenizer_S.next()) !== "`") {
if (ch === "$" && tokenizer_S.peek() === "{") {
segments.push(segment); segment = "";
tokenizer_S.next();
next();
segments.push(expression());
expect("}");
if (is("punc", "`")) {
break;
}
continue;
}
segment += ch;
if (ch === "\\") {
segment += tokenizer_S.next();
}
}
segments.push(segment);
next();
return new AST_TemplateString({
start: start,
segments: segments,
end: S.token
});
}
function expr_list(closing, allow_trailing_comma, allow_empty) {
var first = true, a = [];
while (!is("punc", closing)) {

View File

@@ -46,6 +46,16 @@ typeof_arrow_functions: {
expect_exact: "\"function\";"
}
template_strings: {
input: {
``;
`xx\`x`;
`${ foo + 2 }`;
` foo ${ bar + `baz ${ qux }` }`;
}
expect_exact: "``;`xx\\`x`;`${foo+2}`;` foo ${bar+`baz ${qux}`}`;";
}
destructuring_arguments: {
input: {
(function ( a ) { });