completeBuiltin fixes (#1015)

- Always return a copy to avoid memory corruption (most operations assume an arena allocated copy)
- label_details were only generated for the first (pre-fix) disposable copy
- Correct use_snippets logic (send only if configured and client supports them)
This commit is contained in:
nullptrdevs 2023-02-22 08:30:21 -08:00 committed by GitHub
parent f59fb1ec12
commit 424a06b7ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1364,22 +1364,21 @@ fn completeBuiltin(server: *Server) error{OutOfMemory}!?[]types.CompletionItem {
const allocator = server.arena.allocator(); const allocator = server.arena.allocator();
const builtin_completions = if (server.builtin_completions) |completions| const builtin_completions = blk: {
return completions.items if (server.builtin_completions) |completions| {
else blk: { break :blk completions;
} else {
server.builtin_completions = try std.ArrayListUnmanaged(types.CompletionItem).initCapacity(server.allocator, data.builtins.len); server.builtin_completions = try std.ArrayListUnmanaged(types.CompletionItem).initCapacity(server.allocator, data.builtins.len);
break :blk &server.builtin_completions.?;
};
for (data.builtins) |builtin| { for (data.builtins) |builtin| {
const insert_text = if (server.config.enable_snippets) builtin.snippet else builtin.name; const use_snippets = server.config.enable_snippets and server.client_capabilities.supports_snippets;
builtin_completions.appendAssumeCapacity(.{ const insert_text = if (use_snippets) builtin.snippet else builtin.name;
server.builtin_completions.?.appendAssumeCapacity(.{
.label = builtin.name, .label = builtin.name,
.kind = .Function, .kind = .Function,
.filterText = builtin.name[1..], .filterText = builtin.name[1..],
.detail = builtin.signature, .detail = builtin.signature,
.insertText = if (server.config.include_at_in_builtins) insert_text else insert_text[1..], .insertText = if (server.config.include_at_in_builtins) insert_text else insert_text[1..],
.insertTextFormat = if (server.config.enable_snippets) .Snippet else .PlainText, .insertTextFormat = if (use_snippets) .Snippet else .PlainText,
.documentation = .{ .documentation = .{
.MarkupContent = .{ .MarkupContent = .{
.kind = .markdown, .kind = .markdown,
@ -1388,6 +1387,9 @@ fn completeBuiltin(server: *Server) error{OutOfMemory}!?[]types.CompletionItem {
}, },
}); });
} }
break :blk server.builtin_completions.?;
}
};
var completions = try builtin_completions.clone(allocator); var completions = try builtin_completions.clone(allocator);
@ -1984,11 +1986,9 @@ fn initializedHandler(server: *Server, notification: types.InitializedParams) Er
try server.requestConfiguration(); try server.requestConfiguration();
} }
fn shutdownHandler(server: *Server, _: void) Error!?void { fn shutdownHandler(server: *Server, _: void) Error!void {
defer server.status = .shutdown; defer server.status = .shutdown;
if (server.status != .initialized) return error.InvalidRequest; // received a shutdown request but the server is not initialized! if (server.status != .initialized) return error.InvalidRequest; // received a shutdown request but the server is not initialized!
return null;
} }
fn exitHandler(server: *Server, _: void) Error!void { fn exitHandler(server: *Server, _: void) Error!void {