[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