[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