Compare commits
No commits in common. "aeb734ba64ccbaa499f090138e394292473bff9e" and "5d256413dad6e75da1c71aede6be6c4e3a069a95" have entirely different histories.
aeb734ba64
...
5d256413da
3 changed files with 14 additions and 83 deletions
76
src/LSP.zig
76
src/LSP.zig
|
|
@ -67,45 +67,6 @@ pub fn send_notification_raw(self: *const Self, method: []const u8, cb: []const
|
||||||
self.pid.send(.{ "NTFY", method, cb }) catch return error.SendFailed;
|
self.pid.send(.{ "NTFY", method, cb }) catch return error.SendFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const ErrorCode = enum(i32) {
|
|
||||||
|
|
||||||
// Defined by JSON-RPC
|
|
||||||
ParseError = -32700,
|
|
||||||
InvalidRequest = -32600,
|
|
||||||
MethodNotFound = -32601,
|
|
||||||
InvalidParams = -32602,
|
|
||||||
InternalError = -32603,
|
|
||||||
|
|
||||||
// Defined by LSP
|
|
||||||
RequestFailed = -32803,
|
|
||||||
ServerCancelled = -32802,
|
|
||||||
ContentModified = -32801,
|
|
||||||
RequestCancelled = -32800,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn send_response(allocator: std.mem.Allocator, to: tp.pid_ref, cbor_id: []const u8, result: anytype) (SendError || OutOfMemoryError)!void {
|
|
||||||
var cb = std.ArrayList(u8).init(allocator);
|
|
||||||
defer cb.deinit();
|
|
||||||
const writer = cb.writer();
|
|
||||||
try cbor.writeArrayHeader(writer, 3);
|
|
||||||
try cbor.writeValue(writer, "RSP");
|
|
||||||
try writer.writeAll(cbor_id);
|
|
||||||
try cbor.writeValue(cb.writer(), result);
|
|
||||||
to.send_raw(.{ .buf = cb.items }) catch return error.SendFailed;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn send_error_response(allocator: std.mem.Allocator, to: tp.pid_ref, cbor_id: []const u8, code: ErrorCode, message: []const u8) (SendError || OutOfMemoryError)!void {
|
|
||||||
var cb = std.ArrayList(u8).init(allocator);
|
|
||||||
defer cb.deinit();
|
|
||||||
const writer = cb.writer();
|
|
||||||
try cbor.writeArrayHeader(writer, 4);
|
|
||||||
try cbor.writeValue(writer, "ERR");
|
|
||||||
try writer.writeAll(cbor_id);
|
|
||||||
try cbor.writeValue(cb.writer(), code);
|
|
||||||
try cbor.writeValue(cb.writer(), message);
|
|
||||||
to.send_raw(.{ .buf = cb.items }) catch return error.SendFailed;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn close(self: *Self) void {
|
pub fn close(self: *Self) void {
|
||||||
self.deinit();
|
self.deinit();
|
||||||
}
|
}
|
||||||
|
|
@ -291,8 +252,6 @@ const Process = struct {
|
||||||
var err: []const u8 = "";
|
var err: []const u8 = "";
|
||||||
var code: u32 = 0;
|
var code: u32 = 0;
|
||||||
var cbor_id: []const u8 = "";
|
var cbor_id: []const u8 = "";
|
||||||
var error_code: ErrorCode = undefined;
|
|
||||||
var message: []const u8 = "";
|
|
||||||
|
|
||||||
if (try cbor.match(m.buf, .{ "REQ", "initialize", tp.extract(&bytes) })) {
|
if (try cbor.match(m.buf, .{ "REQ", "initialize", tp.extract(&bytes) })) {
|
||||||
try self.send_request(from, "initialize", bytes);
|
try self.send_request(from, "initialize", bytes);
|
||||||
|
|
@ -303,8 +262,6 @@ const Process = struct {
|
||||||
}
|
}
|
||||||
} else if (try cbor.match(m.buf, .{ "RSP", tp.extract_cbor(&cbor_id), tp.extract_cbor(&bytes) })) {
|
} else if (try cbor.match(m.buf, .{ "RSP", tp.extract_cbor(&cbor_id), tp.extract_cbor(&bytes) })) {
|
||||||
try self.send_response(cbor_id, bytes);
|
try self.send_response(cbor_id, bytes);
|
||||||
} else if (try cbor.match(m.buf, .{ "ERR", tp.extract_cbor(&cbor_id), tp.extract(&error_code), tp.extract(&message) })) {
|
|
||||||
try self.send_error_response(cbor_id, error_code, message);
|
|
||||||
} else if (try cbor.match(m.buf, .{ "NTFY", "initialized", tp.extract(&bytes) })) {
|
} else if (try cbor.match(m.buf, .{ "NTFY", "initialized", tp.extract(&bytes) })) {
|
||||||
self.state = .running;
|
self.state = .running;
|
||||||
try self.send_notification("initialized", bytes);
|
try self.send_notification("initialized", bytes);
|
||||||
|
|
@ -525,39 +482,6 @@ const Process = struct {
|
||||||
self.write_log("### SEND response:\n{s}\n###\n", .{output.items});
|
self.write_log("### SEND response:\n{s}\n###\n", .{output.items});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_error_response(self: *Process, cbor_id: []const u8, error_code: ErrorCode, message: []const u8) (error{Closed} || SendError || cbor.Error || cbor.JsonEncodeError)!void {
|
|
||||||
const sp = if (self.sp) |*sp| sp else return error.Closed;
|
|
||||||
|
|
||||||
var msg = std.ArrayList(u8).init(self.allocator);
|
|
||||||
defer msg.deinit();
|
|
||||||
const msg_writer = msg.writer();
|
|
||||||
try cbor.writeMapHeader(msg_writer, 3);
|
|
||||||
try cbor.writeValue(msg_writer, "jsonrpc");
|
|
||||||
try cbor.writeValue(msg_writer, "2.0");
|
|
||||||
try cbor.writeValue(msg_writer, "id");
|
|
||||||
try msg_writer.writeAll(cbor_id);
|
|
||||||
try cbor.writeValue(msg_writer, "error");
|
|
||||||
try cbor.writeMapHeader(msg_writer, 2);
|
|
||||||
try cbor.writeValue(msg_writer, "code");
|
|
||||||
try cbor.writeValue(msg_writer, @intFromEnum(error_code));
|
|
||||||
try cbor.writeValue(msg_writer, "message");
|
|
||||||
try cbor.writeValue(msg_writer, message);
|
|
||||||
|
|
||||||
const json = try cbor.toJsonAlloc(self.allocator, msg.items);
|
|
||||||
defer self.allocator.free(json);
|
|
||||||
var output = std.ArrayList(u8).init(self.allocator);
|
|
||||||
defer output.deinit();
|
|
||||||
const writer = output.writer();
|
|
||||||
const terminator = "\r\n";
|
|
||||||
const content_length = json.len + terminator.len;
|
|
||||||
try writer.print("Content-Length: {d}\r\nContent-Type: application/vscode-jsonrpc; charset=utf-8\r\n\r\n", .{content_length});
|
|
||||||
_ = try writer.write(json);
|
|
||||||
_ = try writer.write(terminator);
|
|
||||||
|
|
||||||
sp.send(output.items) catch return error.SendFailed;
|
|
||||||
self.write_log("### SEND error response:\n{s}\n###\n", .{output.items});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn send_notification(self: *Process, method: []const u8, params_cb: []const u8) Error!void {
|
fn send_notification(self: *Process, method: []const u8, params_cb: []const u8) Error!void {
|
||||||
const sp = if (self.sp) |*sp| sp else return error.Closed;
|
const sp = if (self.sp) |*sp| sp else return error.Closed;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1494,16 +1494,23 @@ pub fn show_message(self: *Self, _: tp.pid_ref, params_cb: []const u8) !void {
|
||||||
|
|
||||||
pub fn register_capability(self: *Self, from: tp.pid_ref, cbor_id: []const u8, params_cb: []const u8) ClientError!void {
|
pub fn register_capability(self: *Self, from: tp.pid_ref, cbor_id: []const u8, params_cb: []const u8) ClientError!void {
|
||||||
_ = params_cb;
|
_ = params_cb;
|
||||||
return LSP.send_response(self.allocator, from, cbor_id, null) catch error.ClientFailed;
|
return self.send_lsp_response(from, cbor_id, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn workDoneProgress_create(self: *Self, from: tp.pid_ref, cbor_id: []const u8, params_cb: []const u8) ClientError!void {
|
pub fn workDoneProgress_create(self: *Self, from: tp.pid_ref, cbor_id: []const u8, params_cb: []const u8) ClientError!void {
|
||||||
_ = params_cb;
|
_ = params_cb;
|
||||||
return LSP.send_response(self.allocator, from, cbor_id, null) catch error.ClientFailed;
|
return self.send_lsp_response(from, cbor_id, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unsupported_lsp_request(self: *Self, from: tp.pid_ref, cbor_id: []const u8, method: []const u8) ClientError!void {
|
pub fn send_lsp_response(self: *Self, from: tp.pid_ref, cbor_id: []const u8, result: anytype) ClientError!void {
|
||||||
return LSP.send_error_response(self.allocator, from, cbor_id, LSP.ErrorCode.MethodNotFound, method) catch error.ClientFailed;
|
var cb = std.ArrayList(u8).init(self.allocator);
|
||||||
|
defer cb.deinit();
|
||||||
|
const writer = cb.writer();
|
||||||
|
try cbor.writeArrayHeader(writer, 3);
|
||||||
|
try cbor.writeValue(writer, "RSP");
|
||||||
|
try writer.writeAll(cbor_id);
|
||||||
|
try cbor.writeValue(cb.writer(), result);
|
||||||
|
from.send_raw(.{ .buf = cb.items }) catch return error.ClientFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_lsp_init_request(self: *Self, lsp: *const LSP, project_path: []const u8, project_basename: []const u8, project_uri: []const u8, language_server: []const u8) !void {
|
fn send_lsp_init_request(self: *Self, lsp: *const LSP, project_path: []const u8, project_basename: []const u8, project_uri: []const u8, language_server: []const u8) !void {
|
||||||
|
|
|
||||||
|
|
@ -620,11 +620,11 @@ const Process = struct {
|
||||||
project.register_capability(from, cbor_id, params_cb)
|
project.register_capability(from, cbor_id, params_cb)
|
||||||
else if (std.mem.eql(u8, method, "window/workDoneProgress/create"))
|
else if (std.mem.eql(u8, method, "window/workDoneProgress/create"))
|
||||||
project.workDoneProgress_create(from, cbor_id, params_cb)
|
project.workDoneProgress_create(from, cbor_id, params_cb)
|
||||||
else {
|
else blk: {
|
||||||
const params = try cbor.toJsonAlloc(self.allocator, params_cb);
|
const params = try cbor.toJsonAlloc(self.allocator, params_cb);
|
||||||
defer self.allocator.free(params);
|
defer self.allocator.free(params);
|
||||||
self.logger.print("unsupported LSP request: {s} -> {s}", .{ method, params });
|
self.logger.print_err("lsp", "unsupported LSP request: {s} -> {s}", .{ method, params });
|
||||||
project.unsupported_lsp_request(from, cbor_id, method) catch {};
|
break :blk error.Unsupported;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue