expand parameters
Conflicts: test/compress/harmony.js
This commit is contained in:
committed by
Richard van Velzen
parent
e8664e63ef
commit
9863f0efa3
26
lib/ast.js
26
lib/ast.js
@@ -363,10 +363,27 @@ var AST_Toplevel = DEFNODE("Toplevel", "globals", {
|
||||
}
|
||||
}, AST_Scope);
|
||||
|
||||
// TODO besides parameters and function calls, expansions can go in
|
||||
// arrays, array destructuring parameters, and array destructuring
|
||||
// assignment. But I'm not adding this right now because I'm trying
|
||||
// to do the most minimal and independent changesets.
|
||||
var AST_Expansion = DEFNODE("AST_Expansion", "symbol", {
|
||||
$documentation: "An expandible argument, such as ...rest",
|
||||
$propdoc: {
|
||||
symbol: "AST_SymbolFunarg the name of the argument as a SymbolFunarg"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
var self = this;
|
||||
return visitor._visit(this, function(){
|
||||
self.symbol.walk(visitor);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
var AST_ArrowParametersOrSeq = DEFNODE("ArrowParametersOrSeq", "expressions", {
|
||||
$documentation: "A set of arrow function parameters or a sequence expression. This is used because when the parser sees a \"(\" it could be the start of a seq, or the start of a parameter list of an arrow function.",
|
||||
$propdoc: {
|
||||
expressions: "[AST_Expression|AST_Destructuring*] array of expressions or argument names or destructurings."
|
||||
expressions: "[AST_Expression|AST_Destructuring|AST_Expansion*] array of expressions or argument names or destructurings."
|
||||
},
|
||||
as_params: function (croak) {
|
||||
// We don't want anything which doesn't belong in a destructuring
|
||||
@@ -398,6 +415,8 @@ var AST_ArrowParametersOrSeq = DEFNODE("ArrowParametersOrSeq", "expressions", {
|
||||
start: ex.start,
|
||||
end: ex.end
|
||||
});
|
||||
} else if (ex instanceof AST_Expansion) {
|
||||
return ex;
|
||||
} else if (ex instanceof AST_Array) {
|
||||
if (ex.elements.length === 0)
|
||||
croak("Invalid destructuring function parameter", ex.start.line, ex.start.col);
|
||||
@@ -421,7 +440,7 @@ var AST_Lambda = DEFNODE("Lambda", "name argnames uses_arguments", {
|
||||
$documentation: "Base class for functions",
|
||||
$propdoc: {
|
||||
name: "[AST_SymbolDeclaration?] the name of this function",
|
||||
argnames: "[AST_SymbolFunarg|AST_Destructuring*] array of function arguments or destructurings",
|
||||
argnames: "[AST_SymbolFunarg|AST_Destructuring|AST_Expansion*] array of function arguments, destructurings, or expanding arguments",
|
||||
uses_arguments: "[boolean/S] tells whether this function accesses the arguments array"
|
||||
},
|
||||
args_as_names: function () {
|
||||
@@ -431,6 +450,9 @@ var AST_Lambda = DEFNODE("Lambda", "name argnames uses_arguments", {
|
||||
if (parm instanceof AST_SymbolFunarg) {
|
||||
out.push(parm);
|
||||
}
|
||||
if (parm instanceof AST_Expansion) {
|
||||
out.push(parm.symbol);
|
||||
}
|
||||
}));
|
||||
return out;
|
||||
},
|
||||
|
||||
@@ -1107,6 +1107,9 @@ merge(Compressor.prototype, {
|
||||
break;
|
||||
} else {
|
||||
var sym = a[i];
|
||||
if (sym instanceof AST_Expansion) {
|
||||
sym = sym.symbol;
|
||||
}
|
||||
if (sym.unreferenced()) {
|
||||
a.pop();
|
||||
compressor.warn("Dropping unused function argument {name} [{file}:{line},{col}]", {
|
||||
|
||||
@@ -607,6 +607,11 @@ function OutputStream(options) {
|
||||
output.semicolon();
|
||||
});
|
||||
|
||||
DEFPRINT(AST_Expansion, function (self, output) {
|
||||
output.print('...');
|
||||
self.symbol.print(output);
|
||||
});
|
||||
|
||||
DEFPRINT(AST_Destructuring, function (self, output) {
|
||||
output.print(self.is_array ? "[" : "{");
|
||||
var first = true;
|
||||
|
||||
45
lib/parse.js
45
lib/parse.js
@@ -526,9 +526,16 @@ function tokenizer($TEXT, filename, html5_comments) {
|
||||
|
||||
function handle_dot() {
|
||||
next();
|
||||
return is_digit(peek().charCodeAt(0))
|
||||
? read_num(".")
|
||||
: token("punc", ".");
|
||||
if (is_digit(peek().charCodeAt(0))) {
|
||||
return read_num(".");
|
||||
}
|
||||
if (peek() === ".") {
|
||||
next(); // Consume second dot
|
||||
next(); // Consume third dot
|
||||
return token("expand", "...");
|
||||
}
|
||||
|
||||
return token("punc", ".");
|
||||
};
|
||||
|
||||
function read_word() {
|
||||
@@ -1034,7 +1041,16 @@ function parse($TEXT, options) {
|
||||
S.in_parameters = true;
|
||||
while (!is("punc", ")")) {
|
||||
if (first) first = false; else expect(",");
|
||||
a.push(expression(false));
|
||||
if (is("expand", "...")) {
|
||||
next();
|
||||
a.push(new AST_Expansion({
|
||||
start: prev(),
|
||||
symbol: as_symbol(AST_SymbolFunarg),
|
||||
end: S.token,
|
||||
}));
|
||||
} else {
|
||||
a.push(expression(false));
|
||||
}
|
||||
}
|
||||
S.in_parameters = false;
|
||||
var end = S.token
|
||||
@@ -1475,13 +1491,32 @@ function parse($TEXT, options) {
|
||||
return subscripts(new AST_Call({
|
||||
start : start,
|
||||
expression : expr,
|
||||
args : expr_list(")"),
|
||||
args : call_args(),
|
||||
end : prev()
|
||||
}), true);
|
||||
}
|
||||
return expr;
|
||||
};
|
||||
|
||||
var call_args = embed_tokens(function call_args() {
|
||||
var first = true;
|
||||
var args = [];
|
||||
while (!is("punc", ")")) {
|
||||
if (first) first = false; else expect(",");
|
||||
if (is("expand", "...")) {
|
||||
next();
|
||||
args.push(new AST_Expansion({
|
||||
start: prev(),
|
||||
symbol: as_symbol(AST_SymbolFunarg)
|
||||
}));
|
||||
} else {
|
||||
args.push(expression(false));
|
||||
}
|
||||
}
|
||||
next();
|
||||
return args;
|
||||
});
|
||||
|
||||
var maybe_unary = function(allow_calls) {
|
||||
var start = S.token;
|
||||
if (is("operator") && UNARY_PREFIX(start.value)) {
|
||||
|
||||
17
test/compress/expansions.js
Normal file
17
test/compress/expansions.js
Normal file
@@ -0,0 +1,17 @@
|
||||
|
||||
expand_arguments: {
|
||||
input: {
|
||||
func(a, ...rest);
|
||||
func(...all);
|
||||
}
|
||||
expect_exact: "func(a,...rest);func(...all);"
|
||||
}
|
||||
|
||||
expand_parameters: {
|
||||
input: {
|
||||
(function (a, ...b){});
|
||||
(function (...args){});
|
||||
}
|
||||
expect_exact: "(function(a,...b){});(function(...args){});"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user