[Pkg-javascript-commits] [node-acorn-jsx] 182/484: Support rest parameters
Bastien Roucariès
rouca at moszumanska.debian.org
Sat Aug 19 14:20:23 UTC 2017
This is an automated email from the git hooks/post-receive script.
rouca pushed a commit to branch master
in repository node-acorn-jsx.
commit 5552e866f99a83ca05a9cd7ba654c25ecc7475be
Author: Brandon Mills <mills.brandont at gmail.com>
Date: Wed Nov 13 14:25:38 2013 -0500
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.
---
acorn.js | 37 +++++--
test/tests.js | 323 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 350 insertions(+), 10 deletions(-)
diff --git a/acorn.js b/acorn.js
index 31935f4..d84e3b3 100644
--- a/acorn.js
+++ b/acorn.js
@@ -308,7 +308,7 @@
var _bracketL = {type: "[", beforeExpr: true}, _bracketR = {type: "]"}, _braceL = {type: "{", beforeExpr: true};
var _braceR = {type: "}"}, _parenL = {type: "(", beforeExpr: true}, _parenR = {type: ")"};
var _comma = {type: ",", beforeExpr: true}, _semi = {type: ";", beforeExpr: true};
- var _colon = {type: ":", beforeExpr: true}, _dot = {type: "."}, _question = {type: "?", beforeExpr: true};
+ var _colon = {type: ":", beforeExpr: true}, _dot = {type: "."}, _ellipsis = {type: "..."}, _question = {type: "?", beforeExpr: true};
// Operators. These carry several kinds of properties to help the
// parser use them properly (the presence of these properties is
@@ -345,8 +345,8 @@
exports.tokTypes = {bracketL: _bracketL, bracketR: _bracketR, braceL: _braceL, braceR: _braceR,
parenL: _parenL, parenR: _parenR, comma: _comma, semi: _semi, colon: _colon,
- dot: _dot, question: _question, slash: _slash, eq: _eq, name: _name, eof: _eof,
- num: _num, regexp: _regexp, string: _string};
+ dot: _dot, ellipsis: _ellipsis, question: _question, slash: _slash, eq: _eq,
+ name: _name, eof: _eof, num: _num, regexp: _regexp, string: _string};
for (var kw in keywordTypes) exports.tokTypes["_" + kw] = keywordTypes[kw];
// This is a trick taken from Esprima. It turns out that, on
@@ -582,8 +582,14 @@
function readToken_dot() {
var next = input.charCodeAt(tokPos + 1);
if (next >= 48 && next <= 57) return readNumber(true);
- ++tokPos;
- return finishToken(_dot);
+ var next2 = input.charCodeAt(tokPos + 2);
+ if (options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.'
+ tokPos += 3;
+ return finishToken(_ellipsis);
+ } else {
+ ++tokPos;
+ return finishToken(_dot);
+ }
}
function readToken_slash() { // '/'
@@ -659,7 +665,7 @@
function getTokenFromCode(code) {
switch(code) {
// The interpretation of a dot depends on whether it is followed
- // by a digit.
+ // by a digit or another two dots.
case 46: // '.'
return readToken_dot();
@@ -1706,11 +1712,22 @@
else if (isStatement) unexpected();
else node.id = null;
node.params = [];
- var first = true;
+ node.rest = null;
expect(_parenL);
- while (!eat(_parenR)) {
- if (!first) expect(_comma); else first = false;
- node.params.push(parseIdent());
+ for (;;) {
+ if (eat(_parenR)) {
+ break;
+ } else if (options.ecmaVersion >= 6 && eat(_ellipsis)) {
+ node.rest = parseIdent();
+ expect(_parenR);
+ break;
+ } else {
+ node.params.push(parseIdent());
+ if (!eat(_comma)) {
+ expect(_parenR);
+ break;
+ }
+ }
}
// Start a new scope with regard to labels and the `inFunction`
diff --git a/test/tests.js b/test/tests.js
index 9cb0432..4bc5b4d 100644
--- a/test/tests.js
+++ b/test/tests.js
@@ -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)");
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-acorn-jsx.git
More information about the Pkg-javascript-commits
mailing list