ek9_query_data_touch
Answers first: anchor and verdicts (parameter → untouched | mutates | escapes | ... ), then touches[] with the mutation and escape axes and every contributing site - read-only.
When to use it
Does this callable (or what it calls) write through the structure I pass, or keep a reference to it - one call with symbol:'Stash.keep' and parameter:'items'. No file needed; omit parameter for a verdict per parameter.
When not to use it
- Whether a callable is pure (no side effects at all), not whether it touches ONE structure you pass — use
ek9_query_purity_impact/ the purity diagnostics. - You want raw caller/callee chains without the touch overlay — use
ek9_query_call_graph. - You want to CHANGE code — data-touch is a read-only enquiry, it has no fix.
Details
Returns status:ok with 'anchor' (the resolved callable, display form) and 'verdicts' (parameter → verdict) first, then 'touches' — one entry per tracked parameter: {parameter, mutation, escape, verdict (untouched / mutates / mutates-via / escapes / escapes-via / mutates-and-escapes / mutates-and-escapes-via / unknown), reusable, sites[], unknowns[]}. Each mutation/escape site carries file:line, kind, axis, the source 'path' touched, and — when TRANSITIVE — the 'via' callee chain plus the origin file:line where the write/store really happens. Escape currently observes user-code whole-structure store/return only; container retain-into (list += arg) reads no-escape until the retention table lands (a documented trust residual). Runs on demand over FULL_RESOLUTION (or default ek9_compile).
Arguments
| Argument | Type | Required | What it is |
|---|---|---|---|
column | integer | Optional 0-based IDE column. Advisory — the anchor is the enclosing callable, resolved by line, so this may be omitted. | |
file | string | The EK9 source file - OPTIONAL when symbol is a construct name; required to anchor on a member or a use site. | |
line | integer | 1-based line inside the callable whose parameter you are tracking (the enclosing method or function is resolved from it) - OMIT it and pass symbol instead. | |
parameter | string | The parameter name to track (the data structure). Omit to get a verdict for EVERY parameter of the callable. | |
symbol | string | The callable: 'Stash.keep' (Type.member) or a bare function name - no file needed, the tool finds it workspace-wide; or, with file (+ line), the name you mean there. |
It also takes the arguments every tool takes.
Recorded calls
Real calls, recorded against small projects and checked on every build - a changed answer fails it.
Direct store
Request
{
"file" : "locks.ek9",
"line" : 17,
"parameter" : "items"
}
Response
{
"anchor" : "Stash.keep(List of String)",
"meta" : {
"serverMs" : "<timing>"
},
"status" : "ok",
"touches" : [ {
"escape" : "may-escape",
"mutation" : "no-mutation",
"parameter" : "items",
"reusable" : false,
"sites" : [ {
"axis" : "escape",
"file" : "locks.ek9",
"kind" : "escape-store",
"line" : 17,
"path" : "held",
"transitive" : false
} ],
"unknowns" : [ ],
"verdict" : "escapes"
} ],
"verdicts" : {
"items" : "escapes"
...
Cut short here: 2 more lines. The whole recorded call.
Transitive store
Request
{
"file" : "locks.ek9",
"line" : 27,
"parameter" : "lockedItem"
}
Response
{
"anchor" : "fn",
"meta" : {
"serverMs" : "<timing>"
},
"status" : "ok",
"touches" : [ {
"escape" : "may-escape",
"mutation" : "no-mutation",
"parameter" : "lockedItem",
"reusable" : false,
"sites" : [ {
"axis" : "escape",
"file" : "locks.ek9",
"kind" : "escape-store",
"line" : 27,
"originFile" : "locks.ek9",
"originLine" : 17,
"path" : "held",
"transitive" : true,
"via" : [ "probe.mutex.payload::Stash.keep(org.ek9.lang::List of String)" ]
} ],
"unknowns" : [ ],
"verdict" : "escapes-via"
...
Cut short here: 5 more lines. The whole recorded call.