autofix: clean up dupe 'remove capture' action detection

This commit is contained in:
Travis Staloch 2023-05-26 20:55:48 -07:00
parent 49b679ee22
commit 32dc6c32ea
No known key found for this signature in database
GPG Key ID: 9726F5C64475E635
2 changed files with 20 additions and 23 deletions

View File

@ -244,8 +244,9 @@ pub fn autofix(server: *Server, allocator: std.mem.Allocator, handle: *const Doc
}; };
var actions = std.ArrayListUnmanaged(types.CodeAction){}; var actions = std.ArrayListUnmanaged(types.CodeAction){};
var remove_capture_actions = std.AutoHashMapUnmanaged(types.Range, void){};
for (diagnostics.items) |diagnostic| { for (diagnostics.items) |diagnostic| {
try builder.generateCodeAction(diagnostic, &actions); try builder.generateCodeAction(diagnostic, &actions, &remove_capture_actions);
} }
var text_edits = std.ArrayListUnmanaged(types.TextEdit){}; var text_edits = std.ArrayListUnmanaged(types.TextEdit){};
@ -1200,8 +1201,9 @@ fn codeActionHandler(server: *Server, request: types.CodeActionParams) Error!?[]
} }
var actions = std.ArrayListUnmanaged(types.CodeAction){}; var actions = std.ArrayListUnmanaged(types.CodeAction){};
var remove_capture_actions = std.AutoHashMapUnmanaged(types.Range, void){};
for (diagnostics.items) |diagnostic| { for (diagnostics.items) |diagnostic| {
try builder.generateCodeAction(diagnostic, &actions); try builder.generateCodeAction(diagnostic, &actions, &remove_capture_actions);
} }
return actions.items; return actions.items;

View File

@ -14,7 +14,12 @@ pub const Builder = struct {
handle: *const DocumentStore.Handle, handle: *const DocumentStore.Handle,
offset_encoding: offsets.Encoding, offset_encoding: offsets.Encoding,
pub fn generateCodeAction(builder: *Builder, diagnostic: types.Diagnostic, actions: *std.ArrayListUnmanaged(types.CodeAction)) error{OutOfMemory}!void { pub fn generateCodeAction(
builder: *Builder,
diagnostic: types.Diagnostic,
actions: *std.ArrayListUnmanaged(types.CodeAction),
remove_capture_actions: *std.AutoHashMapUnmanaged(types.Range, void),
) error{OutOfMemory}!void {
const kind = DiagnosticKind.parse(diagnostic.message) orelse return; const kind = DiagnosticKind.parse(diagnostic.message) orelse return;
const loc = offsets.rangeToLoc(builder.handle.text, diagnostic.range, builder.offset_encoding); const loc = offsets.rangeToLoc(builder.handle.text, diagnostic.range, builder.offset_encoding);
@ -24,12 +29,12 @@ pub const Builder = struct {
.@"function parameter" => try handleUnusedFunctionParameter(builder, actions, loc), .@"function parameter" => try handleUnusedFunctionParameter(builder, actions, loc),
.@"local constant" => try handleUnusedVariableOrConstant(builder, actions, loc), .@"local constant" => try handleUnusedVariableOrConstant(builder, actions, loc),
.@"local variable" => try handleUnusedVariableOrConstant(builder, actions, loc), .@"local variable" => try handleUnusedVariableOrConstant(builder, actions, loc),
.@"switch tag capture", .capture => try handleUnusedCapture(builder, actions, loc), .@"switch tag capture", .capture => try handleUnusedCapture(builder, actions, loc, remove_capture_actions),
}, },
.non_camelcase_fn => try handleNonCamelcaseFunction(builder, actions, loc), .non_camelcase_fn => try handleNonCamelcaseFunction(builder, actions, loc),
.pointless_discard => try handlePointlessDiscard(builder, actions, loc), .pointless_discard => try handlePointlessDiscard(builder, actions, loc),
.omit_discard => |id| switch (id) { .omit_discard => |id| switch (id) {
.@"error capture" => try handleUnusedCapture(builder, actions, loc), .@"error capture" => try handleUnusedCapture(builder, actions, loc, remove_capture_actions),
}, },
// the undeclared identifier may be a discard // the undeclared identifier may be a discard
.undeclared_identifier => try handlePointlessDiscard(builder, actions, loc), .undeclared_identifier => try handlePointlessDiscard(builder, actions, loc),
@ -164,7 +169,12 @@ fn handleUnusedVariableOrConstant(builder: *Builder, actions: *std.ArrayListUnma
}); });
} }
fn handleUnusedCapture(builder: *Builder, actions: *std.ArrayListUnmanaged(types.CodeAction), loc: offsets.Loc) !void { fn handleUnusedCapture(
builder: *Builder,
actions: *std.ArrayListUnmanaged(types.CodeAction),
loc: offsets.Loc,
remove_capture_actions: *std.AutoHashMapUnmanaged(types.Range, void),
) !void {
const tracy_zone = tracy.trace(@src()); const tracy_zone = tracy.trace(@src());
defer tracy_zone.end(); defer tracy_zone.end();
@ -199,23 +209,8 @@ fn handleUnusedCapture(builder: *Builder, actions: *std.ArrayListUnmanaged(types
// prevent adding duplicate 'remove capture' action. // prevent adding duplicate 'remove capture' action.
// search for a matching action by comparing ranges. // search for a matching action by comparing ranges.
const remove_cap_loc = builder.createTextEditLoc(capture_loc, ""); const remove_cap_loc = builder.createTextEditLoc(capture_loc, "");
const found_remove_capture_action = outer: for (actions.items) |item| { const gop = try remove_capture_actions.getOrPut(builder.arena, remove_cap_loc.range);
const edit = item.edit orelse continue; if (gop.found_existing)
const changes = edit.changes orelse continue;
var iter = changes.iterator();
while (iter.next()) |entry| {
const t_edits = entry.value_ptr.*;
for (t_edits) |t_edit| {
if (remove_cap_loc.range.start.line == t_edit.range.start.line and
remove_cap_loc.range.start.character == t_edit.range.start.character and
remove_cap_loc.range.end.line == t_edit.range.end.line and
remove_cap_loc.range.end.character == t_edit.range.end.character)
break :outer true;
}
}
} else false;
if (found_remove_capture_action)
try actions.appendSlice(builder.arena, &.{ action1, action2 }) try actions.appendSlice(builder.arena, &.{ action1, action2 })
else { else {
const action0 = types.CodeAction{ const action0 = types.CodeAction{