[Pkg-javascript-commits] [node-acorn-jsx] 380/484: Parse assignment patterns in-place in certain contexts.

Bastien Roucariès rouca at moszumanska.debian.org
Sat Aug 19 14:20:59 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 4d4a76588c58c37fea3942a8c7c4fde6a0c6d914
Author: Ingvar Stepanyan <me at rreverser.com>
Date:   Thu Jan 8 17:27:13 2015 +0200

    Parse assignment patterns in-place in certain contexts.
    
    * Parsing assignables without extra transform step when possible (speed-up).
    * Added support for shorthand defaults in such certain contexts (issue #181).
---
 acorn.js              |  75 +++++++++++++++++++++++++++-----
 acorn_loose.js        |   3 +-
 test/tests-harmony.js | 117 ++++++++++++++++++++++++++++++++++++++++++--------
 3 files changed, 163 insertions(+), 32 deletions(-)

diff --git a/acorn.js b/acorn.js
index b116315..20d4b35 100644
--- a/acorn.js
+++ b/acorn.js
@@ -1414,6 +1414,7 @@
   function has(obj, propName) {
     return Object.prototype.hasOwnProperty.call(obj, propName);
   }
+
   // Convert existing expression atom to assignable pattern
   // if possible.
 
@@ -1464,6 +1465,53 @@
     return node;
   }
 
+  // Parses lvalue (assignable) atom.
+
+  function parseAssignableAtom() {
+    if (options.ecmaVersion < 6) return parseIdent();
+    switch (tokType) {
+      case _name:
+        return parseIdent();
+
+      case _bracketL:
+        var node = startNode();
+        next();
+        var elts = node.elements = [], first = true;
+        while (!eat(_bracketR)) {
+          first ? first = false : expect(_comma);
+          if (tokType === _ellipsis) {
+            var spread = startNode();
+            next();
+            spread.argument = parseAssignableAtom();
+            checkSpreadAssign(spread.argument);
+            elts.push(finishNode(spread, "SpreadElement"));
+            expect(_bracketR);
+            break;
+          }
+          elts.push(tokType === _comma ? null : parseMaybeDefault());
+        }
+        return finishNode(node, "ArrayPattern");
+
+      case _braceL:
+        return parseObj(true);
+
+      default:
+        unexpected();
+    }
+  }
+
+  // Parses assignment pattern around given atom if possible.
+
+  function parseMaybeDefault(startPos, left) {
+    left = left || parseAssignableAtom();
+    if (!eat(_eq)) return left;
+    var node = startPos ? startNodeAt(startPos) : startNode();
+    node.operator = "=";
+    node.left = left;
+    node.right = parseMaybeAssign();
+    return finishNode(node, "AssignmentPattern");
+  }
+
   // Checks if node can be assignable spread argument.
 
   function checkSpreadAssign(node) {
@@ -1917,7 +1965,7 @@
     node.kind = kind;
     for (;;) {
       var decl = startNode();
-      decl.id = options.ecmaVersion >= 6 ? toAssignable(parseExprAtom()) : parseIdent();
+      decl.id = parseAssignableAtom();
       checkLVal(decl.id, true);
       decl.init = eat(_eq) ? parseExpression(true, noIn) : (kind === _const.keyword ? unexpected() : null);
       node.declarations.push(finishNode(decl, "VariableDeclarator"));
@@ -2238,7 +2286,7 @@
 
   // Parse an object literal.
 
-  function parseObj() {
+  function parseObj(isPattern) {
     var node = startNode(), first = true, propHash = {};
     node.properties = [];
     next();
@@ -2248,37 +2296,42 @@
         if (options.allowTrailingCommas && eat(_braceR)) break;
       } else first = false;
 
-      var prop = startNode(), isGenerator;
+      var prop = startNode(), isGenerator, start;
       if (options.ecmaVersion >= 6) {
         prop.method = false;
         prop.shorthand = false;
-        isGenerator = eat(_star);
+        if (isPattern) {
+          start = storeCurrentPos();
+        } else {
+          isGenerator = eat(_star);
+        }
       }
       parsePropertyName(prop);
       if (eat(_colon)) {
-        prop.value = parseExpression(true);
+        prop.value = isPattern ? parseMaybeDefault(start) : parseMaybeAssign();
         prop.kind = "init";
       } else if (options.ecmaVersion >= 6 && tokType === _parenL) {
+        if (isPattern) unexpected();
         prop.kind = "init";
         prop.method = true;
         prop.value = parseMethod(isGenerator);
       } else if (options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" &&
                  (prop.key.name === "get" || prop.key.name === "set") &&
                  (tokType != _comma && tokType != _braceR)) {
-        if (isGenerator) unexpected();
+        if (isGenerator || isPattern) unexpected();
         prop.kind = prop.key.name;
         parsePropertyName(prop);
         prop.value = parseMethod(false);
       } else if (options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") {
         prop.kind = "init";
-        prop.value = prop.key;
+        prop.value = isPattern ? parseMaybeDefault(start, prop.key) : prop.key;
         prop.shorthand = true;
       } else unexpected();
 
       checkPropClash(prop, propHash);
       node.properties.push(finishNode(prop, "Property"));
     }
-    return finishNode(node, "ObjectExpression");
+    return finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression");
   }
 
   function parsePropertyName(prop) {
@@ -2382,13 +2435,13 @@
       if (eat(_parenR)) {
         break;
       } else if (options.ecmaVersion >= 6 && eat(_ellipsis)) {
-        node.rest = toAssignable(parseExprAtom(), false, true);
+        node.rest = parseAssignableAtom();
         checkSpreadAssign(node.rest);
         expect(_parenR);
         defaults.push(null);
         break;
       } else {
-        node.params.push(options.ecmaVersion >= 6 ? toAssignable(parseExprAtom(), false, true) : parseIdent());
+        node.params.push(parseAssignableAtom());
         if (options.ecmaVersion >= 6) {
           if (eat(_eq)) {
             hasDefaults = true;
@@ -2676,7 +2729,7 @@
       var block = startNode();
       next();
       expect(_parenL);
-      block.left = toAssignable(parseExprAtom());
+      block.left = parseAssignableAtom();
       checkLVal(block.left, true);
       if (tokType !== _name || tokVal !== "of") unexpected();
       next();
diff --git a/acorn_loose.js b/acorn_loose.js
index 8bc6dfd..33a3cfe 100644
--- a/acorn_loose.js
+++ b/acorn_loose.js
@@ -985,8 +985,7 @@
           break;
 
         case "AssignmentExpression":
-          if (node.operator === "=")
-            node.type = "AssignmentPattern";
+          node.type = "AssignmentPattern";
           break;
       }
     }
diff --git a/test/tests-harmony.js b/test/tests-harmony.js
index 74a927f..4c571b3 100644
--- a/test/tests-harmony.js
+++ b/test/tests-harmony.js
@@ -14444,30 +14444,39 @@ test('var {get} = obj;', {
 
 test("var {propName: localVar = defaultValue} = obj", {
   type: "Program",
+  range: [0, 45],
   body: [{
     type: "VariableDeclaration",
+    range: [0, 45],
     declarations: [{
       type: "VariableDeclarator",
+      range: [4, 45],
       id: {
         type: "ObjectPattern",
+        range: [4, 39],
         properties: [{
           type: "Property",
+          range: [5, 38],
           method: false,
           shorthand: false,
           computed: false,
           key: {
             type: "Identifier",
+            range: [5, 13],
             name: "propName"
           },
           value: {
             type: "AssignmentPattern",
+            range: [5, 38],
             operator: "=",
             left: {
               type: "Identifier",
+              range: [15, 23],
               name: "localVar"
             },
             right: {
               type: "Identifier",
+              range: [26, 38],
               name: "defaultValue"
             }
           },
@@ -14476,44 +14485,114 @@ test("var {propName: localVar = defaultValue} = obj", {
       },
       init: {
         type: "Identifier",
+        range: [42, 45],
         name: "obj"
       }
     }],
     kind: "var"
   }]
-}, {ecmaVersion: 6});
+}, {
+  ecmaVersion: 6,
+  ranges: true,
+  locations: true,
+  loose: false
+});
 
-test("var [a = 1, b = 2] = arr", {
+test("var {propName = defaultValue} = obj", {
   type: "Program",
+  range: [0, 35],
   body: [{
     type: "VariableDeclaration",
+    range: [0, 35],
     declarations: [{
       type: "VariableDeclarator",
+      range: [4, 35],
       id: {
-        type: "ArrayPattern",
-        elements: [
-          {
-            type: "AssignmentPattern",
-            operator: "=",
-            left: {type: "Identifier", name: "a"},
-            right: {
-              type: "Literal",
-              value: 1
-            }
+        type: "ObjectPattern",
+        range: [4, 29],
+        properties: [{
+          type: "Property",
+          range: [5, 28],
+          method: false,
+          shorthand: true,
+          computed: false,
+          key: {
+            type: "Identifier",
+            range: [5, 13],
+            name: "propName"
           },
-          {
+          kind: "init",
+          value: {
             type: "AssignmentPattern",
+            range: [5, 28],
             operator: "=",
-            left: {type: "Identifier", name: "b"},
+            left: {
+              type: "Identifier",
+              range: [5, 13],
+              name: "propName"
+            },
             right: {
-              type: "Literal",
-              value: 2
+              type: "Identifier",
+              range: [16, 28],
+              name: "defaultValue"
             }
           }
-        ]
+        }]
       },
-      init: {type: "Identifier", name: "arr"}
+      init: {
+        type: "Identifier",
+        range: [32, 35],
+        name: "obj"
+      }
     }],
     kind: "var"
   }]
-}, {ecmaVersion: 6});
+}, {
+  ecmaVersion: 6,
+  ranges: true,
+  locations: true,
+  loose: false
+});
+
+test("var [localVar = defaultValue] = obj", {
+  type: "Program",
+  range: [0, 35],
+  body: [{
+    type: "VariableDeclaration",
+    range: [0, 35],
+    declarations: [{
+      type: "VariableDeclarator",
+      range: [4, 35],
+      id: {
+        type: "ArrayPattern",
+        range: [4, 29],
+        elements: [{
+          type: "AssignmentPattern",
+          range: [16, 28],
+          operator: "=",
+          left: {
+            type: "Identifier",
+            range: [5, 13],
+            name: "localVar"
+          },
+          right: {
+            type: "Identifier",
+            range: [16, 28],
+            name: "defaultValue"
+          }
+        }]
+      },
+      init: {
+        type: "Identifier",
+        range: [32, 35],
+        name: "obj"
+      }
+    }],
+    kind: "var"
+  }]
+}, {
+  ecmaVersion: 6,
+  ranges: true,
+  locations: true,
+  loose: false
+});

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