simplify Server.zig (#681)

* simplify Server.zig

* remove wrong default value in Server.zig
This commit is contained in:
Techatrix 2022-09-29 20:01:38 +02:00 committed by GitHub
parent 6ec6d4ea36
commit cf73771739
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -30,7 +30,7 @@ config: *Config,
allocator: std.mem.Allocator = undefined, allocator: std.mem.Allocator = undefined,
arena: std.heap.ArenaAllocator = undefined, arena: std.heap.ArenaAllocator = undefined,
document_store: DocumentStore = undefined, document_store: DocumentStore = undefined,
builtin_completions: ?std.ArrayListUnmanaged(types.CompletionItem) = null, builtin_completions: std.ArrayListUnmanaged(types.CompletionItem),
client_capabilities: ClientCapabilities = .{}, client_capabilities: ClientCapabilities = .{},
offset_encoding: offsets.Encoding = .utf16, offset_encoding: offsets.Encoding = .utf16,
keep_running: bool = true, keep_running: bool = true,
@ -87,16 +87,6 @@ fn send(writer: anytype, allocator: std.mem.Allocator, reqOrRes: anytype) !void
try writer.writeAll(arr.items); try writer.writeAll(arr.items);
} }
fn truncateCompletions(list: []types.CompletionItem, max_detail_length: usize) void {
for (list) |*item| {
if (item.detail) |det| {
if (det.len > max_detail_length) {
item.detail = det[0..max_detail_length];
}
}
}
}
fn respondGeneric(writer: anytype, id: types.RequestId, response: []const u8) !void { fn respondGeneric(writer: anytype, id: types.RequestId, response: []const u8) !void {
var buffered_writer = std.io.bufferedWriter(writer); var buffered_writer = std.io.bufferedWriter(writer);
const buf_writer = buffered_writer.writer(); const buf_writer = buffered_writer.writer();
@ -1110,35 +1100,6 @@ fn populateSnippedCompletions(
} }
} }
fn completeBuiltin(server: *Server) ![]types.CompletionItem {
const tracy_zone = tracy.trace(@src());
defer tracy_zone.end();
if (server.builtin_completions) |completions| return completions.items;
var completions = try std.ArrayListUnmanaged(types.CompletionItem).initCapacity(server.allocator, data.builtins.len);
errdefer completions.deinit();
for (data.builtins) |builtin| {
const insert_text = if (server.config.enable_snippets) builtin.snippet else builtin.name;
completions.appendAssumeCapacity(.{
.label = builtin.name,
.kind = .Function,
.filterText = builtin.name[1..],
.detail = builtin.signature,
.insertText = if (server.config.include_at_in_builtins) insert_text else insert_text[1..],
.insertTextFormat = if (server.config.enable_snippets) .Snippet else .PlainText,
.documentation = .{
.kind = .Markdown,
.value = builtin.documentation,
},
});
}
server.builtin_completions = completions;
return completions.items;
}
fn completeGlobal(server: *Server, pos_index: usize, handle: *DocumentStore.Handle) ![]types.CompletionItem { fn completeGlobal(server: *Server, pos_index: usize, handle: *DocumentStore.Handle) ![]types.CompletionItem {
const tracy_zone = tracy.trace(@src()); const tracy_zone = tracy.trace(@src());
defer tracy_zone.end(); defer tracy_zone.end();
@ -1152,8 +1113,6 @@ fn completeGlobal(server: *Server, pos_index: usize, handle: *DocumentStore.Hand
}; };
try analysis.iterateSymbolsGlobal(&server.document_store, &server.arena, handle, pos_index, declToCompletion, context); try analysis.iterateSymbolsGlobal(&server.document_store, &server.arena, handle, pos_index, declToCompletion, context);
try populateSnippedCompletions(server.arena.allocator(), &completions, &snipped_data.generic, server.config.*, null); try populateSnippedCompletions(server.arena.allocator(), &completions, &snipped_data.generic, server.config.*, null);
try sortCompletionItems(completions.items, server.arena.allocator());
truncateCompletions(completions.items, server.config.max_detail_length);
if (server.client_capabilities.label_details_support) { if (server.client_capabilities.label_details_support) {
for (completions.items) |*item| { for (completions.items) |*item| {
@ -1385,15 +1344,6 @@ fn kindToSortScore(kind: types.CompletionItem.Kind) ?[]const u8 {
}; };
} }
fn sortCompletionItems(completions: []types.CompletionItem, allocator: std.mem.Allocator) error{OutOfMemory}!void {
// TODO: config for sorting rule?
for (completions) |*c| {
const prefix = kindToSortScore(c.kind) orelse continue;
c.sortText = try std.fmt.allocPrint(allocator, "{s}{s}", .{ prefix, c.label });
}
}
fn completeDot(server: *Server, handle: *DocumentStore.Handle) ![]types.CompletionItem { fn completeDot(server: *Server, handle: *DocumentStore.Handle) ![]types.CompletionItem {
const tracy_zone = tracy.trace(@src()); const tracy_zone = tracy.trace(@src());
defer tracy_zone.end(); defer tracy_zone.end();
@ -1687,13 +1637,10 @@ fn openDocumentHandler(server: *Server, writer: anytype, id: types.RequestId, re
const tracy_zone = tracy.trace(@src()); const tracy_zone = tracy.trace(@src());
defer tracy_zone.end(); defer tracy_zone.end();
_ = id;
const handle = try server.document_store.openDocument(req.params.textDocument.uri, req.params.textDocument.text); const handle = try server.document_store.openDocument(req.params.textDocument.uri, req.params.textDocument.text);
try server.publishDiagnostics(writer, handle); try server.publishDiagnostics(writer, handle);
if (server.client_capabilities.supports_semantic_tokens) {
const request: requests.SemanticTokensFull = .{ .params = .{ .textDocument = .{ .uri = req.params.textDocument.uri } } };
try server.semanticTokensFullHandler(writer, id, request);
}
} }
fn changeDocumentHandler(server: *Server, writer: anytype, id: types.RequestId, req: requests.ChangeDocument) !void { fn changeDocumentHandler(server: *Server, writer: anytype, id: types.RequestId, req: requests.ChangeDocument) !void {
@ -1785,10 +1732,11 @@ fn semanticTokensFullHandler(server: *Server, writer: anytype, id: types.Request
const tracy_zone = tracy.trace(@src()); const tracy_zone = tracy.trace(@src());
defer tracy_zone.end(); defer tracy_zone.end();
if (server.config.enable_semantic_tokens) blk: { if (!server.config.enable_semantic_tokens) return try respondGeneric(writer, id, no_semantic_tokens_response);
const handle = server.document_store.getHandle(req.params.textDocument.uri) orelse { const handle = server.document_store.getHandle(req.params.textDocument.uri) orelse {
log.warn("Trying to get semantic tokens of non existent document {s}", .{req.params.textDocument.uri}); log.warn("Trying to get semantic tokens of non existent document {s}", .{req.params.textDocument.uri});
break :blk; return try respondGeneric(writer, id, no_semantic_tokens_response);
}; };
const token_array = try semantic_tokens.writeAllSemanticTokens(&server.arena, &server.document_store, handle, server.offset_encoding); const token_array = try semantic_tokens.writeAllSemanticTokens(&server.arena, &server.document_store, handle, server.offset_encoding);
@ -1798,8 +1746,6 @@ fn semanticTokensFullHandler(server: *Server, writer: anytype, id: types.Request
.id = id, .id = id,
.result = .{ .SemanticTokensFull = .{ .data = token_array } }, .result = .{ .SemanticTokensFull = .{ .data = token_array } },
}); });
}
return try respondGeneric(writer, id, no_semantic_tokens_response);
} }
fn completionHandler(server: *Server, writer: anytype, id: types.RequestId, req: requests.Completion) !void { fn completionHandler(server: *Server, writer: anytype, id: types.RequestId, req: requests.Completion) !void {
@ -1827,7 +1773,7 @@ fn completionHandler(server: *Server, writer: anytype, id: types.RequestId, req:
const pos_context = try analysis.getPositionContext(server.arena.allocator(), handle.document, source_index); const pos_context = try analysis.getPositionContext(server.arena.allocator(), handle.document, source_index);
const maybe_completions = switch (pos_context) { const maybe_completions = switch (pos_context) {
.builtin => try server.completeBuiltin(), .builtin => server.builtin_completions.items,
.var_access, .empty => try server.completeGlobal(source_index, handle), .var_access, .empty => try server.completeGlobal(source_index, handle),
.field_access => |loc| try server.completeFieldAccess(handle, source_index, loc), .field_access => |loc| try server.completeFieldAccess(handle, source_index, loc),
.global_error_set => try server.completeError(handle), .global_error_set => try server.completeError(handle),
@ -1844,8 +1790,22 @@ fn completionHandler(server: *Server, writer: anytype, id: types.RequestId, req:
}; };
const completions = maybe_completions orelse return try respondGeneric(writer, id, no_completions_response); const completions = maybe_completions orelse return try respondGeneric(writer, id, no_completions_response);
truncateCompletions(completions, server.config.max_detail_length);
try sortCompletionItems(completions, server.arena.allocator()); // truncate completions
for (completions) |*item| {
if (item.detail) |det| {
if (det.len > server.config.max_detail_length) {
item.detail = det[0..server.config.max_detail_length];
}
}
}
// TODO: config for sorting rule?
for (completions) |*c| {
const prefix = kindToSortScore(c.kind) orelse continue;
c.sortText = try std.fmt.allocPrint(server.arena.allocator(), "{s}{s}", .{ prefix, c.label });
}
try send(writer, server.arena.allocator(), types.Response{ try send(writer, server.arena.allocator(), types.Response{
.id = id, .id = id,
@ -2204,10 +2164,11 @@ fn inlayHintHandler(server: *Server, writer: anytype, id: types.RequestId, req:
const tracy_zone = tracy.trace(@src()); const tracy_zone = tracy.trace(@src());
defer tracy_zone.end(); defer tracy_zone.end();
if (server.config.enable_inlay_hints) blk: { if (!server.config.enable_inlay_hints) return try respondGeneric(writer, id, null_result_response);
const handle = server.document_store.getHandle(req.params.textDocument.uri) orelse { const handle = server.document_store.getHandle(req.params.textDocument.uri) orelse {
log.warn("Trying to get inlay hint of non existent document {s}", .{req.params.textDocument.uri}); log.warn("Trying to get inlay hint of non existent document {s}", .{req.params.textDocument.uri});
break :blk; return try respondGeneric(writer, id, null_result_response);
}; };
const hover_kind: types.MarkupContent.Kind = if (server.client_capabilities.hover_supports_md) .Markdown else .PlainText; const hover_kind: types.MarkupContent.Kind = if (server.client_capabilities.hover_supports_md) .Markdown else .PlainText;
@ -2251,8 +2212,6 @@ fn inlayHintHandler(server: *Server, writer: anytype, id: types.RequestId, req:
.id = id, .id = id,
.result = .{ .InlayHint = visible_hints }, .result = .{ .InlayHint = visible_hints },
}); });
}
return try respondGeneric(writer, id, null_result_response);
} }
fn codeActionHandler(server: *Server, writer: anytype, id: types.RequestId, req: requests.CodeAction) !void { fn codeActionHandler(server: *Server, writer: anytype, id: types.RequestId, req: requests.CodeAction) !void {
@ -2482,10 +2441,30 @@ pub fn init(
var document_store = try DocumentStore.init(allocator, config); var document_store = try DocumentStore.init(allocator, config);
errdefer document_store.deinit(); errdefer document_store.deinit();
var builtin_completions = try std.ArrayListUnmanaged(types.CompletionItem).initCapacity(allocator, data.builtins.len);
errdefer builtin_completions.deinit();
for (data.builtins) |builtin| {
const insert_text = if (config.enable_snippets) builtin.snippet else builtin.name;
builtin_completions.appendAssumeCapacity(.{
.label = builtin.name,
.kind = .Function,
.filterText = builtin.name[1..],
.detail = builtin.signature,
.insertText = if (config.include_at_in_builtins) insert_text else insert_text[1..],
.insertTextFormat = if (config.enable_snippets) .Snippet else .PlainText,
.documentation = .{
.kind = .Markdown,
.value = builtin.documentation,
},
});
}
return Server{ return Server{
.config = config, .config = config,
.allocator = allocator, .allocator = allocator,
.document_store = document_store, .document_store = document_store,
.builtin_completions = builtin_completions,
}; };
} }
@ -2493,7 +2472,5 @@ pub fn deinit(server: *Server) void {
server.document_store.deinit(); server.document_store.deinit();
analysis.deinit(); analysis.deinit();
if (server.builtin_completions) |*compls| { server.builtin_completions.deinit(server.allocator);
compls.deinit(server.allocator);
}
} }