ek9_remove_statements
Deletes a contiguous statement range from one method/function/operator body; answers status and edits[] (one DELETE per line), or conflicts[] (range-straddles-method-boundary, range-not-on-statement-boundary, removed-statement-declares-used-local, removal-is-a-replacement, range-empties-body).
When to use it
'Delete these two statements inside the body' is one call with file, fromText and toText (the first and last line as written), or startLine:36, endLine:37 - the range must sit inside ONE method/function/operator body on statement boundaries. Use it to drop specific statements without a read + full-text rewrite (the second tool in a force-delete cleanup loop).
When not to use it
- Removing an unused entry from the references block (not body statements) - use
ek9_organize_references(often run AFTER this tool). - Removing the `<- rtn` return-value declaration (a signature change) - use
ek9_change_signature; removing a class/record FIELD - useek9_remove_field. - Moving a block to a new method rather than dropping it - use
ek9_extract_method; removing a whole function/method by inlining it at call sites - useek9_inline_function. - The range is NOT inside a body - use
ek9_edit_fileline-replace with empty replacement (references block, package metadata) orek9_remove_comments(whole-line comment blocks); deleting the entire file - useek9_delete_file.
Details
Range MUST stay within one body and align with statement boundaries. Conflict kinds: range-straddles-method-boundary (mechanical - narrow to one body; a WHOLE member goes through ek9_safe_delete), range-not-on-statement-boundary (mechanical - response carries the boundary-snapped range to re-issue), range-includes-return-value-declaration (use ek9_change_signature). Before any compile the removal CLOSURE is computed by symbol (a kept statement using a removed local goes too; so does a kept local whose every read is removed): one range that compiles is removed-statement-declares-used-local / removal-leaves-unread-local with that exact range in details; gaps or the whole body is removal-is-a-replacement (no widening compiles - the new statements go in with ek9_edit_file line-replace or ek9_insert_statements anchor:'replace'); range-empties-body when every statement goes and the return is not initialised. Statement extents are ANTLR-derived so comments and string literals never false-match; indentation and unrelated statements are preserved.
Arguments
| Argument | Type | Required | What it is |
|---|---|---|---|
endLine | integer | Or the last line to remove (1-based, inclusive). Must be inside the SAME body as startLine, must align with a statement boundary, must be >= startLine. | |
file | string | yes | Workspace-relative path to the .ek9 source file containing the target body. |
fromText | string | The block's FIRST line exactly as written (indentation ignored) - instead of counting startLine. Must name one line; add more of it when it occurs twice. | |
startLine | integer | Or the first line to remove (1-based, inclusive) - an IDE selection. Must be inside a method/function/operator body and must align with a statement boundary. | |
toText | string | The block's LAST line as written - the first line matching it at or after fromText. Omit it for a one-line block. |
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 6 recorded are shown.
Remove single statement apply
Request
{
"endLine" : 8,
"file" : "Hello.ek9",
"startLine" : 8
}
Response
{
"conflicts" : [ ],
"edits" : [ {
"before" : " stdout.println(\"Removable\")",
"endLine" : 8,
"file" : "Hello.ek9",
"startLine" : 8,
"type" : "delete"
} ],
"meta" : {
"serverMs" : "<timing>"
},
"resolvedPath" : "<workspace-root>/Hello.ek9",
"risk" : {
"crossesModuleBoundary" : false,
"estimatedSeverity" : "trivial",
"fileCount" : 1,
"lineCount" : 1,
"touchesPublicApi" : false,
"touchesTests" : false
},
"status" : "applied",
"summary" : "Removed statements 8-8 from com.example.hello::_main",
"workspaceHash" : "<workspace-hash>",
...
Cut short here: 3 more lines. The whole recorded call.
Range empties body
Request
{
"endLine" : 17,
"file" : "task.ek9",
"startLine" : 7
}
Response
{
"conflicts" : [ {
"kind" : "range-empties-body",
"message" : "range 7-17 removes every statement of program 'Main' (declared on line 6), which has no initialised return to stand for a body - the removal would not compile (an implementation must be provided). To re-implement it: ek9_insert_statements(symbol:'Main', anchor:'replace', statements:[...]); to delete it: ek9_safe_delete(file, line:6)"
} ],
"edits" : [ ],
"meta" : {
"serverMs" : "<timing>"
},
"risk" : {
"crossesModuleBoundary" : false,
"estimatedSeverity" : "trivial",
"fileCount" : 0,
"lineCount" : 0,
"touchesPublicApi" : false,
"touchesTests" : false
},
"status" : "conflicts",
"summary" : "Cannot remove statements 7-17 from coder.t9::_main — 1 conflict",
"workspaceHash" : "<workspace-hash>",
"wouldBeDiagnostics" : [ ],
"written" : false
}
Range from declaration line refused
Request
{
"endLine" : 21,
"file" : "task.ek9",
"startLine" : 16
}
Response
{
"conflicts" : [ {
"details" : "20-21",
"kind" : "range-includes-signature",
"message" : "range 16-21 starts above the body of 'public Order <- Order(customerName as String, total as Float)' (declared on line 16) - its statements are lines 20-21; removing line 16 would delete the declaration. To remove statements use a range inside 20-21; to delete the whole member use ek9_safe_delete(file, line:16)"
} ],
"edits" : [ ],
"meta" : {
"serverMs" : "<timing>"
},
"risk" : {
"crossesModuleBoundary" : false,
"estimatedSeverity" : "trivial",
"fileCount" : 0,
"lineCount" : 0,
"touchesPublicApi" : false,
"touchesTests" : false
},
"status" : "conflicts",
"summary" : "Cannot remove statements 16-21 from coder.t11::Order — 1 conflict",
"workspaceHash" : "<workspace-hash>",
"wouldBeDiagnostics" : [ ],
"written" : false
}