ek9_add_operator
Inserts the operator declaration (or the bare 'default operator' block) at the construct's canonical operator position; answers status, edits[] and summary - 'unchanged', naming where it is, for a default operator the construct already declares; statements[] for an operator already written by hand replace its body, and body:'explicit' over one names the insert route in conflicts[].
When to use it
'Add operator $ to Point' is one call with symbol:'Point', operator:'$' and statements:['rtn: ...'] (its body); body:'default' synthesises a defaultable one (==, <=>, ?).
When not to use it
- The member is a regular METHOD with an ordinary identifier name - use
ek9_add_method; a CONSTRUCTOR (the type's own name) - useek9_add_constructor. - You want to CHECK whether an existing operator is contract-compliant - the compiler already reports it; use
ek9_query_diagnostics/ek9_explain_error. (A NEW operator's purity is derived here, so E07500/E07510 cannot reach you from this tool.) - You want to implement TRAIT methods in bulk - use
ek9_implement_methods. - The target type does not exist yet - use
ek9_new_construct.
Details
body:'default' with an operator emits 'default operator <sym>' for that one op; with no operator it emits the bare 'default operator' (compiler synthesises every missing defaultable op; errors if a default block already exists). body:'explicit' generates a field-based implementation stub you fill in (templates for the defaultable set plus the arithmetic/word-form ops; needs at least one field) and is the only form also allowed on traits. The operator is given in EK9 source form ('==' not '_eq'); pipeline keywords (sort, filter, …) are rejected and the deprecated '!=' is applied as '<>' (E07640) with the summary saying so. A duplicate operator symbol returns status:'conflicts' (kind 'signature-collision') naming the ek9_expand_default_operator route - operator semantics are load-bearing; surface to the human rather than retry (pre-check via ek9_query_construct → operators[]).
Arguments
| Argument | Type | Required | What it is |
|---|---|---|---|
body | string: default | explicit | default (the default): a 'default operator' declaration the compiler synthesises from the fields; explicit: a field-based stub for you to complete. | |
file | string | The EK9 source file - OPTIONAL when symbol is a construct name; required to anchor on a member or a use site. | |
operator | string | The operator in EK9 source form: '==', '<=>', '<>', '?', '$', '#?', ':=:', '+', 'mod', … Omit it with body:'default' to default every defaultable operator at once. | |
pure | boolean | IGNORED for a known operator and not worth sending - purity is not a choice. The language fixes it: every non-mutating operator must be 'as pure' (E07500) and the ten mutators ':~: :^: :=: | += -= *= /= ++ --' must not be (E07510). It is derived and the response says so in 'corrected' when your value differed. | |
statements | array of string | The operator's body, one statement or one block per entry (assign 'rtn: <value>' on every path): the operator is complete in this call - override, pure and the language-fixed signature are filled in. Needs 'operator'; 'body' is then ignored. For an operator the construct already implements by hand, its body is REPLACED (the signature stays). | |
symbol | string | yes | The class, record, component, enumeration (or trait, for an explicit body) the operator is added to - a bare name ('Point') finds its file workspace-wide; 'mod::Point' when the name is declared in two modules. |
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 26 recorded are shown.
Add default equality apply
Request
{
"body" : "default",
"constructName" : "Point",
"file" : "Point.ek9",
"operator" : "=="
}
Response
{
"conflicts" : [ ],
"edits" : [ ],
"error" : {
"message" : "'==' on Point is generated from its '<=>' (E07181). If '==' should compare more, add those fields to '<=>' as tie-breakers."
},
"meta" : {
"serverMs" : "<timing>"
},
"status" : "error",
"summary" : "'==' on Point is generated from its '<=>' (E07181). If '==' should compare more, add those fields to '<=>' as tie-breakers.",
"wouldBeDiagnostics" : [ ],
"written" : false
}
Default operator already declared unchanged
Request
{
"body" : "default",
"operator" : "?",
"symbol" : "Basket"
}
Response
{
"conflicts" : [ ],
"edits" : [ ],
"meta" : {
"serverMs" : "<timing>"
},
"risk" : {
"crossesModuleBoundary" : false,
"estimatedSeverity" : "trivial",
"fileCount" : 0,
"lineCount" : 0,
"touchesPublicApi" : false,
"touchesTests" : false
},
"status" : "unchanged",
"summary" : "Not added: Basket already has 'default operator ?' (<workspace-root>/task.ek9:18) - nothing to do.",
"workspaceHash" : "<workspace-hash>",
"wouldBeDiagnostics" : [ ],
"written" : false
}
Moved error is not new
Request
{
"body" : "default",
"symbol" : "Basket"
}
Response
{
"conflicts" : [ ],
"edits" : [ {
"after" : " default operator",
"endLine" : 19,
"file" : "task.ek9",
"startLine" : 19,
"type" : "insert"
} ],
"meta" : {
"serverMs" : "<timing>"
},
"resolvedPath" : "<workspace-root>/task.ek9",
"risk" : {
"crossesModuleBoundary" : false,
"estimatedSeverity" : "trivial",
"fileCount" : 1,
"lineCount" : 1,
"touchesPublicApi" : false,
"touchesTests" : false
},
"status" : "applied",
"summary" : "Added 'default operator' to Basket",
"workspaceHash" : "<workspace-hash>",
...
Cut short here: 3 more lines. The whole recorded call.
See also
- Show me in the IDE: Chapter 14: a record, built
- Show me in the IDE: Chapter 18: traits and delegation, built
- Show me in the IDE: Chapter 21: operators, built
- Show me in the IDE: Chapter 21: promotion, #^
- Show me in the IDE: Chapter 23: the game, built and played