hyperformula-dc
Version:
HyperFormula is a JavaScript engine for efficient processing of spreadsheet-like data and formulas
460 lines (394 loc) • 14.9 kB
JavaScript
"use strict";
exports.__esModule = true;
exports.doesContainRelativeReferences = exports.NamedExpressions = exports.InternalNamedExpression = void 0;
require("core-js/modules/es.array.iterator.js");
require("core-js/modules/es.map.js");
require("core-js/modules/es.object.to-string.js");
require("core-js/modules/es.string.iterator.js");
require("core-js/modules/web.dom-collections.iterator.js");
require("core-js/modules/es.array.filter.js");
require("core-js/modules/es.array.from.js");
require("core-js/modules/es.array.map.js");
require("core-js/modules/web.dom-collections.for-each.js");
var _Cell = require("./Cell");
var _parser = require("./parser");
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; }
var InternalNamedExpression = /*#__PURE__*/function () {
function InternalNamedExpression(displayName, address, added, options) {
_classCallCheck(this, InternalNamedExpression);
this.displayName = displayName;
this.address = address;
this.added = added;
this.options = options;
}
_createClass(InternalNamedExpression, [{
key: "normalizeExpressionName",
value: function normalizeExpressionName() {
return this.displayName.toLowerCase();
}
}, {
key: "copy",
value: function copy() {
return new InternalNamedExpression(this.displayName, this.address, this.added, this.options);
}
}]);
return InternalNamedExpression;
}();
exports.InternalNamedExpression = InternalNamedExpression;
var WorkbookStore = /*#__PURE__*/function () {
function WorkbookStore() {
_classCallCheck(this, WorkbookStore);
this.mapping = new Map();
}
_createClass(WorkbookStore, [{
key: "has",
value: function has(expressionName) {
return this.mapping.has(this.normalizeExpressionName(expressionName));
}
}, {
key: "isNameAvailable",
value: function isNameAvailable(expressionName) {
var normalizedExpressionName = this.normalizeExpressionName(expressionName);
var namedExpression = this.mapping.get(normalizedExpressionName);
return !(namedExpression && namedExpression.added);
}
}, {
key: "add",
value: function add(namedExpression) {
this.mapping.set(namedExpression.normalizeExpressionName(), namedExpression);
}
}, {
key: "get",
value: function get(expressionName) {
return this.mapping.get(this.normalizeExpressionName(expressionName));
}
}, {
key: "getExisting",
value: function getExisting(expressionName) {
var namedExpression = this.mapping.get(this.normalizeExpressionName(expressionName));
if (namedExpression && namedExpression.added) {
return namedExpression;
} else {
return undefined;
}
}
}, {
key: "remove",
value: function remove(expressionName) {
var normalizedExpressionName = this.normalizeExpressionName(expressionName);
var namedExpression = this.mapping.get(normalizedExpressionName);
if (namedExpression) {
namedExpression.added = false;
}
}
}, {
key: "getAllNamedExpressions",
value: function getAllNamedExpressions() {
return Array.from(this.mapping.values()).filter(function (ne) {
return ne.added;
});
}
}, {
key: "normalizeExpressionName",
value: function normalizeExpressionName(expressionName) {
return expressionName.toLowerCase();
}
}]);
return WorkbookStore;
}();
var WorksheetStore = /*#__PURE__*/function () {
function WorksheetStore() {
_classCallCheck(this, WorksheetStore);
this.mapping = new Map();
}
_createClass(WorksheetStore, [{
key: "add",
value: function add(namedExpression) {
this.mapping.set(this.normalizeExpressionName(namedExpression.displayName), namedExpression);
}
}, {
key: "get",
value: function get(expressionName) {
return this.mapping.get(this.normalizeExpressionName(expressionName));
}
}, {
key: "has",
value: function has(expressionName) {
return this.mapping.has(this.normalizeExpressionName(expressionName));
}
}, {
key: "getAllNamedExpressions",
value: function getAllNamedExpressions() {
return Array.from(this.mapping.values()).filter(function (ne) {
return ne.added;
});
}
}, {
key: "normalizeExpressionName",
value: function normalizeExpressionName(expressionName) {
return expressionName.toLowerCase();
}
}, {
key: "isNameAvailable",
value: function isNameAvailable(expressionName) {
var normalizedExpressionName = this.normalizeExpressionName(expressionName);
return !this.mapping.has(normalizedExpressionName);
}
}, {
key: "remove",
value: function remove(expressionName) {
var normalizedExpressionName = this.normalizeExpressionName(expressionName);
var namedExpression = this.mapping.get(normalizedExpressionName);
if (namedExpression) {
this.mapping.delete(normalizedExpressionName);
}
}
}]);
return WorksheetStore;
}();
var NamedExpressions = /*#__PURE__*/function () {
function NamedExpressions() {
_classCallCheck(this, NamedExpressions);
this.nextNamedExpressionRow = 0;
this.workbookStore = new WorkbookStore();
this.worksheetStores = new Map();
this.addressCache = new Map();
}
_createClass(NamedExpressions, [{
key: "isNameAvailable",
value: function isNameAvailable(expressionName, sheetId) {
var _a, _b;
if (sheetId === undefined) {
return this.workbookStore.isNameAvailable(expressionName);
} else {
return (_b = (_a = this.worksheetStore(sheetId)) === null || _a === void 0 ? void 0 : _a.isNameAvailable(expressionName)) !== null && _b !== void 0 ? _b : true;
}
}
}, {
key: "namedExpressionInAddress",
value: function namedExpressionInAddress(row) {
var namedExpression = this.addressCache.get(row);
if (namedExpression && namedExpression.added) {
return namedExpression;
} else {
return undefined;
}
}
}, {
key: "namedExpressionForScope",
value: function namedExpressionForScope(expressionName, sheetId) {
var _a;
if (sheetId === undefined) {
return this.workbookStore.getExisting(expressionName);
} else {
return (_a = this.worksheetStore(sheetId)) === null || _a === void 0 ? void 0 : _a.get(expressionName);
}
}
}, {
key: "nearestNamedExpression",
value: function nearestNamedExpression(expressionName, sheetId) {
var _a, _b;
return (_b = (_a = this.worksheetStore(sheetId)) === null || _a === void 0 ? void 0 : _a.get(expressionName)) !== null && _b !== void 0 ? _b : this.workbookStore.getExisting(expressionName);
}
}, {
key: "isExpressionInScope",
value: function isExpressionInScope(expressionName, sheetId) {
var _a, _b;
return (_b = (_a = this.worksheetStore(sheetId)) === null || _a === void 0 ? void 0 : _a.has(expressionName)) !== null && _b !== void 0 ? _b : false;
}
}, {
key: "isNameValid",
value: function isNameValid(expressionName) {
if (/^[A-Za-z]+[0-9]+$/.test(expressionName)) {
return false;
}
return /^[A-Za-z\u00C0-\u02AF_][A-Za-z0-9\u00C0-\u02AF._]*$/.test(expressionName);
}
}, {
key: "addNamedExpression",
value: function addNamedExpression(expressionName, sheetId, options) {
var store = sheetId === undefined ? this.workbookStore : this.worksheetStoreOrCreate(sheetId);
var namedExpression = store.get(expressionName);
if (namedExpression !== undefined) {
namedExpression.added = true;
namedExpression.displayName = expressionName;
namedExpression.options = options;
} else {
namedExpression = new InternalNamedExpression(expressionName, this.nextAddress(), true, options);
store.add(namedExpression);
}
this.addressCache.set(namedExpression.address.row, namedExpression);
return namedExpression;
}
}, {
key: "restoreNamedExpression",
value: function restoreNamedExpression(namedExpression, sheetId) {
var store = sheetId === undefined ? this.workbookStore : this.worksheetStoreOrCreate(sheetId);
namedExpression.added = true;
store.add(namedExpression);
this.addressCache.set(namedExpression.address.row, namedExpression);
return namedExpression;
}
}, {
key: "worksheetStoreOrCreate",
value: function worksheetStoreOrCreate(sheetId) {
var store = this.worksheetStores.get(sheetId);
if (!store) {
store = new WorksheetStore();
this.worksheetStores.set(sheetId, store);
}
return store;
}
}, {
key: "worksheetStore",
value: function worksheetStore(sheetId) {
return this.worksheetStores.get(sheetId);
}
}, {
key: "namedExpressionOrPlaceholder",
value: function namedExpressionOrPlaceholder(expressionName, sheetId) {
var _a;
return (_a = this.worksheetStoreOrCreate(sheetId).get(expressionName)) !== null && _a !== void 0 ? _a : this.workbookNamedExpressionOrPlaceholder(expressionName);
}
}, {
key: "workbookNamedExpressionOrPlaceholder",
value: function workbookNamedExpressionOrPlaceholder(expressionName) {
var namedExpression = this.workbookStore.get(expressionName);
if (namedExpression === undefined) {
namedExpression = new InternalNamedExpression(expressionName, this.nextAddress(), false);
this.workbookStore.add(namedExpression);
}
return namedExpression;
}
}, {
key: "remove",
value: function remove(expressionName, sheetId) {
var store;
if (sheetId === undefined) {
store = this.workbookStore;
} else {
store = this.worksheetStore(sheetId);
}
var namedExpression = store === null || store === void 0 ? void 0 : store.get(expressionName);
if (store === undefined || namedExpression === undefined || !namedExpression.added) {
throw 'Named expression does not exist';
}
store.remove(expressionName);
if (store instanceof WorksheetStore && store.mapping.size === 0) {
this.worksheetStores.delete(sheetId);
}
this.addressCache.delete(namedExpression.address.row);
}
}, {
key: "getAllNamedExpressionsNamesInScope",
value: function getAllNamedExpressionsNamesInScope(sheetId) {
return this.getAllNamedExpressions().filter(function (_ref) {
var scope = _ref.scope;
return scope === sheetId;
}).map(function (ne) {
return ne.expression.displayName;
});
}
}, {
key: "getAllNamedExpressionsNames",
value: function getAllNamedExpressionsNames() {
return this.getAllNamedExpressions().map(function (ne) {
return ne.expression.displayName;
});
}
}, {
key: "getAllNamedExpressions",
value: function getAllNamedExpressions() {
var storedNamedExpressions = [];
this.workbookStore.getAllNamedExpressions().forEach(function (expr) {
storedNamedExpressions.push({
expression: expr,
scope: undefined
});
});
this.worksheetStores.forEach(function (store, sheetNum) {
store.getAllNamedExpressions().forEach(function (expr) {
storedNamedExpressions.push({
expression: expr,
scope: sheetNum
});
});
});
return storedNamedExpressions;
}
}, {
key: "getAllNamedExpressionsForScope",
value: function getAllNamedExpressionsForScope(scope) {
var _a, _b;
if (scope === undefined) {
return this.workbookStore.getAllNamedExpressions();
} else {
return (_b = (_a = this.worksheetStores.get(scope)) === null || _a === void 0 ? void 0 : _a.getAllNamedExpressions()) !== null && _b !== void 0 ? _b : [];
}
}
}, {
key: "nextAddress",
value: function nextAddress() {
return (0, _Cell.simpleCellAddress)(NamedExpressions.SHEET_FOR_WORKBOOK_EXPRESSIONS, 0, this.nextNamedExpressionRow++);
}
}]);
return NamedExpressions;
}();
exports.NamedExpressions = NamedExpressions;
NamedExpressions.SHEET_FOR_WORKBOOK_EXPRESSIONS = -1;
var doesContainRelativeReferences = function doesContainRelativeReferences(ast) {
switch (ast.type) {
case _parser.AstNodeType.EMPTY:
case _parser.AstNodeType.NUMBER:
case _parser.AstNodeType.STRING:
case _parser.AstNodeType.ERROR:
case _parser.AstNodeType.ERROR_WITH_RAW_INPUT:
return false;
case _parser.AstNodeType.CELL_REFERENCE:
return !ast.reference.isAbsolute();
case _parser.AstNodeType.CELL_RANGE:
case _parser.AstNodeType.COLUMN_RANGE:
case _parser.AstNodeType.ROW_RANGE:
return !ast.start.isAbsolute();
case _parser.AstNodeType.NAMED_EXPRESSION:
return false;
case _parser.AstNodeType.PERCENT_OP:
case _parser.AstNodeType.PLUS_UNARY_OP:
case _parser.AstNodeType.MINUS_UNARY_OP:
{
return doesContainRelativeReferences(ast.value);
}
case _parser.AstNodeType.CONCATENATE_OP:
case _parser.AstNodeType.EQUALS_OP:
case _parser.AstNodeType.NOT_EQUAL_OP:
case _parser.AstNodeType.LESS_THAN_OP:
case _parser.AstNodeType.GREATER_THAN_OP:
case _parser.AstNodeType.LESS_THAN_OR_EQUAL_OP:
case _parser.AstNodeType.GREATER_THAN_OR_EQUAL_OP:
case _parser.AstNodeType.MINUS_OP:
case _parser.AstNodeType.PLUS_OP:
case _parser.AstNodeType.TIMES_OP:
case _parser.AstNodeType.DIV_OP:
case _parser.AstNodeType.POWER_OP:
return doesContainRelativeReferences(ast.left) || doesContainRelativeReferences(ast.right);
case _parser.AstNodeType.PARENTHESIS:
return doesContainRelativeReferences(ast.expression);
case _parser.AstNodeType.FUNCTION_CALL:
{
return ast.args.some(function (arg) {
return doesContainRelativeReferences(arg);
});
}
case _parser.AstNodeType.ARRAY:
{
return ast.args.some(function (row) {
return row.some(function (arg) {
return doesContainRelativeReferences(arg);
});
});
}
}
};
exports.doesContainRelativeReferences = doesContainRelativeReferences;