ek9_make_open
Appends 'as open' to the declaration so the construct can be extended; answers status and edits[] (one REPLACE on the declaration line), or conflicts[] when it is already open.
When to use it
'Open Animal for extension' is one call with symbol:'Animal' - no file or line needed. Use it when a closed (EK9's default) class/record/component/function must permit subclassing - a widening change that never breaks existing compile and resolves E05030.
When not to use it
- Removing 'as open' to lock a class down - use
ek9_make_closed. - Wanting 'as abstract' (implicitly open AND forces subclasses to supply bodies) — use
ek9_make_abstract. - Wanting a SEALED class ('as open' + 'allow only A, B, C', open to a fixed subclass list) — use
ek9_seal_type, which applies both modifications atomically. - Traits — always open already; rejected as an unsupported construct.
Details
Accepts class, record, component and function (both concrete and abstract functions). When the target is sealed ('allow only') but missing 'as open' (the E05270 contradiction), adding the modifier fixes it. An already-open or already-abstract (implicitly open) target is status:conflicts with kind 'already-open' / 'already-abstract'; an unsupported genus is status:error.
Arguments
| Argument | Type | Required | What it is |
|---|---|---|---|
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). | |
symbol | string | A 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. 3 of the 4 recorded are shown.
Make open already open noop
Request
{
"file" : "main.ek9",
"line" : 5
}
Response
{
"conflicts" : [ {
"kind" : "already-open",
"message" : "Class is already open — 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 open — no change needed",
"workspaceHash" : "<workspace-hash>",
"wouldBeDiagnostics" : [ ],
"written" : false
}
Make open apply
Request
{
"file" : "main.ek9",
"line" : 19
}
Response
{
"conflicts" : [ ],
"edits" : [ {
"after" : " ClosedBox as open",
"before" : " ClosedBox",
"endLine" : 19,
"file" : "main.ek9",
"startLine" : 19,
"type" : "replace"
} ],
"meta" : {
"serverMs" : "<timing>"
},
"risk" : {
"crossesModuleBoundary" : false,
"estimatedSeverity" : "trivial",
"fileCount" : 1,
"lineCount" : 1,
"touchesPublicApi" : false,
"touchesTests" : false
},
"status" : "applied",
"summary" : "Changed class ClosedBox → as open",
"workspaceHash" : "<workspace-hash>",
...
Cut short here: 3 more lines. The whole recorded call.
Make open dry run ready
Request
{
"dryRun" : true,
"file" : "main.ek9",
"line" : 19
}
Response
{
"conflicts" : [ ],
"edits" : [ {
"after" : " ClosedBox as open",
"before" : " ClosedBox",
"endLine" : 19,
"file" : "main.ek9",
"startLine" : 19,
"type" : "replace"
} ],
"meta" : {
"serverMs" : "<timing>"
},
"risk" : {
"crossesModuleBoundary" : false,
"estimatedSeverity" : "trivial",
"fileCount" : 1,
"lineCount" : 1,
"touchesPublicApi" : false,
"touchesTests" : false
},
"status" : "ready",
"summary" : "Would change class ClosedBox → as open",
"workspaceHash" : "<workspace-hash>",
...
Cut short here: 3 more lines. The whole recorded call.