Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize analysis backend #1062

Merged
merged 6 commits into from
Mar 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 67 additions & 72 deletions src/Server.zig

Large diffs are not rendered by default.

935 changes: 487 additions & 448 deletions src/analysis.zig

Large diffs are not rendered by default.

12 changes: 4 additions & 8 deletions src/code_actions.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ const std = @import("std");
const Ast = std.zig.Ast;

const DocumentStore = @import("DocumentStore.zig");
const analysis = @import("analysis.zig");
const Analyser = @import("analysis.zig");
const ast = @import("ast.zig");

const types = @import("lsp.zig");
const offsets = @import("offsets.zig");

pub const Builder = struct {
arena: std.mem.Allocator,
document_store: *DocumentStore,
analyser: *Analyser,
handle: *const DocumentStore.Handle,
offset_encoding: offsets.Encoding,

Expand Down Expand Up @@ -88,9 +88,7 @@ fn handleUnusedFunctionParameter(builder: *Builder, actions: *std.ArrayListUnman

const token_starts = tree.tokens.items(.start);

const decl = (try analysis.lookupSymbolGlobal(
builder.arena,
builder.document_store,
const decl = (try builder.analyser.lookupSymbolGlobal(
builder.handle,
identifier_name,
loc.start,
Expand Down Expand Up @@ -134,9 +132,7 @@ fn handleUnusedVariableOrConstant(builder: *Builder, actions: *std.ArrayListUnma
const token_tags = tree.tokens.items(.tag);
const token_starts = tree.tokens.items(.start);

const decl = (try analysis.lookupSymbolGlobal(
builder.arena,
builder.document_store,
const decl = (try builder.analyser.lookupSymbolGlobal(
builder.handle,
identifier_name,
loc.start,
Expand Down
20 changes: 9 additions & 11 deletions src/inlay_hints.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 DocumentStore = @import("DocumentStore.zig");
const analysis = @import("analysis.zig");
const Analyser = @import("analysis.zig");
const types = @import("lsp.zig");
const offsets = @import("offsets.zig");
const tracy = @import("tracy.zig");
Expand All @@ -26,7 +26,7 @@ pub const InlayHint = struct {

const Builder = struct {
arena: std.mem.Allocator,
store: *DocumentStore,
analyser: *Analyser,
config: *const Config,
handle: *const DocumentStore.Handle,
hints: std.ArrayListUnmanaged(InlayHint),
Expand Down Expand Up @@ -64,7 +64,7 @@ const Builder = struct {
/// `call` is the function call
/// `decl_handle` should be a function protototype
/// writes parameter hints into `builder.hints`
fn writeCallHint(builder: *Builder, call: Ast.full.Call, decl_handle: analysis.DeclWithHandle) !void {
fn writeCallHint(builder: *Builder, call: Ast.full.Call, decl_handle: Analyser.DeclWithHandle) !void {
const tracy_zone = tracy.trace(@src());
defer tracy_zone.end();

Expand All @@ -85,7 +85,7 @@ fn writeCallHint(builder: *Builder, call: Ast.full.Call, decl_handle: analysis.D
var i: usize = 0;
var it = fn_proto.iterate(&decl_tree);

if (try analysis.hasSelfParam(builder.arena, builder.store, decl_handle.handle, fn_proto)) {
if (try builder.analyser.hasSelfParam(decl_handle.handle, fn_proto)) {
_ = ast.nextFnParam(&it);
}

Expand Down Expand Up @@ -187,7 +187,7 @@ fn writeCallNodeHint(builder: *Builder, call: Ast.full.Call) !void {
const source_index = offsets.tokenToIndex(tree, main_tokens[call.ast.fn_expr]);
const name = offsets.tokenToSlice(tree, main_tokens[call.ast.fn_expr]);

if (try analysis.lookupSymbolGlobal(builder.arena, builder.store, handle, name, source_index)) |decl_handle| {
if (try builder.analyser.lookupSymbolGlobal(handle, name, source_index)) |decl_handle| {
try writeCallHint(builder, call, decl_handle);
}
},
Expand All @@ -204,13 +204,11 @@ fn writeCallNodeHint(builder: *Builder, call: Ast.full.Call) !void {

// note: we have the ast node, traversing it would probably yield better results
// than trying to re-tokenize and re-parse it
if (try analysis.getFieldAccessType(builder.arena, builder.store, handle, rhs_loc.end, &tokenizer)) |result| {
if (try builder.analyser.getFieldAccessType(handle, rhs_loc.end, &tokenizer)) |result| {
const container_handle = result.unwrapped orelse result.original;
switch (container_handle.type.data) {
.other => |container_handle_node| {
if (try analysis.lookupSymbolContainer(
builder.arena,
builder.store,
if (try builder.analyser.lookupSymbolContainer(
.{ .node = container_handle_node, .handle = container_handle.handle },
tree.tokenSlice(rhsToken),
true,
Expand Down Expand Up @@ -285,7 +283,7 @@ fn writeNodeInlayHint(
pub fn writeRangeInlayHint(
arena: std.mem.Allocator,
config: Config,
store: *DocumentStore,
analyser: *Analyser,
handle: *const DocumentStore.Handle,
loc: offsets.Loc,
hover_kind: types.MarkupKind,
Expand All @@ -295,7 +293,7 @@ pub fn writeRangeInlayHint(

var builder: Builder = .{
.arena = arena,
.store = store,
.analyser = analyser,
.config = &config,
.handle = handle,
.hints = .{},
Expand Down
44 changes: 15 additions & 29 deletions src/references.zig
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
const std = @import("std");
const Ast = std.zig.Ast;
const DocumentStore = @import("DocumentStore.zig");
const analysis = @import("analysis.zig");
const Analyser = @import("analysis.zig");
const types = @import("lsp.zig");
const offsets = @import("offsets.zig");
const log = std.log.scoped(.zls_references);
const ast = @import("ast.zig");

pub fn labelReferences(
allocator: std.mem.Allocator,
decl: analysis.DeclWithHandle,
decl: Analyser.DeclWithHandle,
encoding: offsets.Encoding,
include_decl: bool,
) error{OutOfMemory}!std.ArrayListUnmanaged(types.Location) {
Expand Down Expand Up @@ -57,8 +57,8 @@ const Builder = struct {
allocator: std.mem.Allocator,
locations: std.ArrayListUnmanaged(types.Location) = .{},
/// this is the declaration we are searching for
decl_handle: analysis.DeclWithHandle,
store: *DocumentStore,
decl_handle: Analyser.DeclWithHandle,
analyser: *Analyser,
encoding: offsets.Encoding,

const Context = struct {
Expand Down Expand Up @@ -98,12 +98,10 @@ const Builder = struct {
.identifier,
.test_decl,
=> {
const identifier_token = analysis.getDeclNameToken(tree, node).?;
const identifier_token = Analyser.getDeclNameToken(tree, node).?;
if (token_tags[identifier_token] != .identifier) return;

const child = (try analysis.lookupSymbolGlobal(
builder.allocator,
builder.store,
const child = (try builder.analyser.lookupSymbolGlobal(
handle,
offsets.tokenToSlice(tree, identifier_token),
starts[identifier_token],
Expand All @@ -114,28 +112,16 @@ const Builder = struct {
}
},
.field_access => {
var bound_type_params = analysis.BoundTypeParams{};
defer bound_type_params.deinit(builder.store.allocator);
const left_type = try analysis.resolveFieldAccessLhsType(
builder.allocator,
builder.store,
(try analysis.resolveTypeOfNodeInternal(
builder.allocator,
builder.store,
.{ .node = datas[node].lhs, .handle = handle },
&bound_type_params,
)) orelse return,
&bound_type_params,
const left_type = try builder.analyser.resolveFieldAccessLhsType(
(try builder.analyser.resolveTypeOfNode(.{ .node = datas[node].lhs, .handle = handle })) orelse return,
);

const left_type_node = switch (left_type.type.data) {
.other => |n| n,
else => return,
};

const child = (try analysis.lookupSymbolContainer(
self.builder.allocator,
builder.store,
const child = (try builder.analyser.lookupSymbolContainer(
.{ .node = left_type_node, .handle = left_type.handle },
offsets.tokenToSlice(tree, datas[node].rhs),
!left_type.type.is_type_val,
Expand All @@ -152,8 +138,8 @@ const Builder = struct {

pub fn symbolReferences(
allocator: std.mem.Allocator,
store: *DocumentStore,
decl_handle: analysis.DeclWithHandle,
analyser: *Analyser,
decl_handle: Analyser.DeclWithHandle,
encoding: offsets.Encoding,
/// add `decl_handle` as a references
include_decl: bool,
Expand All @@ -166,7 +152,7 @@ pub fn symbolReferences(

var builder = Builder{
.allocator = allocator,
.store = store,
.analyser = analyser,
.decl_handle = decl_handle,
.encoding = encoding,
};
Expand Down Expand Up @@ -194,7 +180,7 @@ pub fn symbolReferences(
dependencies.deinit(allocator);
}

for (store.handles.values()) |handle| {
for (analyser.store.handles.values()) |handle| {
if (skip_std_references and std.mem.indexOf(u8, handle.uri, "std") != null) {
if (!include_decl or !std.mem.eql(u8, handle.uri, curr_handle.uri))
continue;
Expand All @@ -207,7 +193,7 @@ pub fn symbolReferences(
}
handle_dependencies.deinit(allocator);
}
try store.collectDependencies(allocator, handle.*, &handle_dependencies);
try analyser.store.collectDependencies(allocator, handle.*, &handle_dependencies);

try dependencies.ensureUnusedCapacity(allocator, handle_dependencies.items.len);
for (handle_dependencies.items) |uri| {
Expand All @@ -217,7 +203,7 @@ pub fn symbolReferences(

for (dependencies.keys()) |uri| {
if (std.mem.eql(u8, uri, curr_handle.uri)) continue;
const handle = store.getHandle(uri) orelse continue;
const handle = analyser.store.getHandle(uri) orelse continue;

try builder.collectReferences(handle, 0);
}
Expand Down
Loading