This site describes solve-engine as it is on main: 2.43.0, which npm does not have yet. npm installs 2.40.0, so a page may show an answer that version does not give yet.
extractReadsAndWrites
function extractReadsAndWrites(tokens, onName?): { reads: string[]; writes: string[];};Defined in: packages/engine/src/engine/ExpressionEngineSafety.ts:269
Extract variable reads and writes from a token stream.
Handles both IDENT and UNIT tokens as potential variable references. UNIT tokens occur when the variable name collides with a known unit (e.g., “b” for bits, “s” for seconds). The colon prefix unambiguously signals a variable definition context (handled by VariableParselet). A standalone UNIT token is only a real variable reference when it isn’t in unit-literal position (see isUnitLiteralContext) otherwise it’s a quantity/conversion unit name, never LOAD_VAR’d.
Also detects user-defined-function DEFINITIONS (name(params) = body)
as a read+write of the function’s own name, mirroring :name = value’s
existing convention of registering the defined name as both, and
excludes the definition’s own PARAMETER names from reads/writes
entirely (see collectFunctionParamNames). A function CALL
(name(args), no trailing =) needs no special detection: the call’s
own name falls through to the ordinary bare-identifier read-tracking
below, the same as any other LOAD_VAR-producing identifier. This is
already correct once calls compile successfully, no change needed.
A goal seek’s unknown (solve line 4 for rate = 900) is neither a read nor
a write, although rate = has the shape of a definition: the seek binds it
in its own call frame and the document’s variable is untouched. See
goalSeekUnknownIndex.
The same is true of a what-if’s inputs (line 4 with deposit = 150000) and a
sweep’s input (line 4 for rate from 3% to 6% step 1%): each is a name the
form holds fixed in a scratch re-run, never a write to the document’s own
variable, and never a read of it either. The value an input is given is an
ordinary expression, and its reads count as usual.
onName, when given, is told the position of every name as it is decided,
so a caller that needs spans (the language service’s references and rename)
reads them from these exact rules rather than a second copy that could
drift. The graph’s callers omit it and pay nothing.
Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
tokens | Token[] | One expression’s normalised tokens. |
onName? | (index, key, use) => void | Called with each name’s token index, its graph key (a global’s key carries the global: prefix) and how it is used. |
Returns
Section titled “Returns”{ reads: string[]; writes: string[];}The names read and written, as graph keys.
reads: string[];writes
Section titled “writes”writes: string[];