Support rest parameters

http://wiki.ecmascript.org/doku.php?id=harmony:rest_parameters
The final parameter to a function is a rest parameter if it is
prefixed by "...". FunctionExpression and FunctionDeclaration
nodes have a new "rest" property that is null if there is no
rest parameter, or contains an Identifer for the parameter.
https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API#Functions

Implemented by adding a new token, `_ellipsis`, which consists of
three dots. Modified the body of parseFunction to allow a single
rest parameter at the end of an argument list. Both the token and
the rest parameter require `options.ecmaVersion` >= 6, otherwise
three dots are tokenized as three dots.
This commit is contained in:
Brandon Mills
2013-11-13 14:25:38 -05:00
committed by Marijn Haverbeke
parent 2de16b8cb0
commit 5552e866f9
2 changed files with 350 additions and 10 deletions

View File

@@ -23572,6 +23572,171 @@ test("function hello(a, b) { sayHi(); }", {
}
});
test("function hello(...rest) { }", {
type: "Program",
body: [
{
type: "FunctionDeclaration",
id: {
type: "Identifier",
name: "hello",
loc: {
start: {
line: 1,
column: 9
},
end: {
line: 1,
column: 14
}
}
},
params: [],
rest: {
type: "Identifier",
name: "rest",
loc: {
start: {
line: 1,
column: 18
},
end: {
line: 1,
column: 22
}
}
},
body: {
type: "BlockStatement",
body: [],
loc: {
start: {
line: 1,
column: 24
},
end: {
line: 1,
column: 27
}
}
},
loc: {
start: {
line: 1,
column: 0
},
end: {
line: 1,
column: 27
}
}
}
],
loc: {
start: {
line: 1,
column: 0
},
end: {
line: 1,
column: 27
}
}
}, {
ecmaVersion: 6,
locations: true
});
test("function hello(a, ...rest) { }", {
type: "Program",
body: [
{
type: "FunctionDeclaration",
id: {
type: "Identifier",
name: "hello",
loc: {
start: {
line: 1,
column: 9
},
end: {
line: 1,
column: 14
}
}
},
params: [
{
type: "Identifier",
name: "a",
loc: {
start: {
line: 1,
column: 15
},
end: {
line: 1,
column: 16
}
}
}
],
rest: {
type: "Identifier",
name: "rest",
loc: {
start: {
line: 1,
column: 21
},
end: {
line: 1,
column: 25
}
}
},
body: {
type: "BlockStatement",
body: [],
loc: {
start: {
line: 1,
column: 27
},
end: {
line: 1,
column: 30
}
}
},
loc: {
start: {
line: 1,
column: 0
},
end: {
line: 1,
column: 30
}
}
}
],
loc: {
start: {
line: 1,
column: 0
},
end: {
line: 1,
column: 30
}
}
}, {
ecmaVersion: 6,
locations: true
});
test("var hi = function() { sayHi() };", {
type: "Program",
body: [
@@ -23702,6 +23867,153 @@ test("var hi = function() { sayHi() };", {
}
});
test("var hi = function (...r) { sayHi() };", {
type: "Program",
body: [
{
type: "VariableDeclaration",
declarations: [
{
type: "VariableDeclarator",
id: {
type: "Identifier",
name: "hi",
loc: {
start: {
line: 1,
column: 4
},
end: {
line: 1,
column: 6
}
}
},
init: {
type: "FunctionExpression",
id: null,
params: [],
rest: {
type: "Identifier",
name: "r",
loc: {
start: {
line: 1,
column: 22
},
end: {
line: 1,
column: 23
}
}
},
body: {
type: "BlockStatement",
body: [
{
type: "ExpressionStatement",
expression: {
type: "CallExpression",
callee: {
type: "Identifier",
name: "sayHi",
loc: {
start: {
line: 1,
column: 27
},
end: {
line: 1,
column: 32
}
}
},
arguments: [],
loc: {
start: {
line: 1,
column: 27
},
end: {
line: 1,
column: 34
}
}
},
loc: {
start: {
line: 1,
column: 27
},
end: {
line: 1,
column: 34
}
}
}
],
loc: {
start: {
line: 1,
column: 25
},
end: {
line: 1,
column: 36
}
}
},
loc: {
start: {
line: 1,
column: 9
},
end: {
line: 1,
column: 36
}
}
},
loc: {
start: {
line: 1,
column: 4
},
end: {
line: 1,
column: 36
}
}
}
],
kind: "var",
loc: {
start: {
line: 1,
column: 0
},
end: {
line: 1,
column: 37
}
}
}
],
loc: {
start: {
line: 1,
column: 0
},
end: {
line: 1,
column: 37
}
}
}, {
ecmaVersion: 6,
locations: true
});
test("var hi = function eval() { };", {
type: "Program",
body: [
@@ -26551,6 +26863,17 @@ testFail("({ get i() { }, get i() { } })",
testFail("({ set i(x) { }, set i(x) { } })",
"Redefinition of property (1:21)");
testFail("function t(...) { }",
"Unexpected token (1:11)");
testFail("function t(...) { }",
"Unexpected token (1:14)",
{ ecmaVersion: 6 });
testFail("function t(...rest, b) { }",
"Unexpected token (1:18)",
{ ecmaVersion: 6 });
testFail("function t(if) { }",
"Unexpected token (1:11)");