aboutsummaryrefslogtreecommitdiff
path: root/node_modules/babylon/lib/parser/lval.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/babylon/lib/parser/lval.js')
-rw-r--r--node_modules/babylon/lib/parser/lval.js315
1 files changed, 315 insertions, 0 deletions
diff --git a/node_modules/babylon/lib/parser/lval.js b/node_modules/babylon/lib/parser/lval.js
new file mode 100644
index 000000000..1bdbfa1f0
--- /dev/null
+++ b/node_modules/babylon/lib/parser/lval.js
@@ -0,0 +1,315 @@
+"use strict";
+
+var _types = require("../tokenizer/types");
+
+var _index = require("./index");
+
+var _index2 = _interopRequireDefault(_index);
+
+var _identifier = require("../util/identifier");
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var pp = _index2.default.prototype;
+
+// Convert existing expression atom to assignable pattern
+// if possible.
+
+/* eslint indent: 0 */
+
+pp.toAssignable = function (node, isBinding, contextDescription) {
+ if (node) {
+ switch (node.type) {
+ case "Identifier":
+ case "ObjectPattern":
+ case "ArrayPattern":
+ case "AssignmentPattern":
+ break;
+
+ case "ObjectExpression":
+ node.type = "ObjectPattern";
+ for (var _iterator = node.properties, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
+ var _ref;
+
+ if (_isArray) {
+ if (_i >= _iterator.length) break;
+ _ref = _iterator[_i++];
+ } else {
+ _i = _iterator.next();
+ if (_i.done) break;
+ _ref = _i.value;
+ }
+
+ var prop = _ref;
+
+ if (prop.type === "ObjectMethod") {
+ if (prop.kind === "get" || prop.kind === "set") {
+ this.raise(prop.key.start, "Object pattern can't contain getter or setter");
+ } else {
+ this.raise(prop.key.start, "Object pattern can't contain methods");
+ }
+ } else {
+ this.toAssignable(prop, isBinding, "object destructuring pattern");
+ }
+ }
+ break;
+
+ case "ObjectProperty":
+ this.toAssignable(node.value, isBinding, contextDescription);
+ break;
+
+ case "SpreadProperty":
+ node.type = "RestProperty";
+ break;
+
+ case "ArrayExpression":
+ node.type = "ArrayPattern";
+ this.toAssignableList(node.elements, isBinding, contextDescription);
+ break;
+
+ case "AssignmentExpression":
+ if (node.operator === "=") {
+ node.type = "AssignmentPattern";
+ delete node.operator;
+ } else {
+ this.raise(node.left.end, "Only '=' operator can be used for specifying default value.");
+ }
+ break;
+
+ case "MemberExpression":
+ if (!isBinding) break;
+
+ default:
+ {
+ var message = "Invalid left-hand side" + (contextDescription ? " in " + contextDescription : /* istanbul ignore next */"expression");
+ this.raise(node.start, message);
+ }
+ }
+ }
+ return node;
+};
+
+// Convert list of expression atoms to binding list.
+
+pp.toAssignableList = function (exprList, isBinding, contextDescription) {
+ var end = exprList.length;
+ if (end) {
+ var last = exprList[end - 1];
+ if (last && last.type === "RestElement") {
+ --end;
+ } else if (last && last.type === "SpreadElement") {
+ last.type = "RestElement";
+ var arg = last.argument;
+ this.toAssignable(arg, isBinding, contextDescription);
+ if (arg.type !== "Identifier" && arg.type !== "MemberExpression" && arg.type !== "ArrayPattern") {
+ this.unexpected(arg.start);
+ }
+ --end;
+ }
+ }
+ for (var i = 0; i < end; i++) {
+ var elt = exprList[i];
+ if (elt) this.toAssignable(elt, isBinding, contextDescription);
+ }
+ return exprList;
+};
+
+// Convert list of expression atoms to a list of
+
+pp.toReferencedList = function (exprList) {
+ return exprList;
+};
+
+// Parses spread element.
+
+pp.parseSpread = function (refShorthandDefaultPos) {
+ var node = this.startNode();
+ this.next();
+ node.argument = this.parseMaybeAssign(false, refShorthandDefaultPos);
+ return this.finishNode(node, "SpreadElement");
+};
+
+pp.parseRest = function () {
+ var node = this.startNode();
+ this.next();
+ node.argument = this.parseBindingIdentifier();
+ return this.finishNode(node, "RestElement");
+};
+
+pp.shouldAllowYieldIdentifier = function () {
+ return this.match(_types.types._yield) && !this.state.strict && !this.state.inGenerator;
+};
+
+pp.parseBindingIdentifier = function () {
+ return this.parseIdentifier(this.shouldAllowYieldIdentifier());
+};
+
+// Parses lvalue (assignable) atom.
+
+pp.parseBindingAtom = function () {
+ switch (this.state.type) {
+ case _types.types._yield:
+ if (this.state.strict || this.state.inGenerator) this.unexpected();
+ // fall-through
+ case _types.types.name:
+ return this.parseIdentifier(true);
+
+ case _types.types.bracketL:
+ var node = this.startNode();
+ this.next();
+ node.elements = this.parseBindingList(_types.types.bracketR, true);
+ return this.finishNode(node, "ArrayPattern");
+
+ case _types.types.braceL:
+ return this.parseObj(true);
+
+ default:
+ this.unexpected();
+ }
+};
+
+pp.parseBindingList = function (close, allowEmpty) {
+ var elts = [];
+ var first = true;
+ while (!this.eat(close)) {
+ if (first) {
+ first = false;
+ } else {
+ this.expect(_types.types.comma);
+ }
+ if (allowEmpty && this.match(_types.types.comma)) {
+ elts.push(null);
+ } else if (this.eat(close)) {
+ break;
+ } else if (this.match(_types.types.ellipsis)) {
+ elts.push(this.parseAssignableListItemTypes(this.parseRest()));
+ this.expect(close);
+ break;
+ } else {
+ var decorators = [];
+ while (this.match(_types.types.at)) {
+ decorators.push(this.parseDecorator());
+ }
+ var left = this.parseMaybeDefault();
+ if (decorators.length) {
+ left.decorators = decorators;
+ }
+ this.parseAssignableListItemTypes(left);
+ elts.push(this.parseMaybeDefault(left.start, left.loc.start, left));
+ }
+ }
+ return elts;
+};
+
+pp.parseAssignableListItemTypes = function (param) {
+ return param;
+};
+
+// Parses assignment pattern around given atom if possible.
+
+pp.parseMaybeDefault = function (startPos, startLoc, left) {
+ startLoc = startLoc || this.state.startLoc;
+ startPos = startPos || this.state.start;
+ left = left || this.parseBindingAtom();
+ if (!this.eat(_types.types.eq)) return left;
+
+ var node = this.startNodeAt(startPos, startLoc);
+ node.left = left;
+ node.right = this.parseMaybeAssign();
+ return this.finishNode(node, "AssignmentPattern");
+};
+
+// Verify that a node is an lval — something that can be assigned
+// to.
+
+pp.checkLVal = function (expr, isBinding, checkClashes, contextDescription) {
+ switch (expr.type) {
+ case "Identifier":
+ if (this.state.strict && (_identifier.reservedWords.strictBind(expr.name) || _identifier.reservedWords.strict(expr.name))) {
+ this.raise(expr.start, (isBinding ? "Binding " : "Assigning to ") + expr.name + " in strict mode");
+ }
+
+ if (checkClashes) {
+ // we need to prefix this with an underscore for the cases where we have a key of
+ // `__proto__`. there's a bug in old V8 where the following wouldn't work:
+ //
+ // > var obj = Object.create(null);
+ // undefined
+ // > obj.__proto__
+ // null
+ // > obj.__proto__ = true;
+ // true
+ // > obj.__proto__
+ // null
+ var key = "_" + expr.name;
+
+ if (checkClashes[key]) {
+ this.raise(expr.start, "Argument name clash in strict mode");
+ } else {
+ checkClashes[key] = true;
+ }
+ }
+ break;
+
+ case "MemberExpression":
+ if (isBinding) this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " member expression");
+ break;
+
+ case "ObjectPattern":
+ for (var _iterator2 = expr.properties, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
+ var _ref2;
+
+ if (_isArray2) {
+ if (_i2 >= _iterator2.length) break;
+ _ref2 = _iterator2[_i2++];
+ } else {
+ _i2 = _iterator2.next();
+ if (_i2.done) break;
+ _ref2 = _i2.value;
+ }
+
+ var prop = _ref2;
+
+ if (prop.type === "ObjectProperty") prop = prop.value;
+ this.checkLVal(prop, isBinding, checkClashes, "object destructuring pattern");
+ }
+ break;
+
+ case "ArrayPattern":
+ for (var _iterator3 = expr.elements, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
+ var _ref3;
+
+ if (_isArray3) {
+ if (_i3 >= _iterator3.length) break;
+ _ref3 = _iterator3[_i3++];
+ } else {
+ _i3 = _iterator3.next();
+ if (_i3.done) break;
+ _ref3 = _i3.value;
+ }
+
+ var elem = _ref3;
+
+ if (elem) this.checkLVal(elem, isBinding, checkClashes, "array destructuring pattern");
+ }
+ break;
+
+ case "AssignmentPattern":
+ this.checkLVal(expr.left, isBinding, checkClashes, "assignment pattern");
+ break;
+
+ case "RestProperty":
+ this.checkLVal(expr.argument, isBinding, checkClashes, "rest property");
+ break;
+
+ case "RestElement":
+ this.checkLVal(expr.argument, isBinding, checkClashes, "rest element");
+ break;
+
+ default:
+ {
+ var message = (isBinding ? /* istanbul ignore next */"Binding invalid" : "Invalid") + " left-hand side" + (contextDescription ? " in " + contextDescription : /* istanbul ignore next */"expression");
+ this.raise(expr.start, message);
+ }
+ }
+}; \ No newline at end of file