diff options
Diffstat (limited to 'lib/parse.js')
-rw-r--r-- | lib/parse.js | 98 |
1 files changed, 49 insertions, 49 deletions
diff --git a/lib/parse.js b/lib/parse.js index eb2dc01a..a80fcaf9 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -1818,10 +1818,7 @@ function parse($TEXT, options) { if (is("punc")) { switch (start.value) { case "`": - var tmpl = template(null); - tmpl.start = start; - tmpl.end = prev(); - return subscripts(tmpl, allow_calls); + return subscripts(template(null), allow_calls); case "(": next(); if (is("punc", ")")) { @@ -2230,6 +2227,7 @@ function parse($TEXT, options) { } function template(tag) { + var start = tag ? tag.start : S.token; var read = S.input.context().read_template; var strings = []; var expressions = []; @@ -2240,58 +2238,60 @@ function parse($TEXT, options) { } next(); return new AST_Template({ + start: start, expressions: expressions, strings: strings, tag: tag, + end: prev(), }); } - var subscripts = function(expr, allow_calls, optional) { + function subscripts(expr, allow_calls) { var start = expr.start; - if (is("punc", "[")) { - next(); - var prop = expression(); - expect("]"); - return subscripts(new AST_Sub({ - start: start, - optional: optional, - expression: expr, - property: prop, - end: prev(), - }), allow_calls); - } - if (allow_calls && is("punc", "(")) { - next(); - var call = new AST_Call({ - start: start, - optional: optional, - expression: expr, - args: expr_list(")", !options.strict), - end: prev(), - }); - return subscripts(call, true); - } - if (optional || is("punc", ".")) { - if (!optional) next(); - return subscripts(new AST_Dot({ - start: start, - optional: optional, - expression: expr, - property: as_name(), - end: prev(), - }), allow_calls); - } - if (is("punc", "`")) { - var tmpl = template(expr); - tmpl.start = expr.start; - tmpl.end = prev(); - return subscripts(tmpl, allow_calls); - } - if (is("operator", "?") && is_token(peek(), "punc", ".")) { - next(); - next(); - return subscripts(expr, allow_calls, true); + var optional = null; + while (true) { + if (is("operator", "?") && is_token(peek(), "punc", ".")) { + next(); + next(); + optional = expr; + } + if (is("punc", "[")) { + next(); + var prop = expression(); + expect("]"); + expr = new AST_Sub({ + start: start, + optional: optional === expr, + expression: expr, + property: prop, + end: prev(), + }); + } else if (allow_calls && is("punc", "(")) { + next(); + expr = new AST_Call({ + start: start, + optional: optional === expr, + expression: expr, + args: expr_list(")", !options.strict), + end: prev(), + }); + } else if (optional === expr || is("punc", ".")) { + if (optional !== expr) next(); + expr = new AST_Dot({ + start: start, + optional: optional === expr, + expression: expr, + property: as_name(), + end: prev(), + }); + } else if (is("punc", "`")) { + if (optional) croak("Invalid template on optional chain"); + expr = template(expr); + } else { + break; + } } + if (optional) expr.terminal = true; if (expr instanceof AST_Call && !expr.pure) { var start = expr.start; var comments = start.comments_before; @@ -2305,7 +2305,7 @@ function parse($TEXT, options) { } } return expr; - }; + } function maybe_unary(no_in) { var start = S.token; |