Merge branch 'master' of github.com:zigtools/zls

This commit is contained in:
Alexandros Naskos 2021-04-05 11:59:05 +03:00
commit d397f1119e
No known key found for this signature in database
GPG Key ID: 02BF2E72B0EA32D2

View File

@ -2292,11 +2292,16 @@ fn resolveUse(
uses: []const *const ast.Node.Index, uses: []const *const ast.Node.Index,
symbol: []const u8, symbol: []const u8,
handle: *DocumentStore.Handle, handle: *DocumentStore.Handle,
use_trail: *std.ArrayList(*const ast.Node.Index),
) error{OutOfMemory}!?DeclWithHandle { ) error{OutOfMemory}!?DeclWithHandle {
const state = struct {
var using_trail = std.ArrayListUnmanaged(*const ast.Node.Index){};
};
for (uses) |use| { for (uses) |use| {
if (std.mem.indexOfScalar(*const ast.Node.Index, use_trail.items, use) != null) continue; if (std.mem.indexOfScalar(*const ast.Node.Index, state.using_trail.items, use) != null) continue;
try use_trail.append(use); // We use the child_allocator here because the ArrayList expects its
// allocated memory to persist while it is empty.
try state.using_trail.append(arena.child_allocator, use);
defer _ = state.using_trail.pop();
const use_expr = (try resolveTypeOfNode( const use_expr = (try resolveTypeOfNode(
store, store,
@ -2308,13 +2313,12 @@ fn resolveUse(
.other => |n| n, .other => |n| n,
else => continue, else => continue,
}; };
if (try lookupSymbolContainerInternal( if (try lookupSymbolContainer(
store, store,
arena, arena,
.{ .node = use_expr_node, .handle = use_expr.handle }, .{ .node = use_expr_node, .handle = use_expr.handle },
symbol, symbol,
false, false,
use_trail,
)) |candidate| { )) |candidate| {
if (candidate.handle != handle and !candidate.isPublic()) { if (candidate.handle != handle and !candidate.isPublic()) {
continue; continue;
@ -2348,40 +2352,6 @@ pub fn lookupLabel(
return null; return null;
} }
fn lookupSymbolGlobalInternal(
store: *DocumentStore,
arena: *std.heap.ArenaAllocator,
handle: *DocumentStore.Handle,
symbol: []const u8,
source_index: usize,
use_trail: *std.ArrayList(*const ast.Node.Index),
) error{OutOfMemory}!?DeclWithHandle {
const innermost_scope_idx = innermostBlockScopeIndex(handle.*, source_index);
var curr = innermost_scope_idx;
while (curr >= 0) : (curr -= 1) {
const scope = &handle.document_scope.scopes[curr];
if (source_index >= scope.range.start and source_index <= scope.range.end) {
if (scope.decls.getEntry(symbol)) |candidate| {
switch (candidate.value) {
.ast_node => |node| {
if (handle.tree.nodes.items(.tag)[node].isContainerField()) continue;
},
.label_decl => continue,
else => {},
}
return DeclWithHandle{
.decl = &candidate.value,
.handle = handle,
};
}
if (try resolveUse(store, arena, scope.uses, symbol, handle, use_trail)) |result| return result;
}
if (curr == 0) break;
}
return null;
}
pub fn lookupSymbolGlobal( pub fn lookupSymbolGlobal(
store: *DocumentStore, store: *DocumentStore,
arena: *std.heap.ArenaAllocator, arena: *std.heap.ArenaAllocator,
@ -2389,11 +2359,33 @@ pub fn lookupSymbolGlobal(
symbol: []const u8, symbol: []const u8,
source_index: usize, source_index: usize,
) error{OutOfMemory}!?DeclWithHandle { ) error{OutOfMemory}!?DeclWithHandle {
var use_trail = std.ArrayList(*const ast.Node.Index).init(&arena.allocator); const innermost_scope_idx = innermostBlockScopeIndex(handle.*, source_index);
return try lookupSymbolGlobalInternal(store, arena, handle, symbol, source_index, &use_trail);
var curr = innermost_scope_idx;
while (curr >= 0) : (curr -= 1) {
const scope = &handle.document_scope.scopes[curr];
if (source_index >= scope.range.start and source_index <= scope.range.end) blk: {
if (scope.decls.getEntry(symbol)) |candidate| {
switch (candidate.value) {
.ast_node => |node| {
if (handle.tree.nodes.items(.tag)[node].isContainerField()) break :blk;
},
.label_decl => break :blk,
else => {},
}
return DeclWithHandle{
.decl = &candidate.value,
.handle = handle,
};
}
if (try resolveUse(store, arena, scope.uses, symbol, handle)) |result| return result;
}
if (curr == 0) break;
}
return null;
} }
fn lookupSymbolContainerInternal( pub fn lookupSymbolContainer(
store: *DocumentStore, store: *DocumentStore,
arena: *std.heap.ArenaAllocator, arena: *std.heap.ArenaAllocator,
container_handle: NodeWithHandle, container_handle: NodeWithHandle,
@ -2401,7 +2393,6 @@ fn lookupSymbolContainerInternal(
/// If true, we are looking up the symbol like we are accessing through a field access /// If true, we are looking up the symbol like we are accessing through a field access
/// of an instance of the type, otherwise as a field access of the type value itself. /// of an instance of the type, otherwise as a field access of the type value itself.
instance_access: bool, instance_access: bool,
use_trail: *std.ArrayList(*const ast.Node.Index),
) error{OutOfMemory}!?DeclWithHandle { ) error{OutOfMemory}!?DeclWithHandle {
const container = container_handle.node; const container = container_handle.node;
const handle = container_handle.handle; const handle = container_handle.handle;
@ -2427,26 +2418,13 @@ fn lookupSymbolContainerInternal(
return DeclWithHandle{ .decl = &candidate.value, .handle = handle }; return DeclWithHandle{ .decl = &candidate.value, .handle = handle };
} }
if (try resolveUse(store, arena, container_scope.uses, symbol, handle, use_trail)) |result| return result; if (try resolveUse(store, arena, container_scope.uses, symbol, handle)) |result| return result;
return null; return null;
} }
return null; return null;
} }
pub fn lookupSymbolContainer(
store: *DocumentStore,
arena: *std.heap.ArenaAllocator,
container_handle: NodeWithHandle,
symbol: []const u8,
/// If true, we are looking up the symbol like we are accessing through a field access
/// of an instance of the type, otherwise as a field access of the type value itself.
instance_access: bool,
) error{OutOfMemory}!?DeclWithHandle {
var use_trail = std.ArrayList(*const ast.Node.Index).init(&arena.allocator);
return try lookupSymbolContainerInternal(store, arena, container_handle, symbol, instance_access, &use_trail);
}
fn eqlCompletionItem(a: types.CompletionItem, b: types.CompletionItem) bool { fn eqlCompletionItem(a: types.CompletionItem, b: types.CompletionItem) bool {
return std.mem.eql(u8, a.label, b.label); return std.mem.eql(u8, a.label, b.label);
} }