From 9eb65f3af36fd6546f83517f217625fdbaf9d6f1 Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Mon, 7 Dec 2020 02:07:34 +0000 Subject: [PATCH] extend trailing comma support (#4334) --- lib/parse.js | 17 +++++++---------- test/compress/functions.js | 10 ++++++++++ test/ufuzz/index.js | 35 +++++++++++++++++++++-------------- 3 files changed, 38 insertions(+), 24 deletions(-) diff --git a/lib/parse.js b/lib/parse.js index b3c3f977..5a07ef64 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -1053,12 +1053,9 @@ function parse($TEXT, options) { if (name && ctor !== AST_Accessor && !(name instanceof AST_SymbolDeclaration)) unexpected(prev()); expect("("); - var argnames = []; - for (var first = true; !is("punc", ")");) { - if (first) first = false; else expect(","); - argnames.push(maybe_destructured(AST_SymbolFunarg)); - } - next(); + var argnames = expr_list(")", !options.strict, false, function() { + return maybe_destructured(AST_SymbolFunarg); + }); var loop = S.in_loop; var labels = S.labels; ++S.in_function; @@ -1233,7 +1230,7 @@ function parse($TEXT, options) { var newexp = expr_atom(false), args; if (is("punc", "(")) { next(); - args = expr_list(")"); + args = expr_list(")", !options.strict); } else { args = []; } @@ -1351,9 +1348,9 @@ function parse($TEXT, options) { while (!is("punc", closing)) { if (first) first = false; else expect(","); if (allow_trailing_comma && is("punc", closing)) break; - if (is("punc", ",") && allow_empty) { + if (allow_empty && is("punc", ",")) { a.push(new AST_Hole({ start: S.token, end: S.token })); - } else if (is("operator", "...") && parser === expression) { + } else if (parser === expression && is("operator", "...")) { a.push(new AST_Spread({ start: S.token, expression: (next(), parser()), @@ -1593,7 +1590,7 @@ function parse($TEXT, options) { var call = new AST_Call({ start : start, expression : expr, - args : expr_list(")"), + args : expr_list(")", !options.strict), end : prev() }); mark_pure(call); diff --git a/test/compress/functions.js b/test/compress/functions.js index 49bbfac9..1e7d3e2f 100644 --- a/test/compress/functions.js +++ b/test/compress/functions.js @@ -5213,3 +5213,13 @@ issue_4265: { } expect_stdout: "undefined" } + +trailing_comma: { + input: { + new function(a, b,) { + console.log(b, a,); + }(42, "PASS",); + } + expect_exact: 'new function(a,b){console.log(b,a)}(42,"PASS");' + expect_stdout: "PASS 42" +} diff --git a/test/ufuzz/index.js b/test/ufuzz/index.js index e47e5410..2d2956b4 100644 --- a/test/ufuzz/index.js +++ b/test/ufuzz/index.js @@ -362,6 +362,10 @@ function createFunctions(n, recurmax, allowDefun, canThrow, stmtDepth) { return s; } +function addTrailingComma(list) { + return list && rng(20) == 0 ? list + "," : list; +} + function createParams(noDuplicate) { var len = unique_vars.length; var params = []; @@ -371,7 +375,7 @@ function createParams(noDuplicate) { params.push(name); } unique_vars.length = len; - return params.join(", "); + return addTrailingComma(params.join(", ")); } function createArgs(recurmax, stmtDepth, canThrow) { @@ -394,7 +398,7 @@ function createArgs(recurmax, stmtDepth, canThrow) { args.push(rng(2) ? createValue() : createExpression(recurmax, COMMA_OK, stmtDepth, canThrow)); break; } - return args.join(", "); + return addTrailingComma(args.join(", ")); } function createAssignmentPairs(recurmax, noComma, stmtDepth, canThrow, varNames, was_async) { @@ -463,7 +467,10 @@ function createAssignmentPairs(recurmax, noComma, stmtDepth, canThrow, varNames, while (!rng(10)) { var index = rng(pairs.names.length + 1); pairs.names.splice(index, 0, ""); - pairs.values.splice(index, 0, rng(2) ? createAssignmentValue(recurmax) : ""); + if (rng(2)) { + if (index > pairs.values.length) pairs.values.length = index; + pairs.values.splice(index, 0, createAssignmentValue(recurmax)); + } } names.unshift("[ " + pairs.names.join(", ") + " ]"); values.unshift("[ " + pairs.values.join(", ") + " ]"); @@ -485,14 +492,14 @@ function createAssignmentPairs(recurmax, noComma, stmtDepth, canThrow, varNames, keys[index] = key; } }); - names.unshift("{ " + pairs.names.map(function(name, index) { + names.unshift("{ " + addTrailingComma(pairs.names.map(function(name, index) { var key = index in keys ? keys[index] : rng(10) && createKey(recurmax, keys); return key ? key + ": " + name : name; - }).join(", ") + " }"); - values.unshift("{ " + pairs.values.map(function(value, index) { + }).join(", ")) + " }"); + values.unshift("{ " + addTrailingComma(pairs.values.map(function(value, index) { var key = index in keys ? keys[index] : createKey(recurmax, keys); return key + ": " + value; - }).join(", ") + " }"); + }).join(", ")) + " }"); } break; default: @@ -603,8 +610,8 @@ function createFunction(recurmax, allowDefun, canThrow, stmtDepth) { if ((!allowDefun || !(name in called)) && rng(2)) { called[name] = false; var pairs = createAssignmentPairs(recurmax, COMMA_OK, stmtDepth, canThrow, varNames, save_async); - params = pairs.names.join(", "); - args = pairs.values.join(", "); + params = addTrailingComma(pairs.names.join(", ")); + args = addTrailingComma(pairs.values.join(", ")); } else { params = createParams(); } @@ -968,7 +975,7 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) { createBlockVariables(recurmax, stmtDepth, canThrow, function(defns) { var instantiate = rng(4) ? "new " : ""; s.push( - instantiate + "function " + name + "(){", + instantiate + "function " + name + "(" + createParams() + "){", strictMode(), defns() ); @@ -976,11 +983,11 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) { if (rng(2)) s.push("this." + getDotKey(true) + createAssignment() + _createBinaryExpr(recurmax, noComma, stmtDepth, canThrow) + ";"); else s.push("this[" + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + "]" + createAssignment() + _createBinaryExpr(recurmax, noComma, stmtDepth, canThrow) + ";"); } - s.push( - _createStatements(rng(5) + 1, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth), - rng(2) == 0 ? "}" : "}()" - ); + s.push(_createStatements(rng(5) + 1, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth)); }); + async = save_async; + VAR_NAMES.length = nameLenBefore; + s.push(rng(2) == 0 ? "}" : "}(" + createArgs(recurmax, stmtDepth, canThrow) + ")"); break; } async = save_async; -- 2.34.1