/* */ "format cjs"; "use strict"; var _babelToolsProtectJs2 = require("./../../babel/tools/protect.js"); var _babelToolsProtectJs3 = _interopRequireDefault(_babelToolsProtectJs2); var _tokentype = require("./tokentype"); var _state = require("./state"); var _identifier = require("./identifier"); var _util = require("./util"); _babelToolsProtectJs3["default"](module); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } var pp = _state.Parser.prototype; // Convert existing expression atom to assignable pattern // if possible. pp.toAssignable = function (node, isBinding) { if (this.options.ecmaVersion >= 6 && node) { switch (node.type) { case "Identifier": case "ObjectPattern": case "ArrayPattern": case "AssignmentPattern": break; case "ObjectExpression": node.type = "ObjectPattern"; for (var i = 0; i < node.properties.length; i++) { var prop = node.properties[i]; if (prop.type === "SpreadProperty") continue; if (prop.kind !== "init") this.raise(prop.key.start, "Object pattern can't contain getter or setter"); this.toAssignable(prop.value, isBinding); } break; case "ArrayExpression": node.type = "ArrayPattern"; this.toAssignableList(node.elements, isBinding); 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: this.raise(node.start, "Assigning to rvalue"); } } return node; }; // Convert list of expression atoms to binding list. pp.toAssignableList = function (exprList, isBinding) { 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); 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); } return exprList; }; // Parses spread element. pp.parseSpread = function (refShorthandDefaultPos) { var node = this.startNode(); this.next(); node.argument = this.parseMaybeAssign(refShorthandDefaultPos); return this.finishNode(node, "SpreadElement"); }; pp.parseRest = function () { var node = this.startNode(); this.next(); node.argument = this.type === _tokentype.types.name || this.type === _tokentype.types.bracketL ? this.parseBindingAtom() : this.unexpected(); return this.finishNode(node, "RestElement"); }; // Parses lvalue (assignable) atom. pp.parseBindingAtom = function () { if (this.options.ecmaVersion < 6) return this.parseIdent(); switch (this.type) { case _tokentype.types.name: return this.parseIdent(); case _tokentype.types.bracketL: var node = this.startNode(); this.next(); node.elements = this.parseBindingList(_tokentype.types.bracketR, true, true); return this.finishNode(node, "ArrayPattern"); case _tokentype.types.braceL: return this.parseObj(true); default: this.unexpected(); } }; pp.parseBindingList = function (close, allowEmpty, allowTrailingComma) { var elts = [], first = true; while (!this.eat(close)) { if (first) first = false;else this.expect(_tokentype.types.comma); if (allowEmpty && this.type === _tokentype.types.comma) { elts.push(null); } else if (allowTrailingComma && this.afterTrailingComma(close)) { break; } else if (this.type === _tokentype.types.ellipsis) { elts.push(this.parseAssignableListItemTypes(this.parseRest())); this.expect(close); break; } else { var left = this.parseMaybeDefault(); this.parseAssignableListItemTypes(left); elts.push(this.parseMaybeDefault(null, left)); } } return elts; }; pp.parseAssignableListItemTypes = function (param) { return param; }; // Parses assignment pattern around given atom if possible. pp.parseMaybeDefault = function (startPos, left) { startPos = startPos || this.markPosition(); left = left || this.parseBindingAtom(); if (!this.eat(_tokentype.types.eq)) return left; var node = this.startNodeAt(startPos); node.operator = "="; 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) { switch (expr.type) { case "Identifier": if (this.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) { if (_util.has(checkClashes, expr.name)) this.raise(expr.start, "Argument name clash in strict mode"); checkClashes[expr.name] = true; } break; case "MemberExpression": if (isBinding) this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " member expression"); break; case "ObjectPattern": for (var i = 0; i < expr.properties.length; i++) { var prop = expr.properties[i]; if (prop.type === "Property") prop = prop.value; this.checkLVal(prop, isBinding, checkClashes); } break; case "ArrayPattern": for (var i = 0; i < expr.elements.length; i++) { var elem = expr.elements[i]; if (elem) this.checkLVal(elem, isBinding, checkClashes); } break; case "AssignmentPattern": this.checkLVal(expr.left, isBinding, checkClashes); break; case "SpreadProperty": case "RestElement": this.checkLVal(expr.argument, isBinding, checkClashes); break; case "ParenthesizedExpression": this.checkLVal(expr.expression, isBinding, checkClashes); break; default: this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " rvalue"); } };