[Pkg-javascript-commits] [node-acorn-jsx] 224/484: Recursive destructuring assignment with function arguments name clash checks.

Bastien Roucariès rouca at moszumanska.debian.org
Sat Aug 19 14:20:33 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 50a82135c49c4b59f20c42b81194f1b270e5e171
Author: Ingvar Stepanyan <me at rreverser.com>
Date:   Fri Jul 25 01:58:40 2014 +0300

    Recursive destructuring assignment with function arguments name clash checks.
---
 acorn.js              | 97 +++++++++++++++++++++++++++++++--------------------
 test/tests-harmony.js | 70 ++++++++++++++++++-------------------
 2 files changed, 94 insertions(+), 73 deletions(-)

diff --git a/acorn.js b/acorn.js
index c95d6d0..423d2b4 100644
--- a/acorn.js
+++ b/acorn.js
@@ -1876,29 +1876,22 @@
 
     var defaults = node.defaults, hasDefaults = false;
     
-    for (var i = 0; i < params.length; i++) {
-        var param = params[i];
+    for (var i = 0, lastI = params.length - 1; i <= lastI; i++) {
+      var param = params[i];
 
-        switch (param.type) {
-        case "Identifier":
-          defaults.push(null);
-          break;
-
-        case "AssignmentExpression":
-          defaults.push(param.right);
-          hasDefaults = true;
-          params[i] = param.left;
+      if (param.type === "AssignmentExpression") {
+        hasDefaults = true;
+        params[i] = param.left;
+        defaults.push(param.right);
+      } else {
+        toAssignable(param, i === lastI);
+        defaults.push(null);
+        if (param.type === "SpreadElement") {
+          params.length--;
+          node.rest = param.argument;
           break;
-
-        case "SpreadElement":
-          if (i === --params.length) {
-            node.rest = param.argument;
-            break;
-          }
-
-        default:
-          unexpected(param.start);
         }
+      }
     }
 
     node.params = params;
@@ -1960,22 +1953,38 @@
     // are not repeated, and it does not try to bind the words `eval`
     // or `arguments`.
     if (strict || !isExpression && 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)
-          raise(id.start, "Argument name clash in strict mode");
-      }
+      var nameHash = {};
+      if (node.id)
+        checkFunctionParam(node.id, nameHash);
+      for (var i = 0; i < node.params.length; i++)
+        checkFunctionParam(node.params[i], nameHash);
+      if (node.rest)
+        checkFunctionParam(node.rest, nameHash);
+    }
+  }
+
+  // Verify that argument names are not repeated, and it does not
+  // try to bind the words `eval` or `arguments`.
+
+  function checkFunctionParam(param, nameHash) {
+    switch (param.type) {
+      case "Identifier":
+        if (isStrictReservedWord(param.name) || isStrictBadIdWord(param.name))
+          raise(param.start, "Defining '" + param.name + "' in strict mode");
+        if (param.name in nameHash)
+          raise(param.start, "Argument name clash in strict mode");
+        nameHash[param.name] = true;
+        break;
+
+      case "ObjectPattern":
+        for (var i = 0; i < param.properties.length; i++)
+          checkFunctionParam(param.properties[i].value, nameHash);
+        break;
+
+      case "ArrayPattern":
+        for (var i = 0; i < param.elements.length; i++)
+          checkFunctionParam(param.elements[i], nameHash);
+        break;
     }
   }
 
@@ -2056,20 +2065,32 @@
   // Convert existing expression atom to assignable pattern
   // if possible.
 
-  function toAssignable(node) {
-    if (options.ecmaVersion >= 6) {
+  function toAssignable(node, allowSpread) {
+    if (options.ecmaVersion >= 6 && node) {
       switch (node.type) {
         case "Identifier":
           break;
 
         case "ObjectExpression":
           node.type = "ObjectPattern";
+          for (var i = 0; i < node.properties.length; i++) {
+            toAssignable(node.properties[i].value);
+          }
           break;
 
         case "ArrayExpression":
           node.type = "ArrayPattern";
+          for (var i = 0, lastI = node.elements.length - 1; i <= lastI; i++) {
+            toAssignable(node.elements[i], i === lastI);
+          }
           break;
 
+        case "SpreadElement":
+          if (allowSpread) {
+            toAssignable(node.argument);
+            break;
+          }
+
         default:
           unexpected(node.start);
       }
diff --git a/test/tests-harmony.js b/test/tests-harmony.js
index 4982dc8..75d83da 100644
--- a/test/tests-harmony.js
+++ b/test/tests-harmony.js
@@ -4311,10 +4311,10 @@ test("({ responseText: text }) = res", {
             end: {line: 1, column: 21}
           }
         }],
-        range: [1, 23],
+        range: [0, 24],
         loc: {
-          start: {line: 1, column: 1},
-          end: {line: 1, column: 23}
+          start: {line: 1, column: 0},
+          end: {line: 1, column: 24}
         }
       },
       right: {
@@ -12579,9 +12579,9 @@ test("x = { f(a=1) {} }", {
             rest: null,
             generator: false,
             expression: false,
-            range: [13, 15],
+            range: [7, 15],
             loc: {
-              start: {line: 1, column: 13},
+              start: {line: 1, column: 7},
               end: {line: 1, column: 15}
             }
           },
@@ -13320,10 +13320,10 @@ test("(function x([ a, b ]){})", {
       rest: null,
       generator: false,
       expression: false,
-      range: [1, 23],
+      range: [0, 24],
       loc: {
-        start: {line: 1, column: 1},
-        end: {line: 1, column: 23}
+        start: {line: 1, column: 0},
+        end: {line: 1, column: 24}
       }
     },
     range: [0, 24],
@@ -13441,10 +13441,10 @@ test("(function x({ a, b }){})", {
       rest: null,
       generator: false,
       expression: false,
-      range: [1, 23],
+      range: [0, 24],
       loc: {
-        start: {line: 1, column: 1},
-        end: {line: 1, column: 23}
+        start: {line: 1, column: 0},
+        end: {line: 1, column: 24}
       }
     },
     range: [0, 24],
@@ -13520,10 +13520,10 @@ test("(function x(...[ a, b ]){})", {
       },
       generator: false,
       expression: false,
-      range: [1, 26],
+      range: [0, 27],
       loc: {
-        start: {line: 1, column: 1},
-        end: {line: 1, column: 26}
+        start: {line: 1, column: 0},
+        end: {line: 1, column: 27}
       }
     },
     range: [0, 27],
@@ -13757,10 +13757,10 @@ test("(function x({ a: { w, x }, b: [y, z] }, ...[a, b, c]){})", {
       },
       generator: false,
       expression: false,
-      range: [1, 55],
+      range: [0, 56],
       loc: {
-        start: {line: 1, column: 1},
-        end: {line: 1, column: 55}
+        start: {line: 1, column: 0},
+        end: {line: 1, column: 56}
       }
     },
     range: [0, 56],
@@ -13841,9 +13841,9 @@ test("({ x([ a, b ]){} })", {
           rest: null,
           generator: false,
           expression: false,
-          range: [14, 16],
+          range: [4, 16],
           loc: {
-            start: {line: 1, column: 14},
+            start: {line: 1, column: 4},
             end: {line: 1, column: 16}
           }
         },
@@ -13857,10 +13857,10 @@ test("({ x([ a, b ]){} })", {
           end: {line: 1, column: 16}
         }
       }],
-      range: [1, 18],
+      range: [0, 19],
       loc: {
-        start: {line: 1, column: 1},
-        end: {line: 1, column: 18}
+        start: {line: 1, column: 0},
+        end: {line: 1, column: 19}
       }
     },
     range: [0, 19],
@@ -13941,9 +13941,9 @@ test("({ x(...[ a, b ]){} })", {
           },
           generator: false,
           expression: false,
-          range: [17, 19],
+          range: [4, 19],
           loc: {
-            start: {line: 1, column: 17},
+            start: {line: 1, column: 4},
             end: {line: 1, column: 19}
           }
         },
@@ -13957,10 +13957,10 @@ test("({ x(...[ a, b ]){} })", {
           end: {line: 1, column: 19}
         }
       }],
-      range: [1, 21],
+      range: [0, 22],
       loc: {
-        start: {line: 1, column: 1},
-        end: {line: 1, column: 21}
+        start: {line: 1, column: 0},
+        end: {line: 1, column: 22}
       }
     },
     range: [0, 22],
@@ -14215,10 +14215,10 @@ test("({ x({ a: { w, x }, b: [y, z] }, ...[a, b, c]){} })", {
           end: {line: 1, column: 48}
         }
       }],
-      range: [1, 50],
+      range: [0, 51],
       loc: {
-        start: {line: 1, column: 1},
-        end: {line: 1, column: 50}
+        start: {line: 1, column: 0},
+        end: {line: 1, column: 51}
       }
     },
     range: [0, 51],
@@ -15909,7 +15909,7 @@ testFail("function hello() {'use strict'; ({ i: 10, s(eval) { } }); }", "Definin
 
 testFail("function a() { \"use strict\"; ({ b(t, t) { } }); }", "Argument name clash in strict mode (1:37)", {ecmaVersion: 6});
 
-testFail("var super", "Unexpected token (1:5)", {ecmaVersion: 6, forbidReserved: true});
+testFail("var super", "The keyword 'super' is reserved (1:4)", {ecmaVersion: 6, forbidReserved: true});
 
 testFail("var default", "Unexpected token (1:4)", {ecmaVersion: 6});
 
@@ -16226,19 +16226,19 @@ testFail("\"use strict\"; function x(a, { a }){}", "Unexpected token (1:37)", {e
 
 testFail("\"use strict\"; function x({ b: { a } }, [{ b: { a } }]){}", "Unexpected token (1:57)", {ecmaVersion: 6});
 
-testFail("\"use strict\"; function x(a, ...[a]){}", "Unexpected token (1:38)", {ecmaVersion: 6});
+testFail("\"use strict\"; function x(a, ...[a]){}", "Argument name clash in strict mode (1:32)", {ecmaVersion: 6});
 
 testFail("(...a, b) => {}", "Unexpected token (1:1)", {ecmaVersion: 6});
 
-testFail("([ 5 ]) => {}", "Unexpected token (1:8)", {ecmaVersion: 6});
+testFail("([ 5 ]) => {}", "Unexpected token (1:3)", {ecmaVersion: 6});
 
 testFail("({ 5 }) => {}", "Unexpected token (1:6)", {ecmaVersion: 6});
 
-testFail("(...[ 5 ]) => {}", "Unexpected token (1:10)", {ecmaVersion: 6});
+testFail("(...[ 5 ]) => {}", "Unexpected token (1:6)", {ecmaVersion: 6});
 
 testFail("[...{ a }] = b", "Unexpected token (1:11)", {ecmaVersion: 6});
 
-testFail("[...a, b] = c", "Unexpected token (1:6)", {ecmaVersion: 6});
+testFail("[...a, b] = c", "Unexpected token (1:1)", {ecmaVersion: 6});
 
 testFail("({ t(eval) { \"use strict\"; } });", "Defining 'eval' in strict mode (1:5)", {ecmaVersion: 6});
 

-- 
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