ek9_generate_dispatcher
Inserts the '<name>() as dispatcher' entry with its fallback body plus one same-named handler overload per subtype of the base type; answers status, edits[] and summary naming any existing handlers kept.
When to use it
'Give ShapeProcessor a describe() dispatcher over Shape' is one call with symbol:'ShapeProcessor', name:'describe' and baseType:'Shape'.
When not to use it
- Adding ONE method rather than a dispatcher + handler set - use
ek9_add_method. - Registering a NEW subtype on the sealed base (not generating handlers) - use
ek9_add_to_sealed_allowlist. - INSPECTING existing dispatcher tables, not generating new ones - use
ek9_query_dispatchers. - The dispatcher CLASS does not exist yet - create it with
ek9_new_constructfirst, then run this on it.
Details
Class targets only (errors on record/trait/component); handlers REUSE the entry's name - overload-by-parameter-type IS the dispatch mechanism (E05260), there is no '<name>For<Subtype>' convention. The entry is concrete: its guard-first fallback body ('require' guard, '//AI:' marker, and for a returning dispatcher '<- rtn as T?' assigned only after the guard) is also the runtime default when no handler matches; sealed base → one handler per 'allow only' subtype (compiler enforces exhaustiveness), non-sealed base → known concrete subtypes only with the fallback covering the rest (errors if none known). Never returns 'conflicts': an existing dispatcher on the class (E07820) or a same-named non-dispatcher method taking the base type is an error; an existing per-subtype handler is silently skipped and named in the summary.
Arguments
| Argument | Type | Required | What it is |
|---|---|---|---|
additionalParameters | array of any | Optional extra parameters added to BOTH the entry and every handler, after the auto-added subtype parameter; each ONE item as DATA - {name:'code', type:'Integer'} - never a {name} and a {type} as two items, and never with '->' or '<-' in it; the tool writes the arrows and the layout. ('code as Integer' is also accepted.) A malformed item is rejected before anything is rendered. | |
baseType | string | yes | The type the dispatcher dispatches on. If SEALED, its 'allow only' subtypes drive handlers (exhaustive); if NON-SEALED, its known concrete subtypes do (entry fallback covers the rest). Fully-qualified (com.acme::Animal) when needed; simple name when unambiguous. |
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 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). | |
name | string | yes | The dispatcher method name (e.g. describe, sound, route). ALL generated handlers share this exact name. |
returnType | string | Optional shared return type for the entry + every handler. Omit for a void dispatcher. | |
symbol | string | yes | The class the dispatcher is scaffolded on - a bare name ('ShapeProcessor') finds its file and declaration workspace-wide; 'mod::Name' when the name is declared in two modules. |
visibility | string: private | public | protected | The handlers' access (default 'private' - handlers are implementation details). The entry is always public. |
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. 3 of the 7 recorded are shown.
Non class target
Request
{
"baseType" : "Shape",
"dispatcherMethodName" : "describe",
"file" : "shapes.ek9",
"line" : 6,
"returnType" : "String"
}
Response
{
"conflicts" : [ ],
"edits" : [ ],
"error" : {
"message" : "'Shape' is a trait - a dispatcher lives on a class only"
},
"meta" : {
"serverMs" : "<timing>"
},
"status" : "error",
"summary" : "'Shape' is a trait - a dispatcher lives on a class only",
"wouldBeDiagnostics" : [ ],
"written" : false
}
No subtypes
Request
{
"baseType" : "Circle",
"dispatcherMethodName" : "describe",
"file" : "shapes.ek9",
"line" : 36,
"returnType" : "String"
}
Response
{
"conflicts" : [ ],
"edits" : [ ],
"error" : {
"message" : "Type 'Circle' has no known subtypes to dispatch on — add subtypes first, or seal it with 'allow only ...' for exhaustive handlers"
},
"meta" : {
"serverMs" : "<timing>"
},
"status" : "error",
"summary" : "Type 'Circle' has no known subtypes to dispatch on — add subtypes first, or seal it with 'allow only ...' for exhaustive handlers",
"wouldBeDiagnostics" : [ ],
"written" : false
}
Second dispatcher
Request
{
"baseType" : "Shape",
"dispatcherMethodName" : "describe",
"file" : "shapes.ek9",
"line" : 40,
"returnType" : "String"
}
Response
{
"conflicts" : [ ],
"edits" : [ ],
"error" : {
"message" : "Class 'AlreadyDispatching' already has a dispatcher method 'route' (per E07820: only one method may be marked as dispatcher per class)"
},
"meta" : {
"serverMs" : "<timing>"
},
"status" : "error",
"summary" : "Class 'AlreadyDispatching' already has a dispatcher method 'route' (per E07820: only one method may be marked as dispatcher per class)",
"wouldBeDiagnostics" : [ ],
"written" : false
}
See also
- Show me in the IDE: Generate Dispatcher
- Fixes E05260