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[].

Category: Editor · Compare: Generate Operator (no direct equivalent — EK9-specific)

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

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

ArgumentTypeRequiredWhat it is
bodystring: default | explicitdefault (the default): a 'default operator' declaration the compiler synthesises from the fields; explicit: a field-based stub for you to complete.
filestringThe EK9 source file - OPTIONAL when symbol is a construct name; required to anchor on a member or a use site.
operatorstringThe operator in EK9 source form: '==', '<=>', '<>', '?', '$', '#?', ':=:', '+', 'mod', … Omit it with body:'default' to default every defaultable operator at once.
purebooleanIGNORED 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.
statementsarray of stringThe 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).
symbolstringyesThe 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