use more explicit error sets (#880)

This commit is contained in:
Techatrix 2023-01-03 15:21:58 +00:00 committed by GitHub
parent c718e12d16
commit a574ac68ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 78 additions and 67 deletions

View File

@ -921,7 +921,7 @@ pub fn uriFromImportStr(self: *const DocumentStore, allocator: std.mem.Allocator
}
}
fn tagStoreCompletionItems(self: DocumentStore, arena: std.mem.Allocator, handle: Handle, comptime name: []const u8) ![]types.CompletionItem {
fn tagStoreCompletionItems(self: DocumentStore, arena: std.mem.Allocator, handle: Handle, comptime name: []const u8) error{OutOfMemory}![]types.CompletionItem {
const tracy_zone = tracy.trace(@src());
defer tracy_zone.end();
@ -944,11 +944,11 @@ fn tagStoreCompletionItems(self: DocumentStore, arena: std.mem.Allocator, handle
return result_set.entries.items(.key);
}
pub fn errorCompletionItems(self: DocumentStore, arena: std.mem.Allocator, handle: Handle) ![]types.CompletionItem {
pub fn errorCompletionItems(self: DocumentStore, arena: std.mem.Allocator, handle: Handle) error{OutOfMemory}![]types.CompletionItem {
return try self.tagStoreCompletionItems(arena, handle, "error_completions");
}
pub fn enumCompletionItems(self: DocumentStore, arena: std.mem.Allocator, handle: Handle) ![]types.CompletionItem {
pub fn enumCompletionItems(self: DocumentStore, arena: std.mem.Allocator, handle: Handle) error{OutOfMemory}![]types.CompletionItem {
return try self.tagStoreCompletionItems(arena, handle, "enum_completions");
}

View File

@ -66,8 +66,7 @@ const ClientCapabilities = packed struct {
supports_configuration: bool = false,
};
/// TODO remove anyerror
pub const Error = anyerror || std.mem.Allocator.Error || error{
pub const Error = std.mem.Allocator.Error || error{
ParseError,
InvalidRequest,
MethodNotFound,
@ -138,7 +137,7 @@ fn sendInternal(
maybe_err: ?types.ResponseError,
extra_name: []const u8,
extra: anytype,
) !void {
) error{OutOfMemory}!void {
var buffer = std.ArrayListUnmanaged(u8){};
var writer = buffer.writer(server.allocator);
try writer.writeAll(
@ -191,7 +190,7 @@ fn showMessage(
});
}
fn generateDiagnostics(server: *Server, handle: DocumentStore.Handle) !types.PublishDiagnosticsParams {
fn generateDiagnostics(server: *Server, handle: DocumentStore.Handle) error{OutOfMemory}!types.PublishDiagnosticsParams {
const tracy_zone = tracy.trace(@src());
defer tracy_zone.end();
@ -205,7 +204,7 @@ fn generateDiagnostics(server: *Server, handle: DocumentStore.Handle) !types.Pub
for (tree.errors) |err| {
var mem_buffer: [256]u8 = undefined;
var fbs = std.io.fixedBufferStream(&mem_buffer);
try tree.renderError(err, fbs.writer());
tree.renderError(err, fbs.writer()) catch if (std.debug.runtime_safety) unreachable else continue; // if an error occurs here increase buffer size
try diagnostics.append(allocator, .{
.range = offsets.tokenToRange(tree, err.token, server.offset_encoding),
@ -218,7 +217,9 @@ fn generateDiagnostics(server: *Server, handle: DocumentStore.Handle) !types.Pub
}
if (server.config.enable_ast_check_diagnostics and tree.errors.len == 0) {
try getAstCheckDiagnostics(server, handle, &diagnostics);
getAstCheckDiagnostics(server, handle, &diagnostics) catch |err| {
log.err("failed to run ast-check: {}", .{err});
};
}
if (server.config.warn_style) {
@ -485,12 +486,14 @@ fn getAutofixMode(server: *Server) enum {
}
/// caller owns returned memory.
fn autofix(server: *Server, allocator: std.mem.Allocator, handle: *const DocumentStore.Handle) !std.ArrayListUnmanaged(types.TextEdit) {
fn autofix(server: *Server, allocator: std.mem.Allocator, handle: *const DocumentStore.Handle) error{OutOfMemory}!std.ArrayListUnmanaged(types.TextEdit) {
if (!server.config.enable_ast_check_diagnostics) return .{};
if (handle.tree.errors.len != 0) return .{};
var diagnostics = std.ArrayListUnmanaged(types.Diagnostic){};
try getAstCheckDiagnostics(server, handle.*, &diagnostics);
getAstCheckDiagnostics(server, handle.*, &diagnostics) catch |err| {
log.err("failed to run ast-check: {}", .{err});
};
var builder = code_actions.Builder{
.arena = server.arena,
@ -1086,7 +1089,7 @@ fn getSymbolFieldAccess(
handle: *const DocumentStore.Handle,
source_index: usize,
loc: offsets.Loc,
) !?analysis.DeclWithHandle {
) error{OutOfMemory}!?analysis.DeclWithHandle {
const tracy_zone = tracy.trace(@src());
defer tracy_zone.end();
@ -1167,7 +1170,7 @@ const DeclToCompletionContext = struct {
parent_is_type_val: ?bool = null,
};
fn declToCompletion(context: DeclToCompletionContext, decl_handle: analysis.DeclWithHandle) !void {
fn declToCompletion(context: DeclToCompletionContext, decl_handle: analysis.DeclWithHandle) error{OutOfMemory}!void {
const tracy_zone = tracy.trace(@src());
defer tracy_zone.end();
@ -1227,7 +1230,7 @@ fn completeLabel(
server: *Server,
pos_index: usize,
handle: *const DocumentStore.Handle,
) ![]types.CompletionItem {
) error{OutOfMemory}![]types.CompletionItem {
const tracy_zone = tracy.trace(@src());
defer tracy_zone.end();
@ -1267,7 +1270,7 @@ fn populateSnippedCompletions(
}
}
fn completeGlobal(server: *Server, pos_index: usize, handle: *const DocumentStore.Handle) ![]types.CompletionItem {
fn completeGlobal(server: *Server, pos_index: usize, handle: *const DocumentStore.Handle) error{OutOfMemory}![]types.CompletionItem {
const tracy_zone = tracy.trace(@src());
defer tracy_zone.end();
@ -1290,7 +1293,7 @@ fn completeGlobal(server: *Server, pos_index: usize, handle: *const DocumentStor
return completions.toOwnedSlice(server.arena.allocator());
}
fn completeFieldAccess(server: *Server, handle: *const DocumentStore.Handle, source_index: usize, loc: offsets.Loc) !?[]types.CompletionItem {
fn completeFieldAccess(server: *Server, handle: *const DocumentStore.Handle, source_index: usize, loc: offsets.Loc) error{OutOfMemory}!?[]types.CompletionItem {
const tracy_zone = tracy.trace(@src());
defer tracy_zone.end();
@ -1312,7 +1315,7 @@ fn completeFieldAccess(server: *Server, handle: *const DocumentStore.Handle, sou
return try completions.toOwnedSlice(allocator);
}
fn formatDetailledLabel(item: *types.CompletionItem, alloc: std.mem.Allocator) !void {
fn formatDetailledLabel(item: *types.CompletionItem, alloc: std.mem.Allocator) error{OutOfMemory}!void {
// NOTE: this is not ideal, we should build a detailled label like we do for label/detail
// because this implementation is very loose, nothing is formated properly so we need to clean
// things a little bit, wich is quite messy
@ -1478,7 +1481,7 @@ fn formatDetailledLabel(item: *types.CompletionItem, alloc: std.mem.Allocator) !
// logger.info("labelDetails: {s} :: {s}", .{item.labelDetails.?.detail, item.labelDetails.?.description});
}
fn completeError(server: *Server, handle: *const DocumentStore.Handle) ![]types.CompletionItem {
fn completeError(server: *Server, handle: *const DocumentStore.Handle) error{OutOfMemory}![]types.CompletionItem {
const tracy_zone = tracy.trace(@src());
defer tracy_zone.end();
@ -1513,7 +1516,7 @@ fn kindToSortScore(kind: types.CompletionItemKind) ?[]const u8 {
};
}
fn completeDot(server: *Server, handle: *const DocumentStore.Handle) ![]types.CompletionItem {
fn completeDot(server: *Server, handle: *const DocumentStore.Handle) error{OutOfMemory}![]types.CompletionItem {
const tracy_zone = tracy.trace(@src());
defer tracy_zone.end();
@ -1578,7 +1581,7 @@ fn completeFileSystemStringLiteral(allocator: std.mem.Allocator, store: *const D
return completions.toOwnedSlice(allocator);
}
fn initializeHandler(server: *Server, request: types.InitializeParams) !types.InitializeResult {
fn initializeHandler(server: *Server, request: types.InitializeParams) Error!types.InitializeResult {
const tracy_zone = tracy.trace(@src());
defer tracy_zone.end();
@ -1794,7 +1797,7 @@ fn initializeHandler(server: *Server, request: types.InitializeParams) !types.In
};
}
fn initializedHandler(server: *Server, notification: types.InitializedParams) !void {
fn initializedHandler(server: *Server, notification: types.InitializedParams) Error!void {
_ = notification;
if (server.status != .initializing) {
@ -1807,7 +1810,7 @@ fn initializedHandler(server: *Server, notification: types.InitializedParams) !v
try server.requestConfiguration();
}
fn shutdownHandler(server: *Server, _: void) !?void {
fn shutdownHandler(server: *Server, _: void) Error!?void {
if (server.status != .initialized) return error.InvalidRequest; // received a shutdown request but the server is not initialized!
// Technically we should deinitialize first and send possible errors to the client
@ -1826,13 +1829,13 @@ fn exitHandler(server: *Server, _: void) noreturn {
std.os.exit(error_code);
}
fn cancelRequestHandler(server: *Server, request: types.CancelParams) !void {
fn cancelRequestHandler(server: *Server, request: types.CancelParams) Error!void {
_ = server;
_ = request;
// TODO implement $/cancelRequest
}
fn registerCapability(server: *Server, method: []const u8) !void {
fn registerCapability(server: *Server, method: []const u8) Error!void {
const allocator = server.arena.allocator();
const id = try std.fmt.allocPrint(allocator, "register-{s}", .{method});
@ -1851,7 +1854,7 @@ fn registerCapability(server: *Server, method: []const u8) !void {
);
}
fn requestConfiguration(server: *Server) !void {
fn requestConfiguration(server: *Server) Error!void {
if (server.recording_enabled) {
log.info("workspace/configuration are disabled during a recording session!", .{});
return;
@ -1938,7 +1941,7 @@ fn handleConfiguration(server: *Server, json: std.json.Value) error{OutOfMemory}
};
}
fn openDocumentHandler(server: *Server, notification: types.DidOpenTextDocumentParams) !void {
fn openDocumentHandler(server: *Server, notification: types.DidOpenTextDocumentParams) Error!void {
const tracy_zone = tracy.trace(@src());
defer tracy_zone.end();
@ -1950,7 +1953,7 @@ fn openDocumentHandler(server: *Server, notification: types.DidOpenTextDocumentP
}
}
fn changeDocumentHandler(server: *Server, notification: types.DidChangeTextDocumentParams) !void {
fn changeDocumentHandler(server: *Server, notification: types.DidChangeTextDocumentParams) Error!void {
const tracy_zone = tracy.trace(@src());
defer tracy_zone.end();
@ -1966,7 +1969,7 @@ fn changeDocumentHandler(server: *Server, notification: types.DidChangeTextDocum
}
}
fn saveDocumentHandler(server: *Server, notification: types.DidSaveTextDocumentParams) !void {
fn saveDocumentHandler(server: *Server, notification: types.DidSaveTextDocumentParams) Error!void {
const tracy_zone = tracy.trace(@src());
defer tracy_zone.end();
@ -2000,7 +2003,7 @@ fn closeDocumentHandler(server: *Server, notification: types.DidCloseTextDocumen
server.document_store.closeDocument(notification.textDocument.uri);
}
fn willSaveWaitUntilHandler(server: *Server, request: types.WillSaveTextDocumentParams) !?[]types.TextEdit {
fn willSaveWaitUntilHandler(server: *Server, request: types.WillSaveTextDocumentParams) Error!?[]types.TextEdit {
const tracy_zone = tracy.trace(@src());
defer tracy_zone.end();
@ -2015,7 +2018,7 @@ fn willSaveWaitUntilHandler(server: *Server, request: types.WillSaveTextDocument
return try text_edits.toOwnedSlice(allocator);
}
fn semanticTokensFullHandler(server: *Server, request: types.SemanticTokensParams) !?types.SemanticTokens {
fn semanticTokensFullHandler(server: *Server, request: types.SemanticTokensParams) Error!?types.SemanticTokens {
const tracy_zone = tracy.trace(@src());
defer tracy_zone.end();
@ -2028,7 +2031,7 @@ fn semanticTokensFullHandler(server: *Server, request: types.SemanticTokensParam
return .{ .data = token_array };
}
fn completionHandler(server: *Server, request: types.CompletionParams) !?types.CompletionList {
fn completionHandler(server: *Server, request: types.CompletionParams) Error!?types.CompletionList {
const tracy_zone = tracy.trace(@src());
defer tracy_zone.end();
@ -2056,7 +2059,10 @@ fn completionHandler(server: *Server, request: types.CompletionParams) !?types.C
const completing = offsets.locToSlice(handle.tree.source, loc);
const is_import = pos_context == .import_string_literal;
break :blk try completeFileSystemStringLiteral(server.arena.allocator(), &server.document_store, handle, completing, is_import);
break :blk completeFileSystemStringLiteral(server.arena.allocator(), &server.document_store, handle, completing, is_import) catch |err| {
log.err("failed to get file system completions: {}", .{err});
return null;
};
},
else => null,
};
@ -2082,7 +2088,7 @@ fn completionHandler(server: *Server, request: types.CompletionParams) !?types.C
return .{ .isIncomplete = false, .items = completions };
}
fn signatureHelpHandler(server: *Server, request: types.SignatureHelpParams) !?types.SignatureHelp {
fn signatureHelpHandler(server: *Server, request: types.SignatureHelpParams) Error!?types.SignatureHelp {
const tracy_zone = tracy.trace(@src());
defer tracy_zone.end();
@ -2111,7 +2117,7 @@ fn signatureHelpHandler(server: *Server, request: types.SignatureHelpParams) !?t
};
}
fn gotoHandler(server: *Server, request: types.TextDocumentPositionParams, resolve_alias: bool) !?types.Location {
fn gotoHandler(server: *Server, request: types.TextDocumentPositionParams, resolve_alias: bool) Error!?types.Location {
const tracy_zone = tracy.trace(@src());
defer tracy_zone.end();
@ -2134,7 +2140,7 @@ fn gotoHandler(server: *Server, request: types.TextDocumentPositionParams, resol
fn gotoDefinitionHandler(
server: *Server,
request: types.TextDocumentPositionParams,
) !?types.Location {
) Error!?types.Location {
const tracy_zone = tracy.trace(@src());
defer tracy_zone.end();
@ -2144,14 +2150,14 @@ fn gotoDefinitionHandler(
fn gotoDeclarationHandler(
server: *Server,
request: types.TextDocumentPositionParams,
) !?types.Location {
) Error!?types.Location {
const tracy_zone = tracy.trace(@src());
defer tracy_zone.end();
return try server.gotoHandler(request, false);
}
fn hoverHandler(server: *Server, request: types.HoverParams) !?types.Hover {
fn hoverHandler(server: *Server, request: types.HoverParams) Error!?types.Hover {
const tracy_zone = tracy.trace(@src());
defer tracy_zone.end();
@ -2179,7 +2185,7 @@ fn hoverHandler(server: *Server, request: types.HoverParams) !?types.Hover {
return response;
}
fn documentSymbolsHandler(server: *Server, request: types.DocumentSymbolParams) !?[]types.DocumentSymbol {
fn documentSymbolsHandler(server: *Server, request: types.DocumentSymbolParams) Error!?[]types.DocumentSymbol {
const tracy_zone = tracy.trace(@src());
defer tracy_zone.end();
@ -2188,7 +2194,7 @@ fn documentSymbolsHandler(server: *Server, request: types.DocumentSymbolParams)
return try analysis.getDocumentSymbols(server.arena.allocator(), handle.tree, server.offset_encoding);
}
fn formattingHandler(server: *Server, request: types.DocumentFormattingParams) !?[]types.TextEdit {
fn formattingHandler(server: *Server, request: types.DocumentFormattingParams) Error!?[]types.TextEdit {
const tracy_zone = tracy.trace(@src());
defer tracy_zone.end();
@ -2224,7 +2230,7 @@ fn formattingHandler(server: *Server, request: types.DocumentFormattingParams) !
return text_edits.items;
}
fn didChangeConfigurationHandler(server: *Server, request: configuration.DidChangeConfigurationParams) !void {
fn didChangeConfigurationHandler(server: *Server, request: configuration.DidChangeConfigurationParams) Error!void {
const tracy_zone = tracy.trace(@src());
defer tracy_zone.end();
@ -2244,13 +2250,15 @@ fn didChangeConfigurationHandler(server: *Server, request: configuration.DidChan
}
}
try configuration.configChanged(server.config, server.allocator, null);
configuration.configChanged(server.config, server.allocator, null) catch |err| {
log.err("failed to update config: {}", .{err});
};
} else if (server.client_capabilities.supports_configuration) {
try server.requestConfiguration();
}
}
fn renameHandler(server: *Server, request: types.RenameParams) !?types.WorkspaceEdit {
fn renameHandler(server: *Server, request: types.RenameParams) Error!?types.WorkspaceEdit {
const tracy_zone = tracy.trace(@src());
defer tracy_zone.end();
@ -2258,7 +2266,7 @@ fn renameHandler(server: *Server, request: types.RenameParams) !?types.Workspace
return if (response) |rep| rep.rename else null;
}
fn referencesHandler(server: *Server, request: types.ReferenceParams) !?[]types.Location {
fn referencesHandler(server: *Server, request: types.ReferenceParams) Error!?[]types.Location {
const tracy_zone = tracy.trace(@src());
defer tracy_zone.end();
@ -2266,7 +2274,7 @@ fn referencesHandler(server: *Server, request: types.ReferenceParams) !?[]types.
return if (response) |rep| rep.references else null;
}
fn documentHighlightHandler(server: *Server, request: types.DocumentHighlightParams) !?[]types.DocumentHighlight {
fn documentHighlightHandler(server: *Server, request: types.DocumentHighlightParams) Error!?[]types.DocumentHighlight {
const tracy_zone = tracy.trace(@src());
defer tracy_zone.end();
@ -2302,7 +2310,7 @@ const GeneralReferencesResponse = union {
highlight: []types.DocumentHighlight,
};
fn generalReferencesHandler(server: *Server, request: GeneralReferencesRequest) !?GeneralReferencesResponse {
fn generalReferencesHandler(server: *Server, request: GeneralReferencesRequest) Error!?GeneralReferencesResponse {
const tracy_zone = tracy.trace(@src());
defer tracy_zone.end();
@ -2387,7 +2395,7 @@ fn isPositionBefore(lhs: types.Position, rhs: types.Position) bool {
}
}
fn inlayHintHandler(server: *Server, request: types.InlayHintParams) !?[]types.InlayHint {
fn inlayHintHandler(server: *Server, request: types.InlayHintParams) Error!?[]types.InlayHint {
const tracy_zone = tracy.trace(@src());
defer tracy_zone.end();
@ -2429,7 +2437,7 @@ fn inlayHintHandler(server: *Server, request: types.InlayHintParams) !?[]types.I
return visible_hints;
}
fn codeActionHandler(server: *Server, request: types.CodeActionParams) !?[]types.CodeAction {
fn codeActionHandler(server: *Server, request: types.CodeActionParams) Error!?[]types.CodeAction {
const handle = server.document_store.getHandle(request.textDocument.uri) orelse return null;
var builder = code_actions.Builder{
@ -2442,7 +2450,10 @@ fn codeActionHandler(server: *Server, request: types.CodeActionParams) !?[]types
// as of right now, only ast-check errors may get a code action
var diagnostics = std.ArrayListUnmanaged(types.Diagnostic){};
if (server.config.enable_ast_check_diagnostics and handle.tree.errors.len == 0) {
try getAstCheckDiagnostics(server, handle.*, &diagnostics);
getAstCheckDiagnostics(server, handle.*, &diagnostics) catch |err| {
log.err("failed to run ast-check: {}", .{err});
return error.InternalError;
};
}
var actions = std.ArrayListUnmanaged(types.CodeAction){};
@ -2453,7 +2464,7 @@ fn codeActionHandler(server: *Server, request: types.CodeActionParams) !?[]types
return actions.items;
}
fn foldingRangeHandler(server: *Server, request: types.FoldingRangeParams) !?[]types.FoldingRange {
fn foldingRangeHandler(server: *Server, request: types.FoldingRangeParams) Error!?[]types.FoldingRange {
const Token = std.zig.Token;
const Node = Ast.Node;
const allocator = server.arena.allocator();
@ -2716,7 +2727,7 @@ pub const SelectionRange = struct {
parent: ?*SelectionRange,
};
fn selectionRangeHandler(server: *Server, request: types.SelectionRangeParams) !?[]*SelectionRange {
fn selectionRangeHandler(server: *Server, request: types.SelectionRangeParams) Error!?[]*SelectionRange {
const allocator = server.arena.allocator();
const handle = server.document_store.getHandle(request.textDocument.uri) orelse return null;
@ -2906,26 +2917,23 @@ pub fn processJsonRpc(
var parser = std.json.Parser.init(server.arena.allocator(), false);
defer parser.deinit();
var tree = parser.parse(json) catch {
log.err("failed to parse message!", .{});
var tree = parser.parse(json) catch |err| {
log.err("failed to parse message: {}", .{err});
return; // maybe panic?
};
defer tree.deinit();
const message = Message.fromJsonValueTree(tree) catch {
log.err("failed to parse message!", .{});
const message = Message.fromJsonValueTree(tree) catch |err| {
log.err("failed to parse message: {}", .{err});
return; // maybe panic?
};
server.processMessage(message) catch |err| {
log.err("got {} while processing message!", .{err}); // TODO include message information
switch (message) {
.RequestMessage => |request| server.sendResponseError(request.id, .{
.code = @errorToInt(err),
.message = @errorName(err),
}),
else => {},
}
server.processMessage(message) catch |err| switch (message) {
.RequestMessage => |request| server.sendResponseError(request.id, .{
.code = @errorToInt(err),
.message = @errorName(err),
}),
else => {},
};
}
@ -3039,7 +3047,10 @@ fn processMessage(server: *Server, message: Message) Error!void {
const ParamsType = handler_info.params[1].type.?; // TODO add error message on null
const params: ParamsType = tres.parse(ParamsType, message.params().?, server.arena.allocator()) catch return error.InternalError;
const response = handler(server, params) catch return error.InternalError;
const response = handler(server, params) catch |err| {
log.err("got {} error while handling {s}", .{ err, method });
return error.InternalError;
};
if (@TypeOf(response) == void) return;

View File

@ -1680,7 +1680,7 @@ pub fn getPositionContext(allocator: std.mem.Allocator, text: []const u8, doc_in
return if (tok.tag == .identifier) PositionContext{ .var_access = tok.loc } else .empty;
}
fn addOutlineNodes(allocator: std.mem.Allocator, tree: Ast, child: Ast.Node.Index, context: *GetDocumentSymbolsContext) anyerror!void {
fn addOutlineNodes(allocator: std.mem.Allocator, tree: Ast, child: Ast.Node.Index, context: *GetDocumentSymbolsContext) error{OutOfMemory}!void {
switch (tree.nodes.items(.tag)[child]) {
.string_literal,
.number_literal,
@ -1825,7 +1825,7 @@ const GetDocumentSymbolsContext = struct {
encoding: offsets.Encoding,
};
fn getDocumentSymbolsInternal(allocator: std.mem.Allocator, tree: Ast, node: Ast.Node.Index, context: *GetDocumentSymbolsContext) anyerror!void {
fn getDocumentSymbolsInternal(allocator: std.mem.Allocator, tree: Ast, node: Ast.Node.Index, context: *GetDocumentSymbolsContext) error{OutOfMemory}!void {
const name = getDeclName(tree, node) orelse return;
if (name.len == 0)
return;