ek9_query_flow
Answers first: status, branchCount, loopCount, guardCount, deadBranchCount, then method{name, fullyQualifiedName, signature, declaredAt}, isPure, metrics (cyclomatic/cognitive), flowNodes (the guard-tracked branch/loop tree) and deepAnalysis (provably dead branches, redundant tri-state checks).
When to use it
'How does this method or function flow inside - branches, loops, guards, dead code, complexity' is one call with symbol:'Type.method' - no file or line needed.
When not to use it
- method-to-method call relationships, who calls it or what it calls (use
ek9_query_call_graph) - a body that is a stream pipeline and you want stage-level analysis (use
ek9_query_pipeline) - just complexity numbers across MANY methods workspace-wide (use
ek9_query_complexity) - the structural outline of a class/record, not the flow of a body (use
ek9_query_construct)
Details
Uses on-demand IR generation: flow is available after PRE_IR_CHECKS (Phase 5), no full IR_GENERATION compile needed — fast and usable mid-edit. metrics{cyclomaticComplexity, cognitiveComplexity, lineCount, maxNestingDepth, branchCount, loopCount, guardCount}; flowNodes[] (the IF_ELSE_IF/WHILE_LOOP/SWITCH/TRY_CATCH_FINALLY/FOR_RANGE/… tree with depth/children/per-node guard); guards[] {introducedAt, guarantee}; deepAnalysis {deadBranches — PROVABLY unreachable, redundantChecks — tri-state checks the compiler already proved, guaranteedVariables}. Missing source, no IR construct, or failed IR generation returns status:'not-found' with a note; a line not on a specific method falls back to the construct's best default operation, so anchor precisely (symbol:'Type.method' does); cyclomatic>10, cognitive>15 or non-empty overlays flag refactor candidates for ek9_extract_method / ek9_remove_statements / ek9_apply_guard_pattern.
Arguments
| Argument | Type | Required | What it is |
|---|---|---|---|
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 anywhere inside the method/function or on its declaration - OMIT it and pass symbol:'Type.method' to let the tool find the line (a model counting lines miscounts). | |
symbol | string | A construct NAME alone ('Shape', 'sample.deps.core::Validator') - no file needed, the tool finds it workspace-wide; or, with file (+ line), the identifier you mean there. |
Recorded calls
Real calls, recorded against small projects and checked on every build - a changed answer fails it.
Flow shape
Request
{
"file" : "Hello.ek9",
"line" : 6
}
Response
{
"branchCount" : 0,
"deadBranchCount" : 0,
"deepAnalysis" : {
"deadBranches" : [ ],
"guaranteedVariables" : [ ],
"redundantChecks" : [ ]
},
"flowNodes" : [ ],
"guardCount" : 0,
"guards" : [ ],
"inConstruct" : "Main",
"inConstructFqn" : "com.example.hello::Main",
"isPure" : false,
"loopCount" : 0,
"meta" : {
"serverMs" : "<timing>"
},
"method" : {
"declaredAt" : {
"file" : "Hello.ek9",
"line" : 5
},
"fullyQualifiedName" : "com.example.hello::Main",
...
Cut short here: 16 more lines. The whole recorded call.