ek9_list_visible_symbols
Answers first: scopeChain[] innermost to outermost, each scope with its symbols (name, kind, type, state, roles), then activeGuards and purityConstraint.
When to use it
What names can I use at this position - every variable, field, method, type and constant in scope - one call with file + symbol:'<name on that line>'. Pass file + line instead from an IDE cursor.
When not to use it
- One specific symbol AT the cursor, not the whole list — use
ek9_inspect_symbol_at_cursor(cursor-precise, single result, and the only path that reports 'absent'). - The members of a KNOWN type (e.g. all methods on Customer) — use
ek9_query_effective_api. - The structure of the enclosing construct (class/record) — use
ek9_query_construct. - Not anchored to a position — use
ek9_query_workspacefor a workspace-wide structure overview, orek9_find_constructs_by_nameto locate a known construct NAME.
Details
scopeChain is ordered innermost→outermost with per-scope purityContext; purityConstraint is the effective (innermost) purity — check it before proposing mutations. Free top-level functions are kind FUNCTION, NOT METHOD; mutability is the string "mutable" inside roles[], not a top-level key; omitted fields are absent (presence-detection, not null-checks). A block scope carries scope:'block' and no name. The module rung spans the whole module — a constant declared in a sibling file appears with an extra 'file' key (its 'line' is a line in THAT file). verbosity:'summary' keeps each scope's symbolNames only.
Arguments
| Argument | Type | Required | What it is |
|---|---|---|---|
column | integer | 0-based char offset of the target identifier on 'line' (an IDE cursor). OMIT it and pass symbol:'<name>' instead, or omit both and the first identifier on the line is taken (right for a declaration line). Reuse a column from ek9_inspect_symbol_at_cursor verbatim. | |
file | string | yes | The EK9 source file path |
line | integer | 1-based line of the declaration or a reference - OMIT it and pass symbol:'<name>' to let the tool find the line (a model counting lines in a file miscounts); if you do count, use ek9_read_file(lineNumbers:true). | |
symbol | string | The identifier you mean on 'line' (e.g. 'sayHello'); the tool finds its column. Prefer this to column - a column is a 0-based character offset an IDE supplies. |
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.
Cross file module symbols
Request
{
"file" : "orders.ek9",
"line" : 8
}
Response
{
"activeGuards" : [ ],
"meta" : {
"serverMs" : "<timing>"
},
"purityConstraint" : "non-pure",
"scopeChain" : [ {
"purityContext" : "non-pure",
"scope" : "block",
"symbols" : [ {
"kind" : "VARIABLE",
"line" : 7,
"name" : "stdout",
"roles" : [ "initialised", "mutable" ],
"state" : "set",
"type" : "Stdout"
} ],
"type" : "block"
}, {
"name" : "_main",
"pure" : false,
"purityContext" : "non-pure",
"returnVariable" : {
"kind" : "PARAMETER",
...
Cut short here: 59 more lines. The whole recorded call.
Visible symbols shape
Request
{
"file" : "MyRecord.ek9",
"line" : 5
}
Response
{
"activeGuards" : [ ],
"meta" : {
"serverMs" : "<timing>"
},
"purityConstraint" : "non-pure",
"scopeChain" : [ {
"name" : "MyRecord",
"purityContext" : "non-pure",
"scope" : "aggregate:MyRecord",
"symbols" : [ {
"kind" : "FIELD",
"line" : 6,
"name" : "name",
"roles" : [ "field", "initialised", "mutable" ],
"state" : "set",
"type" : "String"
}, {
"kind" : "METHOD",
"line" : 7,
"name" : "?",
"roles" : [ "initialised", "pure" ],
"state" : "set",
"type" : "Boolean"
...
Cut short here: 102 more lines. The whole recorded call.