Skip to content

Commit 2ffc21c

Browse files
committed
extend lifetime of analyser's arena allocations to the entire request
1 parent 02d7cb2 commit 2ffc21c

6 files changed

Lines changed: 50 additions & 50 deletions

File tree

src/Server.zig

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -297,9 +297,10 @@ fn showMessage(
297297
}
298298
}
299299

300-
pub fn initAnalyser(server: *Server, handle: ?*DocumentStore.Handle) Analyser {
300+
pub fn initAnalyser(server: *Server, arena: std.mem.Allocator, handle: ?*DocumentStore.Handle) Analyser {
301301
return .init(
302302
server.allocator,
303+
arena,
303304
&server.document_store,
304305
&server.ip,
305306
handle,
@@ -333,7 +334,7 @@ fn autofix(server: *Server, arena: std.mem.Allocator, handle: *DocumentStore.Han
333334
defer error_bundle.deinit(server.allocator);
334335
if (error_bundle.errorMessageCount() == 0) return .empty;
335336

336-
var analyser = server.initAnalyser(handle);
337+
var analyser = server.initAnalyser(arena, handle);
337338
defer analyser.deinit();
338339

339340
var builder: code_actions.Builder = .{
@@ -1651,7 +1652,7 @@ fn semanticTokensFullHandler(server: *Server, arena: std.mem.Allocator, request:
16511652
// Workaround: The Ast on .zon files is unusable when an error occured on the root expr
16521653
if (handle.tree.mode == .zon and handle.tree.errors.len > 0) return null;
16531654

1654-
var analyser = server.initAnalyser(handle);
1655+
var analyser = server.initAnalyser(arena, handle);
16551656
defer analyser.deinit();
16561657
// semantic tokens can be quite expensive to compute on large files
16571658
// and disabling callsite references can help with bringing the cost down.
@@ -1678,7 +1679,7 @@ fn semanticTokensRangeHandler(server: *Server, arena: std.mem.Allocator, request
16781679

16791680
const loc = offsets.rangeToLoc(handle.tree.source, request.range, server.offset_encoding);
16801681

1681-
var analyser = server.initAnalyser(handle);
1682+
var analyser = server.initAnalyser(arena, handle);
16821683
defer analyser.deinit();
16831684

16841685
return try semantic_tokens.writeSemanticTokens(
@@ -1698,7 +1699,7 @@ fn completionHandler(server: *Server, arena: std.mem.Allocator, request: types.C
16981699

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

1701-
var analyser = server.initAnalyser(handle);
1702+
var analyser = server.initAnalyser(arena, handle);
17021703
defer analyser.deinit();
17031704

17041705
return .{
@@ -1714,7 +1715,7 @@ fn signatureHelpHandler(server: *Server, arena: std.mem.Allocator, request: type
17141715

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

1717-
var analyser = server.initAnalyser(handle);
1718+
var analyser = server.initAnalyser(arena, handle);
17181719
defer analyser.deinit();
17191720

17201721
const signature_info = (try signature_help.getSignatureInfo(
@@ -1789,7 +1790,7 @@ fn hoverHandler(server: *Server, arena: std.mem.Allocator, request: types.HoverP
17891790

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

1792-
var analyser = server.initAnalyser(handle);
1793+
var analyser = server.initAnalyser(arena, handle);
17931794
defer analyser.deinit();
17941795

17951796
return hover_handler.hover(
@@ -1859,7 +1860,7 @@ fn inlayHintHandler(server: *Server, arena: std.mem.Allocator, request: types.In
18591860
const hover_kind: types.MarkupKind = if (server.client_capabilities.hover_supports_md) .markdown else .plaintext;
18601861
const loc = offsets.rangeToLoc(handle.tree.source, request.range, server.offset_encoding);
18611862

1862-
var analyser = server.initAnalyser(handle);
1863+
var analyser = server.initAnalyser(arena, handle);
18631864
defer analyser.deinit();
18641865

18651866
return try inlay_hints.writeRangeInlayHint(
@@ -1883,7 +1884,7 @@ fn codeActionHandler(server: *Server, arena: std.mem.Allocator, request: types.C
18831884
var error_bundle = try diagnostics_gen.getAstCheckDiagnostics(server, handle);
18841885
defer error_bundle.deinit(server.allocator);
18851886

1886-
var analyser = server.initAnalyser(handle);
1887+
var analyser = server.initAnalyser(arena, handle);
18871888
defer analyser.deinit();
18881889

18891890
const only_kinds = if (request.context.only) |kinds| blk: {

src/analysis.zig

Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub const Scope = DocumentScope.Scope;
2626
const Analyser = @This();
2727

2828
gpa: std.mem.Allocator,
29-
arena: std.heap.ArenaAllocator,
29+
arena: std.mem.Allocator,
3030
store: *DocumentStore,
3131
ip: *InternPool,
3232
// nested scopes with comptime bindings
@@ -45,13 +45,14 @@ const NodeSet = std.HashMapUnmanaged(NodeWithUri, void, NodeWithUri.Context, std
4545

4646
pub fn init(
4747
gpa: std.mem.Allocator,
48+
arena: std.mem.Allocator,
4849
store: *DocumentStore,
4950
ip: *InternPool,
5051
root_handle: ?*DocumentStore.Handle,
5152
) Analyser {
5253
return .{
5354
.gpa = gpa,
54-
.arena = .init(gpa),
55+
.arena = arena,
5556
.store = store,
5657
.ip = ip,
5758
.collect_callsite_references = true,
@@ -66,11 +67,10 @@ pub fn deinit(self: *Analyser) void {
6667
self.resolved_nodes.deinit(self.gpa);
6768
std.debug.assert(self.use_trail.count() == 0);
6869
self.use_trail.deinit(self.gpa);
69-
self.arena.deinit();
7070
}
7171

7272
fn allocType(analyser: *Analyser, ty: Type) error{OutOfMemory}!*Type {
73-
const ptr = try analyser.arena.allocator().create(Type);
73+
const ptr = try analyser.arena.create(Type);
7474
ptr.* = ty;
7575
return ptr;
7676
}
@@ -735,7 +735,7 @@ fn resolveVarDeclAliasInternal(analyser: *Analyser, node_handle: NodeWithHandle,
735735
const node_with_uri: NodeWithUri = .{
736736
.node = node_handle.node,
737737
.uri = node_handle.handle.uri,
738-
.bound_type_params_state_hash = try analyser.bound_type_params.hash(analyser.arena.allocator()),
738+
.bound_type_params_state_hash = try analyser.bound_type_params.hash(analyser.arena),
739739
};
740740

741741
const gop = try node_trail.getOrPut(analyser.gpa, node_with_uri);
@@ -796,7 +796,7 @@ fn resolveVarDeclAliasInternal(analyser: *Analyser, node_handle: NodeWithHandle,
796796
if (node_trail.contains(.{
797797
.node = resolved_node,
798798
.uri = resolved.handle.uri,
799-
.bound_type_params_state_hash = try analyser.bound_type_params.hash(analyser.arena.allocator()),
799+
.bound_type_params_state_hash = try analyser.bound_type_params.hash(analyser.arena),
800800
})) {
801801
return null;
802802
}
@@ -1622,7 +1622,7 @@ fn resolveBindingOfNodeInternal(analyser: *Analyser, node_handle: NodeWithHandle
16221622
const node_with_uri: NodeWithUri = .{
16231623
.node = node_handle.node,
16241624
.uri = node_handle.handle.uri,
1625-
.bound_type_params_state_hash = try analyser.bound_type_params.hash(analyser.arena.allocator()),
1625+
.bound_type_params_state_hash = try analyser.bound_type_params.hash(analyser.arena),
16261626
};
16271627
const gop = try analyser.resolved_nodes.getOrPut(analyser.gpa, node_with_uri);
16281628
if (gop.found_existing) return gop.value_ptr.*;
@@ -1686,8 +1686,8 @@ fn resolveTypeOfNodeUncached(analyser: *Analyser, node_handle: NodeWithHandle) e
16861686

16871687
const func_info = func_ty.data.function;
16881688

1689-
var meta_params: std.ArrayListUnmanaged(ScopeWithHandle.Param) = try .initCapacity(analyser.arena.allocator(), func_info.parameters.len);
1690-
errdefer meta_params.deinit(analyser.arena.allocator());
1689+
var meta_params: std.ArrayListUnmanaged(ScopeWithHandle.Param) = try .initCapacity(analyser.arena, func_info.parameters.len);
1690+
errdefer meta_params.deinit(analyser.arena);
16911691

16921692
const has_self_param = call.ast.params.len + 1 == func_info.parameters.len and
16931693
try analyser.isInstanceCall(handle, call, func_ty);
@@ -1702,8 +1702,7 @@ fn resolveTypeOfNodeUncached(analyser: *Analyser, node_handle: NodeWithHandle) e
17021702
const argument_type = (try analyser.resolveTypeOfNodeInternal(.of(arg, handle))) orelse continue;
17031703
if (!argument_type.is_type_val) continue;
17041704

1705-
const ptyp = try analyser.arena.allocator().create(Type);
1706-
ptyp.* = argument_type;
1705+
const ptyp = try analyser.allocType(argument_type);
17071706

17081707
const symbol = param.name orelse "";
17091708
meta_params.appendAssumeCapacity(.{ .index = param_index, .symbol = symbol, .typ = ptyp });
@@ -1892,7 +1891,7 @@ fn resolveTypeOfNodeUncached(analyser: *Analyser, node_handle: NodeWithHandle) e
18921891
return array_ty.instanceTypeVal(analyser);
18931892
}
18941893

1895-
const elem_ty_slice = try analyser.arena.allocator().alloc(Type, array_init_info.ast.elements.len);
1894+
const elem_ty_slice = try analyser.arena.alloc(Type, array_init_info.ast.elements.len);
18961895
for (elem_ty_slice, array_init_info.ast.elements) |*elem_ty, element| {
18971896
elem_ty.* = try analyser.resolveTypeOfNodeInternal(.of(element, handle)) orelse return null;
18981897
elem_ty.* = elem_ty.typeOf(analyser);
@@ -1985,7 +1984,7 @@ fn resolveTypeOfNodeUncached(analyser: *Analyser, node_handle: NodeWithHandle) e
19851984
const container_decl = tree.fullContainerDecl(&buffer, node).?;
19861985
if (container_decl.ast.members.len == 0) break :not_a_tuple; // technically a tuple
19871986
if (tree.tokenTag(container_decl.ast.main_token) != .keyword_struct) break :not_a_tuple;
1988-
const elem_ty_slice = try analyser.arena.allocator().alloc(Type, container_decl.ast.members.len);
1987+
const elem_ty_slice = try analyser.arena.alloc(Type, container_decl.ast.members.len);
19891988

19901989
var has_unresolved_fields = false;
19911990
for (elem_ty_slice, container_decl.ast.members) |*elem_ty, member_node| {
@@ -2131,11 +2130,11 @@ fn resolveTypeOfNodeUncached(analyser: *Analyser, node_handle: NodeWithHandle) e
21312130

21322131
const import_str = tree.tokenSlice(tree.nodeMainToken(import_param));
21332132
const import_uri = (try analyser.store.uriFromImportStr(
2134-
analyser.arena.allocator(),
2133+
analyser.arena,
21352134
handle,
21362135
import_str[1 .. import_str.len - 1],
21372136
)) orelse (try analyser.store.uriFromImportStr(
2138-
analyser.arena.allocator(),
2137+
analyser.arena,
21392138
analyser.root_handle orelse return null,
21402139
import_str[1 .. import_str.len - 1],
21412140
)) orelse return null;
@@ -2242,7 +2241,7 @@ fn resolveTypeOfNodeUncached(analyser: *Analyser, node_handle: NodeWithHandle) e
22422241
const fn_proto = tree.fullFnProto(&buf, node).?;
22432242

22442243
const container_type = try analyser.innermostContainer(handle, tree.tokenStart(fn_proto.ast.fn_token));
2245-
const doc_comments = try getDocComments(analyser.arena.allocator(), tree, node);
2244+
const doc_comments = try getDocComments(analyser.arena, tree, node);
22462245
const name = if (fn_proto.name_token) |t| tree.tokenSlice(t) else null;
22472246

22482247
var parameters: std.ArrayListUnmanaged(Type.Data.Parameter) = .empty;
@@ -2256,7 +2255,7 @@ fn resolveTypeOfNodeUncached(analyser: *Analyser, node_handle: NodeWithHandle) e
22562255

22572256
var param_comments: ?[]const u8 = null;
22582257
if (param.first_doc_comment) |dc| {
2259-
param_comments = try collectDocComments(analyser.arena.allocator(), tree, dc, false);
2258+
param_comments = try collectDocComments(analyser.arena, tree, dc, false);
22602259
}
22612260

22622261
var param_modifier: ?Type.Data.Parameter.Modifier = null;
@@ -2298,7 +2297,7 @@ fn resolveTypeOfNodeUncached(analyser: *Analyser, node_handle: NodeWithHandle) e
22982297
break :param_type Type.fromIP(analyser, .type_type, .unknown_type);
22992298
};
23002299

2301-
try parameters.append(analyser.arena.allocator(), .{
2300+
try parameters.append(analyser.arena, .{
23022301
.doc_comments = param_comments,
23032302
.modifier = param_modifier,
23042303
.name = param_name,
@@ -2347,7 +2346,7 @@ fn resolveTypeOfNodeUncached(analyser: *Analyser, node_handle: NodeWithHandle) e
23472346
}
23482347
if (if_node.ast.else_expr.unwrap()) |else_expr| {
23492348
if (try analyser.resolveTypeOfNodeInternal(.of(else_expr, handle))) |t| {
2350-
either.appendAssumeCapacity(.{ .type = t, .descriptor = try std.fmt.allocPrint(analyser.arena.allocator(), "!({s})", .{offsets.nodeToSlice(tree, if_node.ast.cond_expr)}) });
2349+
either.appendAssumeCapacity(.{ .type = t, .descriptor = try std.fmt.allocPrint(analyser.arena, "!({s})", .{offsets.nodeToSlice(tree, if_node.ast.cond_expr)}) });
23512350
}
23522351
}
23532352
return Type.fromEither(analyser, either.constSlice());
@@ -2363,14 +2362,14 @@ fn resolveTypeOfNodeUncached(analyser: *Analyser, node_handle: NodeWithHandle) e
23632362
var descriptor: std.ArrayListUnmanaged(u8) = .empty;
23642363

23652364
for (switch_case.ast.values, 0..) |values, index| {
2366-
try descriptor.appendSlice(analyser.arena.allocator(), offsets.nodeToSlice(tree, values));
2367-
if (index != switch_case.ast.values.len - 1) try descriptor.appendSlice(analyser.arena.allocator(), ", ");
2365+
try descriptor.appendSlice(analyser.arena, offsets.nodeToSlice(tree, values));
2366+
if (index != switch_case.ast.values.len - 1) try descriptor.appendSlice(analyser.arena, ", ");
23682367
}
23692368

23702369
if (try analyser.resolveTypeOfNodeInternal(.of(switch_case.ast.target_expr, handle))) |t|
2371-
try either.append(analyser.arena.allocator(), .{
2370+
try either.append(analyser.arena, .{
23722371
.type = t,
2373-
.descriptor = try descriptor.toOwnedSlice(analyser.arena.allocator()),
2372+
.descriptor = try descriptor.toOwnedSlice(analyser.arena),
23742373
});
23752374
}
23762375

@@ -3113,7 +3112,7 @@ pub const Type = struct {
31133112
};
31143113

31153114
pub fn fromEither(analyser: *Analyser, entries: []const TypeWithDescriptor) error{OutOfMemory}!?Type {
3116-
const arena = analyser.arena.allocator();
3115+
const arena = analyser.arena;
31173116
if (entries.len == 0)
31183117
return null;
31193118

@@ -3507,7 +3506,7 @@ pub const Type = struct {
35073506
const analyser = ctx.analyser;
35083507
const options = ctx.options;
35093508
const referenced = options.referenced;
3510-
const arena = analyser.arena.allocator();
3509+
const arena = analyser.arena;
35113510

35123511
switch (ty.data) {
35133512
.pointer => |info| {
@@ -3812,8 +3811,8 @@ pub const BoundTypeParams = struct {
38123811
/// Useful for functionality related to builtin fns
38133812
pub fn instanceStdBuiltinType(analyser: *Analyser, type_name: []const u8) error{OutOfMemory}!?Type {
38143813
const zig_lib_dir = analyser.store.config.zig_lib_dir orelse return null;
3815-
const builtin_path = try zig_lib_dir.join(analyser.arena.allocator(), &.{ "std", "builtin.zig" });
3816-
const builtin_uri = try URI.fromPath(analyser.arena.allocator(), builtin_path);
3814+
const builtin_path = try zig_lib_dir.join(analyser.arena, &.{ "std", "builtin.zig" });
3815+
const builtin_uri = try URI.fromPath(analyser.arena, builtin_path);
38173816

38183817
const builtin_handle = analyser.store.getOrLoadHandle(builtin_uri) orelse return null;
38193818
const builtin_root_struct_type: Type = .{
@@ -3926,7 +3925,7 @@ pub fn getFieldAccessType(
39263925
source_index: usize,
39273926
loc: offsets.Loc,
39283927
) error{OutOfMemory}!?Type {
3929-
const held_range = try analyser.arena.allocator().dupeZ(u8, offsets.locToSlice(handle.tree.source, loc));
3928+
const held_range = try analyser.arena.dupeZ(u8, offsets.locToSlice(handle.tree.source, loc));
39303929
var tokenizer: std.zig.Tokenizer = .init(held_range);
39313930
var current_type: ?Type = null;
39323931

@@ -4074,7 +4073,7 @@ pub fn getFieldAccessType(
40744073
.start = import_str_tok.loc.start + 1,
40754074
.end = import_str_tok.loc.end - 1,
40764075
});
4077-
const uri = try analyser.store.uriFromImportStr(analyser.arena.allocator(), handle, import_str) orelse return null;
4076+
const uri = try analyser.store.uriFromImportStr(analyser.arena, handle, import_str) orelse return null;
40784077
const node_handle = analyser.store.getOrLoadHandle(uri) orelse return null;
40794078
current_type = .{
40804079
.data = .{
@@ -4713,7 +4712,7 @@ pub const DeclWithHandle = struct {
47134712
}
47144713

47154714
const refs = try references.callsiteReferences(
4716-
analyser.arena.allocator(),
4715+
analyser.arena,
47174716
analyser,
47184717
.{ .decl = func_decl, .handle = self.handle },
47194718
false,
@@ -4755,9 +4754,9 @@ pub const DeclWithHandle = struct {
47554754
};
47564755

47574756
const loc = offsets.tokenToPosition(tree, tree.nodeMainToken(call.ast.params[real_param_idx]), .@"utf-8");
4758-
try possible.append(analyser.arena.allocator(), .{
4757+
try possible.append(analyser.arena, .{
47594758
.type = ty,
4760-
.descriptor = try std.fmt.allocPrint(analyser.arena.allocator(), "{s}:{d}:{d}", .{ handle.uri, loc.line + 1, loc.character + 1 }),
4759+
.descriptor = try std.fmt.allocPrint(analyser.arena, "{s}:{d}:{d}", .{ handle.uri, loc.line + 1, loc.character + 1 }),
47614760
});
47624761
}
47634762

@@ -4853,7 +4852,7 @@ pub fn collectDeclarationsOfContainer(
48534852
/// const instance = @as(struct{}, ...);
48544853
/// ```
48554854
instance_access: bool,
4856-
/// allocated with `analyser.arena.allocator()`
4855+
/// allocated with `analyser.arena`
48574856
decl_collection: *std.ArrayListUnmanaged(DeclWithHandle),
48584857
) error{OutOfMemory}!void {
48594858
const scope = container_scope.scope;
@@ -4916,7 +4915,7 @@ pub fn collectDeclarationsOfContainer(
49164915
else => {},
49174916
}
49184917

4919-
try decl_collection.append(analyser.arena.allocator(), decl_with_handle);
4918+
try decl_collection.append(analyser.arena, decl_with_handle);
49204919
}
49214920

49224921
for (document_scope.getScopeUsingnamespaceNodesConst(scope)) |use| {
@@ -4992,7 +4991,7 @@ pub fn collectAllSymbolsAtSourceIndex(
49924991
handle: *DocumentStore.Handle,
49934992
/// a byte-index into `handle.tree.source`
49944993
source_index: usize,
4995-
/// allocated with `analyser.arena.allocator()`
4994+
/// allocated with `analyser.arena`
49964995
decl_collection: *std.ArrayListUnmanaged(DeclWithHandle),
49974996
) error{OutOfMemory}!void {
49984997
std.debug.assert(source_index <= handle.tree.source.len);
@@ -5006,7 +5005,7 @@ pub fn collectAllSymbolsAtSourceIndex(
50065005
const decl = document_scope.declarations.get(@intFromEnum(decl_index));
50075006
if (decl == .ast_node and handle.tree.nodeTag(decl.ast_node).isContainerField()) continue;
50085007
if (decl == .label) continue;
5009-
try decl_collection.append(analyser.arena.allocator(), .{ .decl = decl, .handle = handle });
5008+
try decl_collection.append(analyser.arena, .{ .decl = decl, .handle = handle });
50105009
}
50115010

50125011
for (document_scope.getScopeUsingnamespaceNodesConst(scope_index)) |use| {
@@ -5647,7 +5646,7 @@ pub fn getSymbolEnumLiteral(
56475646
defer tracy_zone.end();
56485647

56495648
const tree = handle.tree;
5650-
const nodes = try ast.nodesOverlappingIndex(analyser.arena.allocator(), tree, source_index);
5649+
const nodes = try ast.nodesOverlappingIndex(analyser.arena, tree, source_index);
56515650
if (nodes.len == 0) return null;
56525651
return analyser.lookupSymbolFieldInit(handle, name, nodes[0], nodes[1..]);
56535652
}

src/features/diagnostics.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ pub fn generateDiagnostics(
6363
var diagnostics: std.ArrayListUnmanaged(types.Diagnostic) = .empty;
6464

6565
if (server.getAutofixMode() != .none and handle.tree.mode == .zig) {
66-
var analyser = server.initAnalyser(handle);
66+
var analyser = server.initAnalyser(arena, handle);
6767
defer analyser.deinit();
6868
try code_actions.collectAutoDiscardDiagnostics(&analyser, handle, arena, &diagnostics, server.offset_encoding);
6969
}

src/features/goto.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ pub fn gotoHandler(
236236
const handle = server.document_store.getHandle(request.textDocument.uri) orelse return null;
237237
if (handle.tree.mode == .zon) return null;
238238

239-
var analyser = server.initAnalyser(handle);
239+
var analyser = server.initAnalyser(arena, handle);
240240
defer analyser.deinit();
241241

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

0 commit comments

Comments
 (0)