Skip to content

Commit

Permalink
Independent configs (#1810)
Browse files Browse the repository at this point in the history
* Independent configs

* Deduplicate analyser creation

* Fix tests
  • Loading branch information
SuperAuguste authored Mar 2, 2024
1 parent 70cf64e commit d034594
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 26 deletions.
39 changes: 28 additions & 11 deletions src/DocumentStore.zig
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ const Ast = std.zig.Ast;
const BuildAssociatedConfig = @import("BuildAssociatedConfig.zig");
const BuildConfig = @import("build_runner/BuildConfig.zig");
const tracy = @import("tracy");
const Config = @import("Config.zig");
const translate_c = @import("translate_c.zig");
const ComptimeInterpreter = @import("ComptimeInterpreter.zig");
const AstGen = std.zig.AstGen;
Expand All @@ -18,6 +17,15 @@ const DocumentScope = @import("DocumentScope.zig");

const DocumentStore = @This();

allocator: std.mem.Allocator,
/// the DocumentStore assumes that `config` is not modified while calling one of its functions.
config: Config,
lock: std.Thread.RwLock = .{},
thread_pool: if (builtin.single_threaded) void else *std.Thread.Pool,
handles: std.StringArrayHashMapUnmanaged(*Handle) = .{},
build_files: std.StringArrayHashMapUnmanaged(*BuildFile) = .{},
cimports: std.AutoArrayHashMapUnmanaged(Hash, translate_c.Result) = .{},

pub const Uri = []const u8;

pub const Hasher = std.crypto.auth.siphash.SipHash128(1, 3);
Expand All @@ -33,6 +41,24 @@ pub fn computeHash(bytes: []const u8) Hash {
return hash;
}

pub const Config = struct {
zig_exe_path: ?[]const u8,
zig_lib_path: ?[]const u8,
build_runner_path: ?[]const u8,
builtin_path: ?[]const u8,
global_cache_path: ?[]const u8,

pub fn fromMainConfig(config: @import("Config.zig")) Config {
return .{
.zig_exe_path = config.zig_exe_path,
.zig_lib_path = config.zig_lib_path,
.build_runner_path = config.build_runner_path,
.builtin_path = config.builtin_path,
.global_cache_path = config.global_cache_path,
};
}
};

pub const BuildFile = struct {
uri: Uri,
/// this build file may have an explicitly specified path to builtin.zig
Expand Down Expand Up @@ -595,15 +621,6 @@ pub const ErrorMessage = struct {
message: []const u8,
};

allocator: std.mem.Allocator,
/// the DocumentStore assumes that `config` is not modified while calling one of its functions.
config: *const Config,
lock: std.Thread.RwLock = .{},
thread_pool: if (builtin.single_threaded) void else *std.Thread.Pool,
handles: std.StringArrayHashMapUnmanaged(*Handle) = .{},
build_files: std.StringArrayHashMapUnmanaged(*BuildFile) = .{},
cimports: std.AutoArrayHashMapUnmanaged(Hash, translate_c.Result) = .{},

pub fn deinit(self: *DocumentStore) void {
for (self.handles.values()) |handle| {
handle.deinit();
Expand Down Expand Up @@ -1505,7 +1522,7 @@ pub fn resolveCImport(self: *DocumentStore, handle: *Handle, node: Ast.Node.Inde

const maybe_result = translate_c.translate(
self.allocator,
self.config.*,
self.config,
include_dirs.items,
source,
) catch |err| switch (err) {
Expand Down
31 changes: 22 additions & 9 deletions src/Server.zig
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,16 @@ fn showMessage(
}
}

fn initAnalyser(server: *Server, handle: ?*DocumentStore.Handle) Analyser {
return Analyser.init(
server.allocator,
&server.document_store,
&server.ip,
handle,
server.config.dangerous_comptime_experiments_do_not_enable,
);
}

fn getAutofixMode(server: *Server) enum {
on_save,
will_save_wait_until,
Expand All @@ -335,7 +345,7 @@ fn autofix(server: *Server, arena: std.mem.Allocator, handle: *DocumentStore.Han
try diagnostics_gen.getAstCheckDiagnostics(server, arena, handle, &diagnostics);
if (diagnostics.items.len == 0) return .{};

var analyser = Analyser.init(server.allocator, &server.document_store, &server.ip, handle);
var analyser = server.initAnalyser(handle);
defer analyser.deinit();

var builder = code_actions.Builder{
Expand Down Expand Up @@ -860,6 +870,8 @@ pub fn updateConfiguration(server: *Server, new_config: configuration.Configurat
}
}

server.document_store.config = DocumentStore.Config.fromMainConfig(server.config);

if (new_zig_exe_path or new_build_runner_path) blk: {
if (!std.process.can_spawn) break :blk;

Expand Down Expand Up @@ -1301,7 +1313,7 @@ fn semanticTokensFullHandler(server: *Server, arena: std.mem.Allocator, request:

const handle = server.document_store.getHandle(request.textDocument.uri) orelse return null;

var analyser = Analyser.init(server.allocator, &server.document_store, &server.ip, handle);
var analyser = server.initAnalyser(handle);
defer analyser.deinit();
// semantic tokens can be quite expensive to compute on large files
// and disabling callsite references can help with bringing the cost down.
Expand All @@ -1323,7 +1335,7 @@ fn semanticTokensRangeHandler(server: *Server, arena: std.mem.Allocator, request
const handle = server.document_store.getHandle(request.textDocument.uri) orelse return null;
const loc = offsets.rangeToLoc(handle.tree.source, request.range, server.offset_encoding);

var analyser = Analyser.init(server.allocator, &server.document_store, &server.ip, handle);
var analyser = server.initAnalyser(handle);
defer analyser.deinit();

return try semantic_tokens.writeSemanticTokens(
Expand All @@ -1341,7 +1353,7 @@ fn completionHandler(server: *Server, arena: std.mem.Allocator, request: types.C

const source_index = offsets.positionToIndex(handle.tree.source, request.position, server.offset_encoding);

var analyser = Analyser.init(server.allocator, &server.document_store, &server.ip, handle);
var analyser = server.initAnalyser(handle);
defer analyser.deinit();

return .{
Expand All @@ -1358,7 +1370,7 @@ fn signatureHelpHandler(server: *Server, arena: std.mem.Allocator, request: type

const markup_kind: types.MarkupKind = if (server.client_capabilities.signature_help_supports_md) .markdown else .plaintext;

var analyser = Analyser.init(server.allocator, &server.document_store, &server.ip, handle);
var analyser = server.initAnalyser(handle);
defer analyser.deinit();

const signature_info = (try signature_help.getSignatureInfo(
Expand Down Expand Up @@ -1434,7 +1446,7 @@ fn hoverHandler(server: *Server, arena: std.mem.Allocator, request: types.HoverP

const markup_kind: types.MarkupKind = if (server.client_capabilities.hover_supports_md) .markdown else .plaintext;

var analyser = Analyser.init(server.allocator, &server.document_store, &server.ip, handle);
var analyser = server.initAnalyser(handle);
defer analyser.deinit();

const response = hover_handler.hover(&analyser, arena, handle, source_index, markup_kind, server.offset_encoding);
Expand Down Expand Up @@ -1495,7 +1507,7 @@ fn inlayHintHandler(server: *Server, arena: std.mem.Allocator, request: types.In
const hover_kind: types.MarkupKind = if (server.client_capabilities.hover_supports_md) .markdown else .plaintext;
const loc = offsets.rangeToLoc(handle.tree.source, request.range, server.offset_encoding);

var analyser = Analyser.init(server.allocator, &server.document_store, &server.ip, handle);
var analyser = server.initAnalyser(handle);
defer analyser.deinit();

return try inlay_hints.writeRangeInlayHint(
Expand All @@ -1512,7 +1524,7 @@ fn inlayHintHandler(server: *Server, arena: std.mem.Allocator, request: types.In
fn codeActionHandler(server: *Server, arena: std.mem.Allocator, request: types.CodeActionParams) Error!ResultType("textDocument/codeAction") {
const handle = server.document_store.getHandle(request.textDocument.uri) orelse return null;

var analyser = Analyser.init(server.allocator, &server.document_store, &server.ip, handle);
var analyser = server.initAnalyser(handle);
defer analyser.deinit();

var builder = code_actions.Builder{
Expand Down Expand Up @@ -1821,9 +1833,10 @@ pub fn create(allocator: std.mem.Allocator) !*Server {
errdefer server.destroy();
server.* = Server{
.allocator = allocator,
.config = .{},
.document_store = .{
.allocator = allocator,
.config = &server.config,
.config = DocumentStore.Config.fromMainConfig(Config{}),
.thread_pool = if (zig_builtin.single_threaded) {} else undefined, // set below
},
.job_queue = std.fifo.LinearFifo(Job, .Dynamic).init(allocator),
Expand Down
12 changes: 10 additions & 2 deletions src/analysis.zig
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,17 @@ collect_callsite_references: bool,
resolve_number_literal_values: bool,
/// handle of the doc where the request originated
root_handle: ?*DocumentStore.Handle,
dangerous_comptime_experiments_do_not_enable: bool,

const NodeSet = std.HashMapUnmanaged(NodeWithUri, void, NodeWithUri.Context, std.hash_map.default_max_load_percentage);

pub fn init(gpa: std.mem.Allocator, store: *DocumentStore, ip: *InternPool, root_handle: ?*DocumentStore.Handle) Analyser {
pub fn init(
gpa: std.mem.Allocator,
store: *DocumentStore,
ip: *InternPool,
root_handle: ?*DocumentStore.Handle,
dangerous_comptime_experiments_do_not_enable: bool,
) Analyser {
return .{
.gpa = gpa,
.arena = std.heap.ArenaAllocator.init(gpa),
Expand All @@ -41,6 +48,7 @@ pub fn init(gpa: std.mem.Allocator, store: *DocumentStore, ip: *InternPool, root
.collect_callsite_references = true,
.resolve_number_literal_values = false,
.root_handle = root_handle,
.dangerous_comptime_experiments_do_not_enable = dangerous_comptime_experiments_do_not_enable,
};
}

Expand Down Expand Up @@ -1338,7 +1346,7 @@ fn resolveTypeOfNodeUncached(analyser: *Analyser, node_handle: NodeWithHandle) e
const body = func_tree.nodes.items(.data)[func_node].rhs;
if (try analyser.resolveReturnType(fn_proto, func_handle, if (has_body) body else null)) |ret| {
return ret;
} else if (analyser.store.config.dangerous_comptime_experiments_do_not_enable) {
} else if (analyser.dangerous_comptime_experiments_do_not_enable) {
// TODO: Better case-by-case; we just use the ComptimeInterpreter when all else fails,
// probably better to use it more liberally
// TODO: Handle non-isolate args; e.g. `const T = u8; TypeFunc(T);`
Expand Down
8 changes: 7 additions & 1 deletion src/features/goto.zig
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,13 @@ pub fn gotoHandler(
const handle = server.document_store.getHandle(request.textDocument.uri) orelse return null;
const source_index = offsets.positionToIndex(handle.tree.source, request.position, server.offset_encoding);

var analyser = Analyser.init(server.allocator, &server.document_store, &server.ip, handle);
var analyser = Analyser.init(
server.allocator,
&server.document_store,
&server.ip,
handle,
server.config.dangerous_comptime_experiments_do_not_enable,
);
defer analyser.deinit();

const pos_context = try Analyser.getPositionContext(arena, handle.tree.source, source_index, true);
Expand Down
8 changes: 7 additions & 1 deletion src/features/references.zig
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,13 @@ pub fn referencesHandler(server: *Server, arena: std.mem.Allocator, request: Gen
const name = offsets.locToSlice(handle.tree.source, name_loc);
const pos_context = try Analyser.getPositionContext(server.allocator, handle.tree.source, source_index, true);

var analyser = Analyser.init(server.allocator, &server.document_store, &server.ip, handle);
var analyser = Analyser.init(
server.allocator,
&server.document_store,
&server.ip,
handle,
server.config.dangerous_comptime_experiments_do_not_enable,
);
defer analyser.deinit();

// TODO: Make this work with branching types
Expand Down
2 changes: 1 addition & 1 deletion src/translate_c.zig
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const std = @import("std");
const zig_builtin = @import("builtin");
const builtin = @import("builtin");
const Config = @import("Config.zig");
const Config = @import("DocumentStore.zig").Config;
const ast = @import("ast.zig");
const tracy = @import("tracy");
const Ast = std.zig.Ast;
Expand Down
2 changes: 1 addition & 1 deletion tests/language_features/cimport.zig
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ fn testTranslate(c_source: []const u8) !translate_c.Result {
var ctx = try Context.init();
defer ctx.deinit();

const result = (try translate_c.translate(allocator, ctx.server.config, &.{}, c_source)).?;
const result = (try translate_c.translate(allocator, zls.DocumentStore.Config.fromMainConfig(ctx.server.config), &.{}, c_source)).?;

switch (result) {
.success => |uri| {
Expand Down

0 comments on commit d034594

Please sign in to comment.