fix textDocument/rename

This commit is contained in:
Techatrix 2022-08-29 21:28:05 +02:00
parent 2ac8ab6ce9
commit 605c4e2988
3 changed files with 39 additions and 38 deletions

View File

@ -1071,10 +1071,9 @@ fn renameDefinitionGlobal(
const decl = (try server.getSymbolGlobal(pos_index, handle)) orelse return try respondGeneric(writer, id, null_result_response); const decl = (try server.getSymbolGlobal(pos_index, handle)) orelse return try respondGeneric(writer, id, null_result_response);
var workspace_edit = types.WorkspaceEdit{ var workspace_edit = types.WorkspaceEdit{ .changes = .{} };
.changes = std.StringHashMapUnmanaged([]types.TextEdit){}, try rename.renameSymbol(&server.arena, &server.document_store, decl, new_name, &workspace_edit.changes, server.offset_encoding);
};
try rename.renameSymbol(&server.arena, &server.document_store, decl, new_name, &workspace_edit.changes.?, server.offset_encoding);
try send(writer, server.arena.allocator(), types.Response{ try send(writer, server.arena.allocator(), types.Response{
.id = id, .id = id,
.result = .{ .WorkspaceEdit = workspace_edit }, .result = .{ .WorkspaceEdit = workspace_edit },
@ -1095,10 +1094,9 @@ fn renameDefinitionFieldAccess(
const decl = (try server.getSymbolFieldAccess(handle, position, range)) orelse return try respondGeneric(writer, id, null_result_response); const decl = (try server.getSymbolFieldAccess(handle, position, range)) orelse return try respondGeneric(writer, id, null_result_response);
var workspace_edit = types.WorkspaceEdit{ var workspace_edit = types.WorkspaceEdit{ .changes = .{} };
.changes = std.StringHashMapUnmanaged([]types.TextEdit){}, try rename.renameSymbol(&server.arena, &server.document_store, decl, new_name, &workspace_edit.changes, server.offset_encoding);
};
try rename.renameSymbol(&server.arena, &server.document_store, decl, new_name, &workspace_edit.changes.?, server.offset_encoding);
try send(writer, server.arena.allocator(), types.Response{ try send(writer, server.arena.allocator(), types.Response{
.id = id, .id = id,
.result = .{ .WorkspaceEdit = workspace_edit }, .result = .{ .WorkspaceEdit = workspace_edit },
@ -1118,10 +1116,9 @@ fn renameDefinitionLabel(
const decl = (try getLabelGlobal(pos_index, handle)) orelse return try respondGeneric(writer, id, null_result_response); const decl = (try getLabelGlobal(pos_index, handle)) orelse return try respondGeneric(writer, id, null_result_response);
var workspace_edit = types.WorkspaceEdit{ var workspace_edit = types.WorkspaceEdit{ .changes = .{} };
.changes = std.StringHashMapUnmanaged([]types.TextEdit){}, try rename.renameLabel(&server.arena, decl, new_name, &workspace_edit.changes, server.offset_encoding);
};
try rename.renameLabel(&server.arena, decl, new_name, &workspace_edit.changes.?, server.offset_encoding);
try send(writer, server.arena.allocator(), types.Response{ try send(writer, server.arena.allocator(), types.Response{
.id = id, .id = id,
.result = .{ .WorkspaceEdit = workspace_edit }, .result = .{ .WorkspaceEdit = workspace_edit },

View File

@ -8,24 +8,26 @@ const offsets = @import("offsets.zig");
// TODO Use a map to array lists and collect at the end instead? // TODO Use a map to array lists and collect at the end instead?
const RefHandlerContext = struct { const RefHandlerContext = struct {
allocator: std.mem.Allocator, allocator: std.mem.Allocator,
edits: *std.StringHashMapUnmanaged([]types.TextEdit), edits: *std.StringHashMapUnmanaged(std.ArrayListUnmanaged(types.TextEdit)),
new_name: []const u8, new_name: []const u8,
}; };
fn refHandler(context: RefHandlerContext, loc: types.Location) !void { fn refHandler(context: RefHandlerContext, loc: types.Location) !void {
var text_edits = if (context.edits.get(loc.uri)) |slice| const gop = try context.edits.getOrPutValue(context.allocator, loc.uri, .{});
std.ArrayListUnmanaged(types.TextEdit){ .items = slice } try gop.value_ptr.append(context.allocator, .{
else
std.ArrayListUnmanaged(types.TextEdit){};
(try text_edits.addOne(context.allocator)).* = .{
.range = loc.range, .range = loc.range,
.newText = context.new_name, .newText = context.new_name,
}; });
try context.edits.put(context.allocator, loc.uri, text_edits.toOwnedSlice(context.allocator));
} }
pub fn renameSymbol(arena: *std.heap.ArenaAllocator, store: *DocumentStore, decl_handle: analysis.DeclWithHandle, new_name: []const u8, edits: *std.StringHashMapUnmanaged([]types.TextEdit), encoding: offsets.Encoding) !void { pub fn renameSymbol(
arena: *std.heap.ArenaAllocator,
store: *DocumentStore,
decl_handle: analysis.DeclWithHandle,
new_name: []const u8,
edits: *std.StringHashMapUnmanaged(std.ArrayListUnmanaged(types.TextEdit)),
encoding: offsets.Encoding,
) !void {
std.debug.assert(decl_handle.decl.* != .label_decl); std.debug.assert(decl_handle.decl.* != .label_decl);
try references.symbolReferences(arena, store, decl_handle, encoding, true, RefHandlerContext{ try references.symbolReferences(arena, store, decl_handle, encoding, true, RefHandlerContext{
.edits = edits, .edits = edits,
@ -34,7 +36,13 @@ pub fn renameSymbol(arena: *std.heap.ArenaAllocator, store: *DocumentStore, decl
}, refHandler, true, true); }, refHandler, true, true);
} }
pub fn renameLabel(arena: *std.heap.ArenaAllocator, decl_handle: analysis.DeclWithHandle, new_name: []const u8, edits: *std.StringHashMapUnmanaged([]types.TextEdit), encoding: offsets.Encoding) !void { pub fn renameLabel(
arena: *std.heap.ArenaAllocator,
decl_handle: analysis.DeclWithHandle,
new_name: []const u8,
edits: *std.StringHashMapUnmanaged(std.ArrayListUnmanaged(types.TextEdit)),
encoding: offsets.Encoding,
) !void {
std.debug.assert(decl_handle.decl.* == .label_decl); std.debug.assert(decl_handle.decl.* == .label_decl);
try references.labelReferences(arena, decl_handle, encoding, true, RefHandlerContext{ try references.labelReferences(arena, decl_handle, encoding, true, RefHandlerContext{
.edits = edits, .edits = edits,

View File

@ -152,13 +152,11 @@ pub const TextDocument = struct {
}; };
pub const WorkspaceEdit = struct { pub const WorkspaceEdit = struct {
changes: ?std.StringHashMapUnmanaged([]TextEdit), changes: std.StringHashMapUnmanaged(std.ArrayListUnmanaged(TextEdit)),
pub fn jsonStringify(self: WorkspaceEdit, options: std.json.StringifyOptions, writer: anytype) @TypeOf(writer).Error!void { pub fn jsonStringify(self: WorkspaceEdit, options: std.json.StringifyOptions, writer: anytype) @TypeOf(writer).Error!void {
try writer.writeByte('{'); try writer.writeAll("{\"changes\": {");
if (self.changes) |changes| { var it = self.changes.iterator();
try writer.writeAll("\"changes\": {");
var it = changes.iterator();
var idx: usize = 0; var idx: usize = 0;
while (it.next()) |entry| : (idx += 1) { while (it.next()) |entry| : (idx += 1) {
if (idx != 0) try writer.writeAll(", "); if (idx != 0) try writer.writeAll(", ");
@ -166,11 +164,9 @@ pub const WorkspaceEdit = struct {
try writer.writeByte('"'); try writer.writeByte('"');
try writer.writeAll(entry.key_ptr.*); try writer.writeAll(entry.key_ptr.*);
try writer.writeAll("\":"); try writer.writeAll("\":");
try std.json.stringify(entry.value_ptr.*, options, writer); try std.json.stringify(entry.value_ptr.items, options, writer);
} }
try writer.writeByte('}'); try writer.writeAll("}}");
}
try writer.writeByte('}');
} }
}; };