ek9_add_method

Inserts the method (signature, a require-guarded stub body and the return) at the construct's canonical member position; answers status, edits[] and summary, a same-signature method as conflicts[] (signature-collision). Records reject named methods.

Category: Editor · Compare: Generate Method (IntelliJ) / Override/Implement Method

When to use it

'Add a method to CustomerOrder' is one call with symbol:'CustomerOrder', name, parameters:['code as Integer'], returnType and statements:['rtn: ...'] (the body) - no file, no line, nothing left to fill.

When not to use it

Details

Inserts exactly ONE method per call; a same-signature second call yields status:conflicts (kind 'signature-collision' — rename, change the parameter shape, or add override:true if overriding an inherited method). status:error when the target genus rejects methods (record/program/text/enumeration …) or isAbstract targets a non-abstract class/component. No override-inheritance analysis is performed — a bad override surfaces only on the apply-path verify compile as would-fail.

Arguments

ArgumentTypeRequiredWhat it is
emptyBodybooleanWhen true, generate ONLY the signature (declaration + parameters + return-with-default) with no placeholder body - no 'require param?' preconditions, no '//AI' lead, for a body you then supply with ek9_insert_statements. NOTE: EK9 flags unused parameters, so a shell WITH parameters will would-fail on apply until a body uses them; only the no-parameter-with-return shape compiles standalone.
filestringThe EK9 source file - OPTIONAL when symbol is a construct name; required to anchor on a member or a use site.
isAbstractbooleanAdd 'as abstract'. Only valid on traits and classes already marked 'as abstract'.
namestringyesThe new method's name (camelCase).
overridebooleanAdd 'override' prefix when overriding a parent or trait method.
parametersarray of anyParameter list, 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. Empty / omitted means a no-arg method.
purebooleanAdd 'as pure' modifier. Default false.
returnTypestringReturn TYPE only, e.g. 'String', 'List of Integer' - never '<- rtn as String', never a name: the tool writes the '<- rtn as <Type>?' declaration, and the body assigns 'rtn: <expr>'. Omitted means no return.
statementsarray of stringThe body, one statement or one block per entry (assign 'rtn: <value>' on every path when there is a return): the method is complete in this call - no stub, no second ek9_insert_statements call. Parsed alone first; a problem names the entry and its fix.
symbolstringyesThe class, trait, component or service the method is added to - a bare name ('Order') finds its file workspace-wide; 'mod::Order' when the name is declared in two modules.
visibilitystring: public | private | protectedThe method's access. Default 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 9 recorded are shown.

One of two trait members is progress

Request

{
  "name" : "area",
  "override" : true,
  "pure" : true,
  "returnType" : "Float",
  "statements" : [ "rtn: side * side" ],
  "symbol" : "Square"
}

Response

{
  "conflicts" : [ ],
  "edits" : [ {
    "after" : "\n      override area() as pure\n        <- rtn as Float?\n        rtn: side * side",
    "endLine" : 23,
    "file" : "task.ek9",
    "startLine" : 23,
    "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 method 'area' to Square",
  "workspaceHash" : "<workspace-hash>",
...

Cut short here: 3 more lines. The whole recorded call.

Return type with question mark

Request

{
  "name" : "sayCount",
  "parameters" : [ {
    "name" : "count",
    "type" : "Integer"
  } ],
  "pure" : true,
  "returnType" : "String?",
  "statements" : [ "rtn: count == 0 <- \"empty\" : count == 1 <- \"one item\" : $count + \" items\"" ],
  "symbol" : "Basket",
  "verbosity" : "summary"
}

Response

{
  "conflicts" : [ ],
  "corrected" : [ "returnType 'String?' read as 'String' - the return is declared '<- rtn as String?' already" ],
  "edits" : [ {
    "endLine" : 18,
    "file" : "task.ek9",
    "startLine" : 18,
    "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 method 'sayCount' to Basket",
  "workspaceHash" : "<workspace-hash>",
...

Cut short here: 3 more lines. The whole recorded call.

Add no arg pure method apply

Request

{
  "constructName" : "Greeter",
  "file" : "Greeter.ek9",
  "name" : "farewell",
  "pure" : true
}

Response

{
  "conflicts" : [ ],
  "edits" : [ {
    "after" : "\n      farewell() as pure\n        ready <- true\n        require ready?\n        //AI: Implement farewell",
    "endLine" : 10,
    "file" : "Greeter.ek9",
    "startLine" : 10,
    "type" : "insert"
  } ],
  "meta" : {
    "serverMs" : "<timing>"
  },
  "resolvedPath" : "<workspace-root>/Greeter.ek9",
  "risk" : {
    "crossesModuleBoundary" : false,
    "estimatedSeverity" : "trivial",
    "fileCount" : 1,
    "lineCount" : 1,
    "touchesPublicApi" : false,
    "touchesTests" : false
  },
  "status" : "applied",
  "summary" : "Added method 'farewell' to Greeter",
  "workspaceHash" : "<workspace-hash>",
...

Cut short here: 3 more lines. The whole recorded call.

See also