Skip to content
Spreadsheet Engine

EvaluationContext

Context object for formula evaluation. Historically often called options or opts when passed to spreadsheet functions and other evaluation-related functions.

allowBoxed?: boolean;

Allow ValueBox values to be returned without unboxing first


allowMatrices?: boolean;

false (the default) if a Matrix result should be mapped to a #VALUE! error, true to return it as-is.


cell?: CellItem | null;

Cell object whose formula is being evaluated, or null


cellId?: string | null;

Unprefixed ID (name or A1 address) of the cell containing the formula being evaluated, null if not evaluating a cell formula.


checkAllReferences?: boolean;

coerceNullToZero: CoercionMode;

collectReferencesFromLambdaDefinitions?: boolean;

True if static references should be collected inside lambda definitions. Normally that is not done because the act of defining a lambda does not depend on any values of cells referenced by the lambda (those values will be looked up only when the defined lambda is called). However, when the static dependencies of a lambda call are too tricky to determine because of lambdas returning lambdas, we fall back on recording all references, in the lambda definition and in all arguments of the call to it, and marking them all conditional. That’s done in a sub-context with this property set to true, to tell the reference analysis to descend into lambda definitions.


env?: ReadonlyMap<string, MaybeBoxedFormulaArgument>;

evaluateAST: (ast, options) => MaybeBoxedFormulaValue;

Evaluate a whole formula, expressed as an AST, in this context. NOTE: this must be a function, not arrow function, and be invoked on an evaluation context, so that it captures the correct this context.

ASTRootNode

EvaluationContext

MaybeBoxedFormulaValue


evaluateASTNode: FnEvaluateASTNode;

Evaluate an expression, expressed as an AST node, in this context. NOTE: this must be a function, not arrow function, and be invoked on an evaluation context, so that it captures the correct this context.


evaluateStaticReference?: FnEvaluateStaticReferenceASTNode;

Resolve an AST node to a static reference if possible. Present only on cell-evaluation contexts. Wraps evaluateStaticReferenceASTNodeUnbound so that a function handler can reach it without importing evaluate.ts (forming a runtime import cycle through the function-handler registry). Named differently from the dependency-analysis evaluateStaticReferenceASTNode resolver even though both wrap the same unbound function: that one is not a field on this interface, but is bound per dependency-graph traversal and attached to derived contexts through { ...ctx } spreads, so reusing its name for this field would leak this runtime handle into dependency analysis and corrupt it. Like the other context functions, must be a function (not arrow) invoked on the context.


getContextTable?: () => Table | null;

Used to resolve the context table for unprefixed structured references (e.g. =[[#This row], [Column]]).

Table | null


getWorkbookByKey: (key) => Workbook | undefined;

Get the workbook with the given dependency-graph key (based uniquely on the workbook name in a case-insensitive way by the wbNameToKey function).

number

Workbook | undefined


isDirtyFormulaCell?: (cell) => boolean;

Check whether the given cell is in a state considered dirty in the current evaluation context.

CellItem | null

boolean


lambdaBindings?: LambdaBindings;

Bindings of lambda parameter names to unique symbols, and symbols to the arguments for those parameters and their evaluation contexts. The layer of indirection (as opposed to just mapping names directly to arguments) is to ensure the scoping of lambda parameters: they should be visible in nested lambda contexts only if lexically in scope, i.e. LAMBDA(x, LAMBDA(y, x + y)), and not e.g. in LAMBDA(x, OtherLambda(x)) where OtherLambda is defined as LAMBDA(y, x + y) … because in the latter case, the x in OtherLambda refers to the defined name x, not the lambda parameter x of the calling lambda.


lambdaCallDepth?: number;

Current lambda call nesting depth, incremented on each evaluateLambda entry. When it exceeds MAX_LAMBDA_CALL_DEPTH, the call returns #NUM! instead of recursing further.


letParameterNames?: ReadonlySet<string>;

Upper-cased names of the parameters of the LET expressions enclosing the node being evaluated or analysed. A name node naming one of these is a reference to the LET parameter even when the reference parser rejects the name (R, C) or reads it as a cell address (A1), which a defined name may not have but a LET parameter may.


metricsCallback?: ((event) => void) | null;

Callback to report metrics


mode: ModeBit;

plain?: boolean;

True if the formula is a plain formula (formula type 'plain'), evaluated by Excel’s pre-dynamic-array rules: its result never spills, and each argument’s context, array or scalar, follows from the parameter it is passed to. Default false.


profile?: Profile | null;

Profiling information


rawOutput?: boolean;

false (the default) if the result of AST evaluation should be postprocessed (reference resolved, number rounded to 15 decimal places) before returning it; true to return it as-is.


recordDependencyUse?: (ref) => void;

Callback to report the use of a dependency in evaluating a formula

Reference

void


recurseIntoContextDependentNames?: boolean;

True if reference analysis should recurse into context-dependent defined names to discover their context-specific dependencies. When a cell references a defined name whose formula is context-dependent (like =INDIRECT("B2")), the actual dependencies depend on the calling context’s sheet. Setting this to true causes reference analysis to recurse into such names and yield their context-specific references, in addition to a nonvalue reference to the name itself.


relativeRefOrigin?:
| {
col: number;
row: number;
}
| null;

Zero-based coordinates of the cell against which a reference coordinate written without a $ is resolved. A defined name stores the address its reference resolves to in A1, so each referencing cell shifts the unanchored coordinates by its own position; this is set only while such a name’s formula is evaluated on a referencing cell’s behalf. An ordinary cell formula’s written address is the address it names, so this stays unset there and nothing shifts.


resolveLambdaArgumentAST?: (param) => ASTNode | undefined;

Look up an argument expression AST of a lambda call by parameter symbol. This exists in the context of finding references in a specific lambda call.

LambdaParameterSymbol

ASTNode | undefined


resolveName: (name, sheetName?, workbookName?) =>
| FormulaError
| DefinedName;

Get the cell object for the given defined name (matched case-insensitively) in the indicated scope or in this context. If sheetName is given, then only sheet-scoped defined names will be considered, not workbook-scoped defined names. If this context permits cross-workbook name resolution, then a match in the current workbook will be preferred but if no match is found there, then the first match across all workbooks in model order will be returned. Passing workbookName confines the search to that workbook, as a reference naming a workbook asks for a name in it and nowhere else. If no match is found, #NAME? is returned.

string

string | null

string | null

| FormulaError | DefinedName


resolveNameOutsideLet?: (name, sheetName?, workbookName?) =>
| FormulaError
| DefinedName;

resolveName without the variables of the enclosing LET expressions; absent outside LET. A lambda body resolves names where the lambda is defined, so a lambda called inside a LET does not see its variables.

string

string | null

string | null

| FormulaError | DefinedName


resolveSheet: (sheetName?, workbookName?) => WorkSheet | null;

Get the sheet with the given name (matched case-insensitively), or the first sheet of the context workbook if no name is given. The context workbook is the default (first) workbook of the model if not evaluating in the context of a specific workbook.

string | null

string | null

WorkSheet | null


resolveTable: (name, workbookName?) => Table | null;

Get the table with the given name (matched case-insensitively) in the context workbook, or if not found there, then in the first workbook in the model that contains a table by this name.

string

string | null

Table | null


resolveWorkbook: (name?) => Workbook | undefined;

Get the workbook with the given case-insensitive name, or if no name is given, the context workbook, or the default (first) workbook of the model if not evaluating in the context of a specific workbook.

string | null

Workbook | undefined


sheetName?: string | null;

Name of the sheet containing the reference or formula, null for references in workbook-scoped defined-names, and for formulas in GRID elements


singleCell?: boolean;

True if formulas should be evaluated in single-cell (non-array) mode. Default false.

ISO/IEC 29500 section 18.17.2.7, “Single- and Array Formulas”


supportedFunctionNames?: Set<string>;

Set of function names supported in GRID (irrespective of mode). Exposed via the evaluation context to dodge a circular import because the CELL function needs this set but is imported by the module that populates and exports it.


upToDateState?: number;

The up-to-date state of the context workbook after the latest completed recalculation, a non-negative integer.

  • Cells with state > upToDateState and state < upToDateState + NUM_STATES are dirty.
  • Cells can have state === upToDateState + NUM_STATES during recalculation, as that is the new up-to-date state, to which the workbook’s upToDateState attribute will be raised when recalculation completes.
  • Cells cannot have state > upToDateState + NUM_STATES.

visitedContextDependentNames?: Set<string>;

Set of defined name identifiers that have already been visited during context-dependent name recursion. Used to prevent infinite recursion when context-dependent names reference each other (e.g., name1 = ROW() + name2, name2 = ROW() + name1).


visitedLambdaExpressions?: Map<ASTRootNode, Set<Map<LambdaParameterSymbol, LambdaArg> | undefined>>;

The lambda bodies the reference visitor is inside, each with the captured arguments of the closures it is inside them for (undefined for a lambda that captures none). A call to one of these closures visits only its arguments, and one passed as a value is not visited again, so that a defined-name lambda calling itself, directly or through other names, ends the visit. Closures that share a body but capture different arguments are visited each in turn.


workbookName: string | null;

Name of the workbook containing the reference or formula, null for a GRID element formula