From 605c4e29882d0954c0fd5a40506d2e0cb4bfd7e0 Mon Sep 17 00:00:00 2001 From: Techatrix <19954306+Techatrix@users.noreply.github.com> Date: Mon, 29 Aug 2022 21:28:05 +0200 Subject: [PATCH] fix textDocument/rename --- src/Server.zig | 21 +++++++++------------ src/rename.zig | 30 +++++++++++++++++++----------- src/types.zig | 26 +++++++++++--------------- 3 files changed, 39 insertions(+), 38 deletions(-) diff --git a/src/Server.zig b/src/Server.zig index 59eec00..f404253 100644 --- a/src/Server.zig +++ b/src/Server.zig @@ -1071,10 +1071,9 @@ fn renameDefinitionGlobal( const decl = (try server.getSymbolGlobal(pos_index, handle)) orelse return try respondGeneric(writer, id, null_result_response); - var workspace_edit = types.WorkspaceEdit{ - .changes = std.StringHashMapUnmanaged([]types.TextEdit){}, - }; - try rename.renameSymbol(&server.arena, &server.document_store, decl, new_name, &workspace_edit.changes.?, server.offset_encoding); + var workspace_edit = types.WorkspaceEdit{ .changes = .{} }; + 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{ .id = id, .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); - var workspace_edit = types.WorkspaceEdit{ - .changes = std.StringHashMapUnmanaged([]types.TextEdit){}, - }; - try rename.renameSymbol(&server.arena, &server.document_store, decl, new_name, &workspace_edit.changes.?, server.offset_encoding); + var workspace_edit = types.WorkspaceEdit{ .changes = .{} }; + 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{ .id = id, .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); - var workspace_edit = types.WorkspaceEdit{ - .changes = std.StringHashMapUnmanaged([]types.TextEdit){}, - }; - try rename.renameLabel(&server.arena, decl, new_name, &workspace_edit.changes.?, server.offset_encoding); + var workspace_edit = types.WorkspaceEdit{ .changes = .{} }; + try rename.renameLabel(&server.arena, decl, new_name, &workspace_edit.changes, server.offset_encoding); + try send(writer, server.arena.allocator(), types.Response{ .id = id, .result = .{ .WorkspaceEdit = workspace_edit }, diff --git a/src/rename.zig b/src/rename.zig index 43ace34..50054ee 100644 --- a/src/rename.zig +++ b/src/rename.zig @@ -8,24 +8,26 @@ const offsets = @import("offsets.zig"); // TODO Use a map to array lists and collect at the end instead? const RefHandlerContext = struct { allocator: std.mem.Allocator, - edits: *std.StringHashMapUnmanaged([]types.TextEdit), + edits: *std.StringHashMapUnmanaged(std.ArrayListUnmanaged(types.TextEdit)), new_name: []const u8, }; fn refHandler(context: RefHandlerContext, loc: types.Location) !void { - var text_edits = if (context.edits.get(loc.uri)) |slice| - std.ArrayListUnmanaged(types.TextEdit){ .items = slice } - else - std.ArrayListUnmanaged(types.TextEdit){}; - - (try text_edits.addOne(context.allocator)).* = .{ + const gop = try context.edits.getOrPutValue(context.allocator, loc.uri, .{}); + try gop.value_ptr.append(context.allocator, .{ .range = loc.range, .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); try references.symbolReferences(arena, store, decl_handle, encoding, true, RefHandlerContext{ .edits = edits, @@ -34,7 +36,13 @@ pub fn renameSymbol(arena: *std.heap.ArenaAllocator, store: *DocumentStore, decl }, 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); try references.labelReferences(arena, decl_handle, encoding, true, RefHandlerContext{ .edits = edits, diff --git a/src/types.zig b/src/types.zig index 9a5696f..659a77b 100644 --- a/src/types.zig +++ b/src/types.zig @@ -152,25 +152,21 @@ pub const TextDocument = 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 { - try writer.writeByte('{'); - if (self.changes) |changes| { - try writer.writeAll("\"changes\": {"); - var it = changes.iterator(); - var idx: usize = 0; - while (it.next()) |entry| : (idx += 1) { - if (idx != 0) try writer.writeAll(", "); + try writer.writeAll("{\"changes\": {"); + var it = self.changes.iterator(); + var idx: usize = 0; + while (it.next()) |entry| : (idx += 1) { + if (idx != 0) try writer.writeAll(", "); - try writer.writeByte('"'); - try writer.writeAll(entry.key_ptr.*); - try writer.writeAll("\":"); - try std.json.stringify(entry.value_ptr.*, options, writer); - } - try writer.writeByte('}'); + try writer.writeByte('"'); + try writer.writeAll(entry.key_ptr.*); + try writer.writeAll("\":"); + try std.json.stringify(entry.value_ptr.items, options, writer); } - try writer.writeByte('}'); + try writer.writeAll("}}"); } };