support trailing commas in function parameter lists and calls (#2156)

fixes #2155
This commit is contained in:
Alex Lam S.L
2017-06-24 17:34:14 +08:00
committed by GitHub
parent d1f085bce7
commit 94f93ad82d
4 changed files with 91 additions and 25 deletions

View File

@@ -856,6 +856,7 @@ function parse($TEXT, options) {
options = defaults(options, {
bare_returns : false,
ecma : 8,
expression : false,
filename : null,
html5_comments : true,
@@ -1386,22 +1387,20 @@ function parse($TEXT, options) {
function parameters() {
var start = S.token;
var first = true;
var params = [];
var used_parameters = track_used_binding_identifiers(true, S.input.has_directive("use strict"));
expect("(");
while (!is("punc", ")")) {
if (first) {
first = false;
} else {
expect(",");
}
var param = parameter(used_parameters);
params.push(param);
if (!is("punc", ")")) {
expect(",");
if (is("punc", ")") && options.ecma < 8) unexpected();
}
if (param instanceof AST_Expansion) {
break;
}
@@ -1617,25 +1616,40 @@ function parse($TEXT, options) {
}
}
function params_or_seq_() {
var first = true;
function params_or_seq_(allow_arrows, maybe_sequence) {
var spread_token;
var invalid_sequence;
var trailing_comma;
var a = [];
expect("(");
while (!is("punc", ")")) {
if (first) first = false; else expect(",");
if (spread_token) unexpected(spread_token);
if (is("expand", "...")) {
var spread_token = S.token;
spread_token = S.token;
if (maybe_sequence) invalid_sequence = S.token;
next();
a.push(new AST_Expansion({
start: prev(),
expression: expression(),
end: S.token,
}));
if (!is("punc", ")")) {
unexpected(spread_token);
}
} else {
a.push(expression());
}
if (!is("punc", ")")) {
expect(",");
if (is("punc", ")")) {
if (options.ecma < 8) unexpected();
trailing_comma = prev();
if (maybe_sequence) invalid_sequence = trailing_comma;
}
}
}
expect(")");
if (allow_arrows && is("arrow", "=>")) {
if (spread_token && trailing_comma) unexpected(trailing_comma);
} else if (invalid_sequence) {
unexpected(invalid_sequence);
}
return a;
}
@@ -1883,7 +1897,7 @@ function parse($TEXT, options) {
var newexp = expr_atom(false), args;
if (is("punc", "(")) {
next();
args = expr_list(")");
args = expr_list(")", options.ecma >= 8);
} else {
args = [];
}
@@ -2000,9 +2014,7 @@ function parse($TEXT, options) {
switch (S.token.value) {
case "(":
if (async && !allow_calls) break;
next();
var exprs = params_or_seq_();
expect(")");
var exprs = params_or_seq_(allow_arrows, !async);
if (allow_arrows && is("arrow", "=>")) {
return arrow_function(start, exprs.map(to_fun_args), !!async);
}
@@ -2608,11 +2620,9 @@ function parse($TEXT, options) {
return expr;
};
var call_args = embed_tokens(function call_args() {
var first = true;
var call_args = embed_tokens(function _call_args() {
var args = [];
while (!is("punc", ")")) {
if (first) first = false; else expect(",");
if (is("expand", "...")) {
next();
args.push(new AST_Expansion({
@@ -2622,6 +2632,10 @@ function parse($TEXT, options) {
} else {
args.push(expression(false));
}
if (!is("punc", ")")) {
expect(",");
if (is("punc", ")") && options.ecma < 8) unexpected();
}
}
next();
return args;