[Pkg-javascript-commits] [node-acorn-jsx] 251/484: Added Generator Comprehension support.

Bastien Roucariès rouca at moszumanska.debian.org
Sat Aug 19 14:20:40 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 9d552efe452c3af523043ac5e6635c9978e41d11
Author: Ingvar Stepanyan <me at rreverser.com>
Date:   Sun Jul 27 03:54:04 2014 +0300

    Added Generator Comprehension support.
---
 acorn.js              |  88 +++++++++++++++++++---------------
 test/tests-harmony.js | 127 +++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 176 insertions(+), 39 deletions(-)

diff --git a/acorn.js b/acorn.js
index e819209..68d6f82 100644
--- a/acorn.js
+++ b/acorn.js
@@ -1893,26 +1893,31 @@
       return finishNode(node, "Literal");
 
     case _parenL:
-      var node = startNode(), tokStartLoc1 = tokStartLoc, tokStart1 = tokStart, val, exprList;
+      var tokStartLoc1 = tokStartLoc, tokStart1 = tokStart, val, exprList;
       next();
-      var oldParenL = ++metParenL;
-      if (tokType !== _parenR) {
-        val = parseExpression();
-        exprList = val.type === "SequenceExpression" ? val.expressions : [val];
-      } else {
-        exprList = [];
-      }
-      expect(_parenR);
-      // if '=>' follows '(...)', convert contents to arguments
-      if (metParenL === oldParenL && eat(_arrow)) {
-        val = parseArrowExpression(node, exprList);
+      // check whether this is generator comprehension or regular expression
+      if (options.ecmaVersion >= 6 && tokType === _for) {
+        val = parseComprehension(startNode(), true);
       } else {
-        // forbid '()' before everything but '=>'
-        if (!val) unexpected(lastStart);
-        // forbid '...' in sequence expressions
-        if (options.ecmaVersion >= 6) {
-          for (var i = 0; i < exprList.length; i++) {
-            if (exprList[i].type === "SpreadElement") unexpected();
+        var oldParenL = ++metParenL;
+        if (tokType !== _parenR) {
+          val = parseExpression();
+          exprList = val.type === "SequenceExpression" ? val.expressions : [val];
+        } else {
+          exprList = [];
+        }
+        expect(_parenR);
+        // if '=>' follows '(...)', convert contents to arguments
+        if (metParenL === oldParenL && eat(_arrow)) {
+          val = parseArrowExpression(startNode(), exprList);
+        } else {
+          // forbid '()' before everything but '=>'
+          if (!val) unexpected(lastStart);
+          // forbid '...' in sequence expressions
+          if (options.ecmaVersion >= 6) {
+            for (var i = 0; i < exprList.length; i++) {
+              if (exprList[i].type === "SpreadElement") unexpected();
+            }
           }
         }
       }
@@ -1932,26 +1937,7 @@
       next();
       // check whether this is array comprehension or regular array
       if (options.ecmaVersion >= 6 && tokType === _for) {
-        node.blocks = [];
-        while (tokType === _for) {
-          var block = startNode();
-          next();
-          expect(_parenL);
-          block.left = toAssignable(parseExprAtom());
-          checkLVal(block.left, true);
-          if (tokType !== _name || tokVal !== "of") unexpected();
-          next();
-          // `of` property is here for compatibility with Esprima's AST
-          // which also supports deprecated [for (... in ...) expr]
-          block.of = true;
-          block.right = parseExpression();
-          expect(_parenR);
-          node.blocks.push(finishNode(block, "ComprehensionBlock"));
-        }
-        node.filter = eat(_if) ? parseParenExpression() : null;
-        node.body = parseExpression();
-        expect(_bracketR);
-        return finishNode(node, "ComprehensionExpression");
+        return parseComprehension(node, false);
       }
       node.elements = parseExprList(_bracketR, true, true);
       return finishNode(node, "ArrayExpression");
@@ -2455,4 +2441,30 @@
     return finishNode(node, "YieldExpression");
   }
 
+  // Parses array and generator comprehensions.
+
+  function parseComprehension(node, isGenerator) {
+    node.blocks = [];
+    while (tokType === _for) {
+      var block = startNode();
+      next();
+      expect(_parenL);
+      block.left = toAssignable(parseExprAtom());
+      checkLVal(block.left, true);
+      if (tokType !== _name || tokVal !== "of") unexpected();
+      next();
+      // `of` property is here for compatibility with Esprima's AST
+      // which also supports deprecated [for (... in ...) expr]
+      block.of = true;
+      block.right = parseExpression();
+      expect(_parenR);
+      node.blocks.push(finishNode(block, "ComprehensionBlock"));
+    }
+    node.filter = eat(_if) ? parseParenExpression() : null;
+    node.body = parseExpression();
+    expect(isGenerator ? _parenR : _bracketR);
+    node.generator = isGenerator;
+    return finishNode(node, "ComprehensionExpression");
+  }
+
 });
diff --git a/test/tests-harmony.js b/test/tests-harmony.js
index fc522c8..98ec29f 100644
--- a/test/tests-harmony.js
+++ b/test/tests-harmony.js
@@ -3513,7 +3513,7 @@ test("x = { set method(val) v = val }", {
   locations: true
 });
 
-// Array Comprehension
+// Array and Generator Comprehension
 
 test("[for (x of array) x]", {
   type: "Program",
@@ -3558,6 +3558,7 @@ test("[for (x of array) x]", {
           end: {line: 1, column: 19}
         }
       },
+      generator: false,
       range: [0, 20],
       loc: {
         start: {line: 1, column: 0},
@@ -3679,6 +3680,129 @@ test("[for (x of array) for (y of array2) if (x === test) x]", {
           end: {line: 1, column: 53}
         }
       },
+      generator: false,
+      range: [0, 54],
+      loc: {
+        start: {line: 1, column: 0},
+        end: {line: 1, column: 54}
+      }
+    },
+    range: [0, 54],
+    loc: {
+      start: {line: 1, column: 0},
+      end: {line: 1, column: 54}
+    }
+  }],
+  range: [0, 54],
+  loc: {
+    start: {line: 1, column: 0},
+    end: {line: 1, column: 54}
+  }
+}, {
+  ecmaVersion: 6,
+  ranges: true,
+  locations: true
+});
+
+test("(for (x of array) for (y of array2) if (x === test) x)", {
+  type: "Program",
+  body: [{
+    type: "ExpressionStatement",
+    expression: {
+      type: "ComprehensionExpression",
+      filter: {
+        type: "BinaryExpression",
+        operator: "===",
+        left: {
+          type: "Identifier",
+          name: "x",
+          range: [40, 41],
+          loc: {
+            start: {line: 1, column: 40},
+            end: {line: 1, column: 41}
+          }
+        },
+        right: {
+          type: "Identifier",
+          name: "test",
+          range: [46, 50],
+          loc: {
+            start: {line: 1, column: 46},
+            end: {line: 1, column: 50}
+          }
+        },
+        range: [40, 50],
+        loc: {
+          start: {line: 1, column: 40},
+          end: {line: 1, column: 50}
+        }
+      },
+      blocks: [
+        {
+          type: "ComprehensionBlock",
+          left: {
+            type: "Identifier",
+            name: "x",
+            range: [6, 7],
+            loc: {
+              start: {line: 1, column: 6},
+              end: {line: 1, column: 7}
+            }
+          },
+          right: {
+            type: "Identifier",
+            name: "array",
+            range: [11, 16],
+            loc: {
+              start: {line: 1, column: 11},
+              end: {line: 1, column: 16}
+            }
+          },
+          range: [1, 17],
+          loc: {
+            start: {line: 1, column: 1},
+            end: {line: 1, column: 17}
+          },
+          of: true
+        },
+        {
+          type: "ComprehensionBlock",
+          left: {
+            type: "Identifier",
+            name: "y",
+            range: [23, 24],
+            loc: {
+              start: {line: 1, column: 23},
+              end: {line: 1, column: 24}
+            }
+          },
+          right: {
+            type: "Identifier",
+            name: "array2",
+            range: [28, 34],
+            loc: {
+              start: {line: 1, column: 28},
+              end: {line: 1, column: 34}
+            }
+          },
+          range: [18, 35],
+          loc: {
+            start: {line: 1, column: 18},
+            end: {line: 1, column: 35}
+          },
+          of: true
+        }
+      ],
+      body: {
+        type: "Identifier",
+        name: "x",
+        range: [52, 53],
+        loc: {
+          start: {line: 1, column: 52},
+          end: {line: 1, column: 53}
+        }
+      },
+      generator: true,
       range: [0, 54],
       loc: {
         start: {line: 1, column: 0},
@@ -3882,6 +4006,7 @@ test("[for ([,x] of array) for ({[start.x]: x, [start.y]: y} of array2) x]", {
           end: {line: 1, column: 67}
         }
       },
+      generator: false,
       range: [0, 68],
       loc: {
         start: {line: 1, column: 0},

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