Ignore unimplemented notifications

Responding to an unimplemented notification can cause errors for some
LSP clients that do not expect to receive a response after sending a
notification. Differentiate between unimplemented requests and
notifications and only send a generic null response for the former while
silently ignoring the latter.
This commit is contained in:
Gregory Anders 2022-06-05 13:34:02 -06:00 committed by Auguste Rame
parent ebc6de9673
commit 289d137d13

View File

@ -1637,24 +1637,32 @@ fn processJsonRpc(arena: *std.heap.ArenaAllocator, parser: *std.json.Parser, jso
else => return err,
};
const unimplemented_map = std.ComptimeStringMap(void, .{
.{"textDocument/documentHighlight"},
.{"textDocument/codeAction"},
.{"textDocument/codeLens"},
.{"textDocument/documentLink"},
.{"textDocument/rangeFormatting"},
.{"textDocument/onTypeFormatting"},
.{"textDocument/prepareRename"},
.{"textDocument/foldingRange"},
.{"textDocument/selectionRange"},
.{"textDocument/semanticTokens/range"},
.{"workspace/didChangeWorkspaceFolders"},
// Boolean value is true if the method is a request (and thus the client
// needs a response) or false if the method is a notification (in which
// case it should be silently ignored)
const unimplemented_map = std.ComptimeStringMap(bool, .{
.{ "textDocument/documentHighlight", true },
.{ "textDocument/codeAction", true },
.{ "textDocument/codeLens", true },
.{ "textDocument/documentLink", true },
.{ "textDocument/rangeFormatting", true },
.{ "textDocument/onTypeFormatting", true },
.{ "textDocument/prepareRename", true },
.{ "textDocument/foldingRange", true },
.{ "textDocument/selectionRange", true },
.{ "textDocument/semanticTokens/range", true },
.{ "workspace/didChangeWorkspaceFolders", false },
});
if (unimplemented_map.has(method)) {
if (unimplemented_map.get(method)) |request| {
// TODO: Unimplemented methods, implement them and add them to server capabilities.
if (request) {
return try respondGeneric(id, null_result_response);
}
logger.debug("Notification method {s} is not implemented", .{method});
return;
}
if (tree.root.Object.get("id")) |_| {
return try respondGeneric(id, not_implemented_response);
}