ek9_safe_delete
Deletes a top-level construct or a class/record/component member - or several as one change - after a workspace-wide reference check; answers status and edits[] (one DELETE per line), or conflicts[] with one 'construct-still-referenced' entry per citing site.
When to use it
'Delete OrderProcessor if nothing uses it' is one call with symbol:'OrderProcessor' - no file or line needed (a member is 'Type.member'). Use it to DELETE a top-level construct or a class/record/component member with a workspace-wide reference check blocking it while anything still uses the target.
When not to use it
- You only want to KNOW the reference count, not delete - use
ek9_query_references. - You want to DISCOVER deletion candidates across the workspace — use
ek9_find_unused_code. - The construct should be RENAMED, not deleted — use
ek9_rename_symbol. - A method should keep existing but shed parameters — use
ek9_change_signature.
Details
Live references yield status:'conflicts', NOT an error — one conflicts[] entry per citing site (kind 'construct-still-referenced'; only the declaration site is excluded from the count); references are intentional, so surface them rather than silently retrying. Single-file V1: anchoring on a usage of a symbol declared elsewhere (or an external/built-in symbol) errors and names the declaring file; non-deletable kinds (enum values, individual references-block entries, statements) also error. A top-level deletion that empties its file attaches a 'file-emptied' advisory pointing at ek9_delete_file; override/sealed coupling is not pre-checked in V1 and surfaces as a post-apply compile failure.
Arguments
| Argument | Type | Required | What it is |
|---|---|---|---|
column | integer | 0-based char offset of the target identifier on 'line' (an IDE cursor). OMIT it and pass symbol:'<name>' instead, or omit both and the first identifier on the line is taken (right for a declaration line). Reuse a column from ek9_inspect_symbol_at_cursor verbatim. | |
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. | |
symbols | array of string | Several to delete as ONE change - all or none (e.g. a dead method and its dead callers: ['reportTitles','Product.getTitle'], in any order). Instead of symbol. |
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 16 recorded are shown.
Safe delete same basename other directory
Request
{
"file" : "app/rates.ek9",
"line" : 5,
"symbol" : "discount"
}
Response
{
"conflicts" : [ ],
"edits" : [ ],
"error" : {
"message" : "Target 'discount' is declared in file://<workspace-root>/other/rates.ek9 — open that file and place the cursor on its declaration to delete it"
},
"meta" : {
"serverMs" : "<timing>"
},
"status" : "error",
"summary" : "Target 'discount' is declared in file://<workspace-root>/other/rates.ek9 — open that file and place the cursor on its declaration to delete it",
"wouldBeDiagnostics" : [ ],
"written" : false
}
Safe delete module constant apply
Request
{
"file" : "Limits.ek9",
"line" : 7,
"symbol" : "OLD_LIMIT"
}
Response
{
"conflicts" : [ ],
"edits" : [ {
"before" : " OLD_LIMIT <- 99",
"endLine" : 7,
"file" : "Limits.ek9",
"startLine" : 7,
"type" : "delete"
} ],
"meta" : {
"serverMs" : "<timing>"
},
"resolvedPath" : "<workspace-root>/Limits.ek9",
"risk" : {
"crossesModuleBoundary" : false,
"estimatedSeverity" : "high",
"fileCount" : 1,
"lineCount" : 1,
"touchesPublicApi" : true,
"touchesTests" : false
},
"status" : "applied",
"summary" : "Deleted constant OLD_LIMIT",
"workspaceHash" : "<workspace-hash>",
...
Cut short here: 3 more lines. The whole recorded call.
Safe delete module constant by bare name
Request
{
"symbol" : "OLD_LIMIT"
}
Response
{
"conflicts" : [ ],
"edits" : [ {
"before" : " OLD_LIMIT <- 99",
"endLine" : 7,
"file" : "Limits.ek9",
"startLine" : 7,
"type" : "delete"
} ],
"meta" : {
"serverMs" : "<timing>"
},
"resolvedPath" : "<workspace-root>/Limits.ek9",
"risk" : {
"crossesModuleBoundary" : false,
"estimatedSeverity" : "high",
"fileCount" : 1,
"lineCount" : 1,
"touchesPublicApi" : true,
"touchesTests" : false
},
"status" : "applied",
"summary" : "Deleted constant OLD_LIMIT",
"workspaceHash" : "<workspace-hash>",
...
Cut short here: 3 more lines. The whole recorded call.
See also
- Show me in the IDE: Safe Delete
- Show me in the IDE: Unused Code