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) ) ); }}