UNPKG

hyperformula-dc

Version:

HyperFormula is a JavaScript engine for efficient processing of spreadsheet-like data and formulas

453 lines (359 loc) 18.1 kB
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e2) { throw _e2; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_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 _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } import "core-js/modules/es.array.map.js"; import "core-js/modules/es.array.slice.js"; import "core-js/modules/es.number.is-integer.js"; import "core-js/modules/es.number.constructor.js"; import "core-js/modules/es.symbol.js"; import "core-js/modules/es.symbol.description.js"; import "core-js/modules/es.object.to-string.js"; import "core-js/modules/es.symbol.iterator.js"; import "core-js/modules/es.array.iterator.js"; import "core-js/modules/es.string.iterator.js"; import "core-js/modules/web.dom-collections.iterator.js"; import "core-js/modules/es.array.from.js"; import "core-js/modules/es.function.name.js"; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } /** * @license * Copyright (c) 2021 Handsoncode. All rights reserved. */ import { AbsoluteCellRange } from '../../AbsoluteCellRange'; import { CellError, ErrorType } from '../../Cell'; import { ErrorMessage } from '../../error-message'; import { AstNodeType } from '../../parser'; import { coerceRangeToScalar, coerceScalarToBoolean, coerceScalarToString, coerceToRange } from '../ArithmeticHelper'; import { getRawValue, isExtendedNumber } from '../InterpreterValue'; import { SimpleRangeValue } from '../SimpleRangeValue'; export var ArgumentTypes; (function (ArgumentTypes) { /** * String type. */ ArgumentTypes["STRING"] = "STRING"; /** * Floating point type. */ ArgumentTypes["NUMBER"] = "NUMBER"; /** * Boolean type. */ ArgumentTypes["BOOLEAN"] = "BOOLEAN"; /** * Any non-range value. */ ArgumentTypes["SCALAR"] = "SCALAR"; /** * Any non-range, no-error type. */ ArgumentTypes["NOERROR"] = "NOERROR"; /** * Range type. */ ArgumentTypes["RANGE"] = "RANGE"; /** * Integer type. */ ArgumentTypes["INTEGER"] = "INTEGER"; /** * String representing complex number. */ ArgumentTypes["COMPLEX"] = "COMPLEX"; /** * Range or scalar. */ ArgumentTypes["ANY"] = "ANY"; })(ArgumentTypes || (ArgumentTypes = {})); /** * Abstract class representing interpreter function plugin. * Plugin may contain multiple functions. Each function should be of type {@link PluginFunctionType} and needs to be * included in {@link implementedFunctions} */ export var FunctionPlugin = /*#__PURE__*/function () { function FunctionPlugin(interpreter) { var _this = this; _classCallCheck(this, FunctionPlugin); this.coerceScalarToNumberOrError = function (arg) { return _this.arithmeticHelper.coerceScalarToNumberOrError(arg); }; this.runFunction = function (args, state, metadata, fn) { var _a, _b, _c, _d, _e; var argumentDefinitions = metadata.parameters; var argValues; if (metadata.expandRanges) { argValues = _this.listOfScalarValues(args, state); } else { argValues = args.map(function (ast) { return [_this.evaluateAst(ast, state), false]; }); } if (metadata.repeatLastArgs === undefined && argumentDefinitions.length < argValues.length) { return new CellError(ErrorType.NA, ErrorMessage.WrongArgNumber); } if (metadata.repeatLastArgs !== undefined && argumentDefinitions.length < argValues.length && (argValues.length - argumentDefinitions.length) % metadata.repeatLastArgs !== 0) { return new CellError(ErrorType.NA, ErrorMessage.WrongArgNumber); } argumentDefinitions = _toConsumableArray(argumentDefinitions); while (argumentDefinitions.length < argValues.length) { var _argumentDefinitions; (_argumentDefinitions = argumentDefinitions).push.apply(_argumentDefinitions, _toConsumableArray(argumentDefinitions.slice(argumentDefinitions.length - metadata.repeatLastArgs))); } var maxWidth = 1; var maxHeight = 1; if (!metadata.vectorizationForbidden && state.arraysFlag) { for (var i = 0; i < argValues.length; i++) { var _argValues$i = _slicedToArray(argValues[i], 1), val = _argValues$i[0]; if (val instanceof SimpleRangeValue && argumentDefinitions[i].argumentType !== ArgumentTypes.RANGE && argumentDefinitions[i].argumentType !== ArgumentTypes.ANY) { maxHeight = Math.max(maxHeight, val.height()); maxWidth = Math.max(maxWidth, val.width()); } } } for (var _i2 = argValues.length; _i2 < argumentDefinitions.length; _i2++) { if (((_a = argumentDefinitions[_i2]) === null || _a === void 0 ? void 0 : _a.defaultValue) === undefined) { if (!((_b = argumentDefinitions[_i2]) === null || _b === void 0 ? void 0 : _b.optionalArg)) { //not enough values passed as arguments, and there was no default value and argument was not optional return new CellError(ErrorType.NA, ErrorMessage.WrongArgNumber); } } } var retArr = []; for (var row = 0; row < maxHeight; row++) { var rowArr = []; for (var col = 0; col < maxWidth; col++) { var argCoerceFailure = undefined; var coercedArguments = []; for (var _i3 = 0; _i3 < argumentDefinitions.length; _i3++) { // eslint-disable-next-line prefer-const var _ref = (_c = argValues[_i3]) !== null && _c !== void 0 ? _c : [undefined, undefined], _ref2 = _slicedToArray(_ref, 2), _val = _ref2[0], ignorable = _ref2[1]; if (_val instanceof SimpleRangeValue && argumentDefinitions[_i3].argumentType !== ArgumentTypes.RANGE && argumentDefinitions[_i3].argumentType !== ArgumentTypes.ANY) { if (!metadata.vectorizationForbidden && state.arraysFlag) { _val = (_d = _val.data[_val.height() !== 1 ? row : 0]) === null || _d === void 0 ? void 0 : _d[_val.width() !== 1 ? col : 0]; } } var arg = _val !== null && _val !== void 0 ? _val : (_e = argumentDefinitions[_i3]) === null || _e === void 0 ? void 0 : _e.defaultValue; if (arg === undefined) { coercedArguments.push(undefined); //we verified in previous loop that this arg is optional } else { //we apply coerce only to non-default values var coercedArg = _val !== undefined ? _this.coerceToType(arg, argumentDefinitions[_i3], state) : arg; if (coercedArg !== undefined) { if (coercedArg instanceof CellError && argumentDefinitions[_i3].argumentType !== ArgumentTypes.SCALAR) { //if this is first error encountered, store it argCoerceFailure = argCoerceFailure !== null && argCoerceFailure !== void 0 ? argCoerceFailure : coercedArg; } coercedArguments.push(coercedArg); } else if (!ignorable) { //if this is first error encountered, store it argCoerceFailure = argCoerceFailure !== null && argCoerceFailure !== void 0 ? argCoerceFailure : new CellError(ErrorType.VALUE, ErrorMessage.WrongType); } } } var ret = argCoerceFailure !== null && argCoerceFailure !== void 0 ? argCoerceFailure : _this.returnNumberWrapper(fn.apply(void 0, coercedArguments), metadata.returnNumberType); if (maxHeight === 1 && maxWidth === 1) { return ret; } if (ret instanceof SimpleRangeValue) { throw 'Function returning array cannot be vectorized.'; } rowArr.push(ret); } retArr.push(rowArr); } return SimpleRangeValue.onlyValues(retArr); }; this.runFunctionWithReferenceArgument = function (args, state, metadata, noArgCallback, referenceCallback) { var nonReferenceCallback = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : function () { return new CellError(ErrorType.NA, ErrorMessage.CellRefExpected); }; if (args.length === 0) { return _this.returnNumberWrapper(noArgCallback(), metadata.returnNumberType); } else if (args.length > 1) { return new CellError(ErrorType.NA, ErrorMessage.WrongArgNumber); } var arg = args[0]; while (arg.type === AstNodeType.PARENTHESIS) { arg = arg.expression; } var cellReference; if (arg.type === AstNodeType.CELL_REFERENCE) { cellReference = arg.reference.toSimpleCellAddress(state.formulaAddress); } else if (arg.type === AstNodeType.CELL_RANGE || arg.type === AstNodeType.COLUMN_RANGE || arg.type === AstNodeType.ROW_RANGE) { try { cellReference = AbsoluteCellRange.fromAst(arg, state.formulaAddress).start; } catch (e) { return new CellError(ErrorType.REF, ErrorMessage.CellRefExpected); } } if (cellReference !== undefined) { return _this.returnNumberWrapper(referenceCallback(cellReference), metadata.returnNumberType); } return _this.runFunction(args, state, metadata, nonReferenceCallback); }; this.interpreter = interpreter; this.dependencyGraph = interpreter.dependencyGraph; this.columnSearch = interpreter.columnSearch; this.config = interpreter.config; this.serialization = interpreter.serialization; this.arraySizePredictor = interpreter.arraySizePredictor; this.dateTimeHelper = interpreter.dateTimeHelper; this.arithmeticHelper = interpreter.arithmeticHelper; } _createClass(FunctionPlugin, [{ key: "evaluateAst", value: function evaluateAst(ast, state) { return this.interpreter.evaluateAst(ast, state); } }, { key: "arraySizeForAst", value: function arraySizeForAst(ast, state) { return this.arraySizePredictor.checkArraySizeForAst(ast, state); } }, { key: "listOfScalarValues", value: function listOfScalarValues(asts, state) { var ret = []; var _iterator = _createForOfIteratorHelper(asts), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var argAst = _step.value; var value = this.evaluateAst(argAst, state); if (value instanceof SimpleRangeValue) { var _iterator2 = _createForOfIteratorHelper(value.valuesFromTopLeftCorner()), _step2; try { for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { var scalarValue = _step2.value; ret.push([scalarValue, true]); } } catch (err) { _iterator2.e(err); } finally { _iterator2.f(); } } else { ret.push([value, false]); } } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } return ret; } }, { key: "coerceToType", value: function coerceToType(arg, coercedType, state) { var ret; if (arg instanceof SimpleRangeValue) { switch (coercedType.argumentType) { case ArgumentTypes.RANGE: case ArgumentTypes.ANY: ret = arg; break; default: { var coerce = coerceRangeToScalar(arg, state); if (coerce === undefined) { return undefined; } arg = coerce; } } } if (!(arg instanceof SimpleRangeValue)) { switch (coercedType.argumentType) { case ArgumentTypes.INTEGER: case ArgumentTypes.NUMBER: // eslint-disable-next-line no-case-declarations var coerced = this.coerceScalarToNumberOrError(arg); if (!isExtendedNumber(coerced)) { ret = coerced; break; } // eslint-disable-next-line no-case-declarations var value = getRawValue(coerced); if (coercedType.maxValue !== undefined && value > coercedType.maxValue) { return new CellError(ErrorType.NUM, ErrorMessage.ValueLarge); } if (coercedType.minValue !== undefined && value < coercedType.minValue) { return new CellError(ErrorType.NUM, ErrorMessage.ValueSmall); } if (coercedType.lessThan !== undefined && value >= coercedType.lessThan) { return new CellError(ErrorType.NUM, ErrorMessage.ValueLarge); } if (coercedType.greaterThan !== undefined && value <= coercedType.greaterThan) { return new CellError(ErrorType.NUM, ErrorMessage.ValueSmall); } if (coercedType.argumentType === ArgumentTypes.INTEGER && !Number.isInteger(value)) { return new CellError(ErrorType.NUM, ErrorMessage.IntegerExpected); } ret = coerced; break; case ArgumentTypes.STRING: ret = coerceScalarToString(arg); break; case ArgumentTypes.BOOLEAN: ret = coerceScalarToBoolean(arg); break; case ArgumentTypes.SCALAR: case ArgumentTypes.NOERROR: case ArgumentTypes.ANY: ret = arg; break; case ArgumentTypes.RANGE: if (arg instanceof CellError) { return arg; } ret = coerceToRange(arg); break; case ArgumentTypes.COMPLEX: return this.arithmeticHelper.coerceScalarToComplex(getRawValue(arg)); } } if (coercedType.passSubtype || ret === undefined) { return ret; } else { return getRawValue(ret); } } }, { key: "metadata", value: function metadata(name) { var params = this.constructor.implementedFunctions[name]; if (params !== undefined) { return params; } throw new Error("No metadata for function ".concat(name, ".")); } }, { key: "returnNumberWrapper", value: function returnNumberWrapper(val, type, format) { if (type !== undefined && isExtendedNumber(val)) { return this.arithmeticHelper.ExtendedNumberFactory(getRawValue(val), { type: type, format: format }); } else { return val; } } }]); return FunctionPlugin; }();