Implement $/setTrace and add --enable-message-tracing (#1135)

This commit is contained in:
Casey Banner 2023-04-16 12:04:42 -04:00 committed by GitHub
parent 421ae86917
commit 3ae56929fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 1 deletions

View File

@ -48,6 +48,7 @@ runtime_zig_version: ?ZigVersionWrapper,
outgoing_messages: std.ArrayListUnmanaged([]const u8) = .{}, outgoing_messages: std.ArrayListUnmanaged([]const u8) = .{},
recording_enabled: bool, recording_enabled: bool,
replay_enabled: bool, replay_enabled: bool,
message_tracing_enabled: bool = false,
offset_encoding: offsets.Encoding = .@"utf-16", offset_encoding: offsets.Encoding = .@"utf-16",
status: enum { status: enum {
/// the server has not received a `initialize` request /// the server has not received a `initialize` request
@ -450,6 +451,13 @@ fn initializeHandler(server: *Server, request: types.InitializeParams) Error!typ
} }
} }
if (request.trace) |trace| {
// To support --enable-message-tracing, only allow turning this on here
if (trace != .off) {
server.message_tracing_enabled = true;
}
}
log.info("zls initializing", .{}); log.info("zls initializing", .{});
log.info("{}", .{server.client_capabilities}); log.info("{}", .{server.client_capabilities});
log.info("Using offset encoding: {s}", .{std.meta.tagName(server.offset_encoding)}); log.info("Using offset encoding: {s}", .{std.meta.tagName(server.offset_encoding)});
@ -614,6 +622,10 @@ fn cancelRequestHandler(server: *Server, request: types.CancelParams) Error!void
// TODO implement $/cancelRequest // TODO implement $/cancelRequest
} }
fn setTraceHandler(server: *Server, request: types.SetTraceParams) Error!void {
server.message_tracing_enabled = request.value != .off;
}
fn registerCapability(server: *Server, method: []const u8) Error!void { fn registerCapability(server: *Server, method: []const u8) Error!void {
const allocator = server.arena.allocator(); const allocator = server.arena.allocator();
@ -1449,6 +1461,7 @@ pub fn processMessage(server: *Server, message: Message) Error!void {
.{ "shutdown", shutdownHandler }, .{ "shutdown", shutdownHandler },
.{ "exit", exitHandler }, .{ "exit", exitHandler },
.{ "$/cancelRequest", cancelRequestHandler }, .{ "$/cancelRequest", cancelRequestHandler },
.{ "$/setTrace", setTraceHandler },
.{ "textDocument/didOpen", openDocumentHandler }, .{ "textDocument/didOpen", openDocumentHandler },
.{ "textDocument/didChange", changeDocumentHandler }, .{ "textDocument/didChange", changeDocumentHandler },
.{ "textDocument/didSave", saveDocumentHandler }, .{ "textDocument/didSave", saveDocumentHandler },
@ -1533,6 +1546,7 @@ pub fn create(
config_path: ?[]const u8, config_path: ?[]const u8,
recording_enabled: bool, recording_enabled: bool,
replay_enabled: bool, replay_enabled: bool,
message_tracing_enabled: bool,
) !*Server { ) !*Server {
const server = try allocator.create(Server); const server = try allocator.create(Server);
server.* = Server{ server.* = Server{
@ -1549,6 +1563,7 @@ pub fn create(
.builtin_completions = null, .builtin_completions = null,
.recording_enabled = recording_enabled, .recording_enabled = recording_enabled,
.replay_enabled = replay_enabled, .replay_enabled = replay_enabled,
.message_tracing_enabled = message_tracing_enabled,
.status = .uninitialized, .status = .uninitialized,
}; };
server.analyser = Analyser.init(allocator, &server.document_store); server.analyser = Analyser.init(allocator, &server.document_store);

View File

@ -11,6 +11,7 @@ const Header = @import("Header.zig");
const debug = @import("debug.zig"); const debug = @import("debug.zig");
const logger = std.log.scoped(.zls_main); const logger = std.log.scoped(.zls_main);
const message_logger = std.log.scoped(.message);
var actual_log_level: std.log.Level = switch (zig_builtin.mode) { var actual_log_level: std.log.Level = switch (zig_builtin.mode) {
.Debug => .debug, .Debug => .debug,
@ -60,6 +61,7 @@ fn loop(
const header = Header{ .content_length = outgoing_message.len }; const header = Header{ .content_length = outgoing_message.len };
try header.write(true, writer); try header.write(true, writer);
try writer.writeAll(outgoing_message); try writer.writeAll(outgoing_message);
if (server.message_tracing_enabled) message_logger.info("sent: {s}\n", .{outgoing_message});
} }
try buffered_writer.flush(); try buffered_writer.flush();
for (server.outgoing_messages.items) |outgoing_message| { for (server.outgoing_messages.items) |outgoing_message| {
@ -78,6 +80,7 @@ fn loop(
try file.writeAll(json_message); try file.writeAll(json_message);
} }
if (server.message_tracing_enabled) message_logger.info("received: {s}\n", .{json_message});
server.processJsonRpc(json_message); server.processJsonRpc(json_message);
if (server.status == .exiting_success or server.status == .exiting_failure) return; if (server.status == .exiting_success or server.status == .exiting_failure) return;
@ -195,6 +198,7 @@ const ParseArgsResult = struct {
config_path: ?[]const u8, config_path: ?[]const u8,
replay_enabled: bool, replay_enabled: bool,
replay_session_path: ?[]const u8, replay_session_path: ?[]const u8,
message_tracing_enabled: bool,
}; };
fn parseArgs(allocator: std.mem.Allocator) !ParseArgsResult { fn parseArgs(allocator: std.mem.Allocator) !ParseArgsResult {
@ -203,6 +207,7 @@ fn parseArgs(allocator: std.mem.Allocator) !ParseArgsResult {
.config_path = null, .config_path = null,
.replay_enabled = false, .replay_enabled = false,
.replay_session_path = null, .replay_session_path = null,
.message_tracing_enabled = false,
}; };
const ArgId = enum { const ArgId = enum {
@ -210,6 +215,7 @@ fn parseArgs(allocator: std.mem.Allocator) !ParseArgsResult {
version, version,
replay, replay,
@"enable-debug-log", @"enable-debug-log",
@"enable-message-tracing",
@"show-config-path", @"show-config-path",
@"config-path", @"config-path",
}; };
@ -236,6 +242,7 @@ fn parseArgs(allocator: std.mem.Allocator) !ParseArgsResult {
.version = "Prints the compiler version with which the server was compiled.", .version = "Prints the compiler version with which the server was compiled.",
.replay = "Replay a previous recorded zls session", .replay = "Replay a previous recorded zls session",
.@"enable-debug-log" = "Enables debug logs.", .@"enable-debug-log" = "Enables debug logs.",
.@"enable-message-tracing" = "Enables message tracing.",
.@"config-path" = "Specify the path to a configuration file specifying LSP behaviour.", .@"config-path" = "Specify the path to a configuration file specifying LSP behaviour.",
.@"show-config-path" = "Prints the path to the configuration file to stdout", .@"show-config-path" = "Prints the path to the configuration file to stdout",
}); });
@ -281,6 +288,7 @@ fn parseArgs(allocator: std.mem.Allocator) !ParseArgsResult {
.help, .help,
.version, .version,
.@"enable-debug-log", .@"enable-debug-log",
.@"enable-message-tracing",
.@"show-config-path", .@"show-config-path",
=> {}, => {},
.@"config-path" => { .@"config-path" => {
@ -310,6 +318,10 @@ fn parseArgs(allocator: std.mem.Allocator) !ParseArgsResult {
actual_log_level = .debug; actual_log_level = .debug;
logger.info("Enabled debug logging.\n", .{}); logger.info("Enabled debug logging.\n", .{});
} }
if (specified.get(.@"enable-message-tracing")) {
result.message_tracing_enabled = true;
logger.info("Enabled message tracing.\n", .{});
}
if (specified.get(.@"config-path")) { if (specified.get(.@"config-path")) {
std.debug.assert(result.config_path != null); std.debug.assert(result.config_path != null);
} }
@ -390,6 +402,7 @@ pub fn main() !void {
config.config_path, config.config_path,
record_file != null, record_file != null,
replay_file != null, replay_file != null,
result.message_tracing_enabled,
); );
defer server.destroy(); defer server.destroy();

View File

@ -41,7 +41,7 @@ pub const Context = struct {
config.* = default_config; config.* = default_config;
const server = try Server.create(allocator, config, null, false, false); const server = try Server.create(allocator, config, null, false, false, false);
errdefer server.destroy(); errdefer server.destroy();
var context: Context = .{ var context: Context = .{