ek9_make_closed

Strips 'as open' from the declaration so the construct can no longer be extended; answers status, edits[] and conflicts[] naming every subtype (kind 'subtype') that would break with E05030.

Category: Editor · Compare: Refactor → Make Class Closed / Final

When to use it

'Close Animal to extension' is one call with symbol:'Animal' - no file or line needed. Use it on an 'as open' class/record/component/function with NO subtypes to return it to EK9's closed-by-default.

When not to use it

Details

Supports class/record/component/function (all carry the optional 'as open'); traits are always open and rejected as an unsupported construct. status:'conflicts' with kind:'subtype' (an escalation — human must decide) when any workspace subtype would hit E05030 (NOT_OPEN_TO_EXTENSION), and kind:'already-closed' when there is nothing to do; status:'error' when the target is abstract (hint: ek9_make_concrete) or sealed (hint: ek9_unseal_type). Closed is the ABSENCE of 'as open' — there is no 'as closed' keyword.

Arguments

ArgumentTypeRequiredWhat it is
filestringThe EK9 source file - OPTIONAL when symbol is a construct name; required to anchor on a member or a use site.
lineinteger1-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).
symbolstringA 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.

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.

Make closed abstract refused

Request

{
  "file" : "main.ek9",
  "line" : 15
}

Response

{
  "conflicts" : [ ],
  "edits" : [ ],
  "error" : {
    "message" : "Cannot close an abstract class — remove 'as abstract' first (make concrete)"
  },
  "meta" : {
    "serverMs" : "<timing>"
  },
  "status" : "error",
  "summary" : "Cannot close an abstract class — remove 'as abstract' first (make concrete)",
  "wouldBeDiagnostics" : [ ],
  "written" : false
}

Make closed already closed noop

Request

{
  "file" : "main.ek9",
  "line" : 19
}

Response

{
  "conflicts" : [ {
    "kind" : "already-closed",
    "message" : "Class is already closed — no change needed"
  } ],
  "edits" : [ ],
  "meta" : {
    "serverMs" : "<timing>"
  },
  "risk" : {
    "crossesModuleBoundary" : false,
    "estimatedSeverity" : "trivial",
    "fileCount" : 0,
    "lineCount" : 0,
    "touchesPublicApi" : false,
    "touchesTests" : false
  },
  "status" : "conflicts",
  "summary" : "Class is already closed — no change needed",
  "workspaceHash" : "<workspace-hash>",
  "wouldBeDiagnostics" : [ ],
  "written" : false
}

Make closed with subclasses

Request

{
  "file" : "main.ek9",
  "line" : 5
}

Response

{
  "conflicts" : [ {
    "fullyQualifiedName" : "net.test.classmod::Dog",
    "kind" : "subtype",
    "line" : 10,
    "name" : null
  } ],
  "edits" : [ ],
  "meta" : {
    "serverMs" : "<timing>"
  },
  "risk" : {
    "crossesModuleBoundary" : false,
    "estimatedSeverity" : "trivial",
    "fileCount" : 0,
    "lineCount" : 0,
    "touchesPublicApi" : false,
    "touchesTests" : false
  },
  "status" : "conflicts",
  "summary" : "Animal has 1 subtype(s) that would break if closed",
  "workspaceHash" : "<workspace-hash>",
  "wouldBeDiagnostics" : [ ],
  "written" : false
...

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

See also