diff --git a/acorn.js b/acorn.js index 9201398d6f..ad2f60905a 100644 --- a/acorn.js +++ b/acorn.js @@ -1741,8 +1741,17 @@ // are not repeated, and it does not try to bind the words `eval` // or `arguments`. if (strict || node.body.body.length && isUseStrict(node.body.body[0])) { - for (var i = node.id ? -1 : 0; i < node.params.length; ++i) { - var id = i < 0 ? node.id : node.params[i]; + // Negative indices are used to reuse loop body for node.rest and node.id + for (var i = -2, id; i < node.params.length; ++i) { + if (i >= 0) { + id = node.params[i]; + } else if (i == -2) { + if (node.rest) id = node.rest; + else continue; + } else { + if (node.id) id = node.id; + else continue; + } if (isStrictReservedWord(id.name) || isStrictBadIdWord(id.name)) raise(id.start, "Defining '" + id.name + "' in strict mode"); if (i >= 0) for (var j = 0; j < i; ++j) if (id.name === node.params[j].name) diff --git a/index.html b/index.html index f336e3c3af..1f74c47c59 100644 --- a/index.html +++ b/index.html @@ -473,7 +473,7 @@ number, or float.

often referred to. finishOp simply skips the amount of characters it is given as second argument, and returns a token of the type given by its first argument.

    case 47: // '/'
-      return readToken_slash(code);
+      return readToken_slash();
 
     case 37: case 42: // '%*'
       return readToken_mult_modulo();
@@ -1308,9 +1308,16 @@ flag (restore them to their old value afterwards).

node.body = parseBlock(true); inFunction = oldInFunc; labels = oldLabels;

If this is a strict mode function, verify that argument names are not repeated, and it does not try to bind the words eval -or arguments.

    if (strict || node.body.body.length && isUseStrict(node.body.body[0])) {
-      for (var i = node.id ? -1 : 0; i < node.params.length; ++i) {
-        var id = i < 0 ? node.id : node.params[i];
+or arguments.

    if (strict || node.body.body.length && isUseStrict(node.body.body[0])) {

Negative indices are used to reuse loop body for node.rest and node.id

      for (var i = -2, id; i < node.params.length; ++i) {
+        if (i >= 0) {
+          id = node.params[i];
+        } else if (i == -2) {
+          if (node.rest) id = node.rest;
+          else continue;
+        } else {
+          if (node.id) id = node.id;
+          else continue;
+        }
         if (isStrictReservedWord(id.name) || isStrictBadIdWord(id.name))
           raise(id.start, "Defining '" + id.name + "' in strict mode");
         if (i >= 0) for (var j = 0; j < i; ++j) if (id.name === node.params[j].name)
@@ -1319,7 +1326,7 @@ or arguments.

} return finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression"); - }

Parses a comma-separated list of expressions, and returns them as + }

Parses a comma-separated list of expressions, and returns them as an array. close is the token type that ends the list, and allowEmpty can be turned on to allow subsequent commas with nothing in between them to be parsed as null (which is needed @@ -1335,7 +1342,7 @@ for array literals).

else elts.push(parseExpression(true)); } return elts; - }

Parse the next token as an identifier. If liberal is true (used + }

Parse the next token as an identifier. If liberal is true (used when parsing properties), it will also convert keywords into identifiers.

  function parseIdent(liberal) {
     var node = startNode();