aboutsummaryrefslogtreecommitdiff
path: root/lib/parse.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/parse.js')
-rw-r--r--lib/parse.js98
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;