numenor
Version:
Customizable, safe evaluator of JavaScript-like expressions.
147 lines (115 loc) • 4.77 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Assignment = void 0;
var _Parser = require("../../Parser");
var _ = require("./");
var _Error = require("../Error");
var _util = require("./util");
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
var Assignment = function Assignment(expr, options, compile) {
if (expr.type !== _Parser.ExpressionType.Assignment) {
throw new TypeError((0, _Error.UnknownExpression)(expr));
}
if (options.ImmutableContext) {
return (0, _.mark)({
isConst: true
}, function () {
throw new TypeError(_Error.ImmutableContext);
});
}
var rhs = compile(expr.rhs, options, compile);
var contains = options.NoProtoAccess ? _util.hasOwnProp : (0, _util.makeProtoPropQuery)(options);
var isConst = options.Constants && (0, _.hasConstValue)(rhs);
var isAsync = (0, _.hasAsyncValue)(rhs);
if (expr.lhs.type === _Parser.ExpressionType.Identifier) {
var _name = expr.lhs.name;
if (options.NoNewVars) {
return function (context, stack) {
if (!(0, _util.hasOwnProp)(context, _name)) {
throw new ReferenceError((0, _Error.UndefinedIdentifier)(_name));
}
return context[_name] = rhs(context, stack);
};
}
if (isConst && contains(options.Constants, _name)) {
if (isAsync) {
return (0, _.mark)({
isConst: isConst,
isAsync: isAsync
}, function () {
return (0, _.evalConst)(rhs).then(function (value) {
return options.Constants[_name] = value;
});
});
}
return (0, _.makeConstEval)(options.Constants[_name] = (0, _.evalConst)(rhs));
}
if (isAsync) {
return (0, _.mark)({
isAsync: isAsync
}, function (context, stack) {
return rhs(context, stack).then(function (value) {
return context[_name] = value;
});
});
}
return function (context, stack) {
return context[_name] = rhs(context, stack);
};
}
var prop;
var propProcessor = _util.identity;
if (expr.lhs.type === _Parser.ExpressionType.MemberAccess) {
var _name2 = expr.lhs.name;
if (_name2 === '__proto__') {
return (0, _.mark)({
isConst: true
}, function () {
throw new TypeError(_Error.CannotAccessProto);
});
}
prop = function prop() {
return _name2;
};
propProcessor = _util.identity;
} else if (expr.lhs.type === _Parser.ExpressionType.ComputedMemberAccess) {
prop = compile(expr.lhs.rhs, options, compile);
propProcessor = function propProcessor(propName) {
if (propName === '__proto__') {
throw new TypeError(_Error.CannotAccessProto);
}
return propName;
};
isConst = isConst && (0, _.hasConstValue)(prop);
isAsync = isAsync || (0, _.hasAsyncValue)(prop);
} else {
throw new TypeError((0, _Error.UnknownExpression)(expr.lhs));
}
var lhs = compile(expr.lhs.lhs, options, compile);
isConst = isConst && (0, _.hasConstValue)(lhs);
isAsync = isAsync || (0, _.hasAsyncValue)(lhs);
return (0, _.mark)({
isConst: isConst,
isAsync: isAsync
}, function (context, stack) {
return (0, _util.evalMaybeAsyncSteps)(context, stack, [[lhs, function (object) {
if (object === null || _typeof(object) !== 'object') {
throw new TypeError((0, _Error.CannotAccessProperty)(object, name));
}
return object;
}], [prop, propProcessor], rhs]).then(function (_ref) {
var _ref2 = _slicedToArray(_ref, 3),
object = _ref2[0],
propName = _ref2[1],
value = _ref2[2];
return object[propName] = value;
});
});
};
exports.Assignment = Assignment;