Skip to content

Dereference helper functions reference

For completeness, here are the functions which are called from dereference but are implementation specific.

function msDereferenceIntoCellValue(funcDispatcher, cell, anchors) {
funcDispatcher.precedents.cells.push(cell);
var cellValue = funcDispatcher.globals.getCellValue(cell);
if (cellValue.kind === ResultKind.Failure)
return msThrowEvaluationError(cellValue.reason);
var cellValueValue = cellValue.value;
if (cellValueValue.kind === CellKind.FinalValue)
return cellValueValue.oper;
Ab(cellValueValue.anchor, funcDispatcher.visitedCells);
anchors.push(cellValueValue.anchor);
}
function msDereferenceIntoArrayInner(
funcDispatcher,
givenSheetRange,
anchors,
tryToAvoidDereferencingUnused
) {
var toDereference;
funcDispatcher.precedents.cells.push(givenSheetRange);
// My guess is that the else branch of this if statement is an
// optimization which tries to avoid dereferencing "unused cells"
// (whatever that means?). The optimization is not worth it when the
// number of cells in the range is below 16.
if (
!tryToAvoidDereferencingUnused ||
msRowsTimesColumns(givenSheetRange.range) <= 16
) {
toDereference = givenSheetRange;
} else {
var usedRange = funcDispatcher.globals.getUsedRange(
givenSheetRange.sheet
);
var usedRangeValueRange = undefined;
if (isSuccess(usedRange)) {
if (usedRange.value != null) {
usedRangeValueRange = usedRange.value.range;
}
} else {
msThrowEvaluationError(usedRange.reason);
}
var givenAndUsedSheetRangeIntersection = undefined;
if (usedRangeValueRange !== undefined) {
givenAndUsedSheetRangeIntersection = gridRangesIntersect(
givenSheetRange.range,
gridRange(
0,
0,
usedRangeValueRange.row + usedRangeValueRange.rows,
usedRangeValueRange.col + usedRangeValueRange.cols
)
);
}
if (undefined === givenAndUsedSheetRangeIntersection) {
return new StrictSparseArray2D(
givenSheetRange.range.rows,
givenSheetRange.range.cols,
0,
0,
[],
blankOper
);
}
toDereference = sheetGridRange(
givenSheetRange.sheet,
givenAndUsedSheetRangeIntersection
);
}
var cellValues = funcDispatcher.globals.getCellValues(toDereference);
if (cellValues.kind === ResultKind.Failure)
return msThrowEvaluationError(cellValues.reason);
var oldNumAnchors = anchors.length;
var result = (function (
funcDispatcher,
givenSheetRange,
toDereferenceRange,
cellValuesValue,
anchors
) {
var denseElements = [];
var denseRows = cellValuesValue.length;
var denseCols = 0;
msAssert(
"calc.runtime.deference: readIntoArray2D number of rows",
denseRows === toDereferenceRange.rows
);
for (var i = 0; i < denseRows; i += 1) {
denseElements.push([]);
var c = cellValuesValue[i].length;
msAssert(
"calc.runtime.deference: readIntoArray2D number of cols",
c === toDereferenceRange.cols
);
if (i === 0) {
denseCols = c;
} else {
denseCols = fastMin(c, denseCols);
}
for (var j = 0; j < c; j += 1) {
var d = cellValuesValue[i][j];
if (CellKind.FinalValue === d.kind) {
denseElements[i][j] = d.oper;
} else {
Ab(d.anchor, funcDispatcher.visitedCells);
msAssert(
"calc.runtime.deference: readIntoArray2D correct sheet",
isSheetIndexEqual(d.anchor.sheet, givenSheetRange.sheet)
);
anchors.push(d.anchor);
denseElements[i][j] = refErrorOper;
}
}
}
return new StrictSparseArray2D(
givenSheetRange.range.rows,
givenSheetRange.range.cols,
denseRows,
denseCols,
denseElements,
blankOper
);
})(
funcDispatcher,
givenSheetRange,
toDereference.range,
cellValues.value,
anchors
);
return oldNumAnchors === anchors.length ? result : undefined;
}
function msDereferenceIntoArray(funcDispatcher, sheetRange, anchors) {
var n;
var array2d = msDereferenceIntoArrayInner(
funcDispatcher,
sheetRange,
anchors,
false
);
if (array2d != null) {
return arrayOper(
array2d.rows,
array2d.cols,
array2d.rows === array2d.denseRows &&
array2d.cols === array2d.denseCols
? array2d.denseElements
: msCreateMatrixFilledWithFunction(
(n = array2d).rows,
n.cols,
n.get.bind(n)
)
);
}
}