Skip to content

Commit bcdeab5

Browse files
committed
limit symbol references search to a local scope on certain declarations
1 parent 6154e28 commit bcdeab5

File tree

1 file changed

+47
-35
lines changed

1 file changed

+47
-35
lines changed

src/features/references.zig

Lines changed: 47 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -242,48 +242,60 @@ fn symbolReferences(
242242

243243
std.debug.assert(decl_handle.decl != .label); // use `labelReferences` instead
244244

245-
var builder = Builder{
246-
.allocator = allocator,
247-
.analyser = analyser,
248-
.decl_handle = decl_handle,
249-
.encoding = encoding,
250-
};
251-
errdefer builder.deinit();
252-
253-
const curr_handle = decl_handle.handle;
254-
if (include_decl) try builder.add(curr_handle, decl_handle.nameToken());
255-
256-
switch (decl_handle.decl) {
257-
.ast_node => {
258-
try builder.collectReferences(curr_handle, .root);
259-
260-
const source_index = decl_handle.handle.tree.tokenStart(decl_handle.nameToken());
261-
// highlight requests only pertain to the current document, otherwise we can try to narrow things down
262-
const workspace = if (request == .highlight) false else blk: {
263-
const doc_scope = try curr_handle.getDocumentScope();
264-
const scope_index = Analyser.innermostScopeAtIndex(doc_scope, source_index);
265-
break :blk switch (doc_scope.getScopeTag(scope_index)) {
266-
.function, .block => false,
267-
.container, .container_usingnamespace => decl_handle.isPublic(),
268-
.other => true,
269-
};
270-
};
271-
if (workspace) {
272-
try gatherReferences(allocator, analyser, curr_handle, skip_std_references, include_decl, &builder, .get);
273-
}
245+
const doc_scope = try decl_handle.handle.getDocumentScope();
246+
const source_index = decl_handle.handle.tree.tokenStart(decl_handle.nameToken());
247+
const scope_index = Analyser.innermostScopeAtIndexWithTag(doc_scope, source_index, .init(.{
248+
.block = true,
249+
.container = true,
250+
.container_usingnamespace = true,
251+
.function = false,
252+
.other = false,
253+
})).unwrap().?;
254+
const scope_node = doc_scope.getScopeAstNode(scope_index).?;
255+
256+
// If `local_node != null`, references to the declaration can only be
257+
// found inside of the given ast node.
258+
const local_node: ?Ast.Node.Index = switch (decl_handle.decl) {
259+
.ast_node => switch (doc_scope.getScopeTag(scope_index)) {
260+
.block => scope_node,
261+
.container, .container_usingnamespace => null,
262+
.function, .other => unreachable,
274263
},
275264
.optional_payload,
276265
.error_union_payload,
277266
.error_union_error,
278267
.for_loop_payload,
279268
.assign_destructure,
280-
.switch_payload,
281-
=> {
282-
try builder.collectReferences(curr_handle, .root);
283-
},
284-
.function_parameter => |payload| try builder.collectReferences(curr_handle, payload.func),
269+
=> scope_node,
270+
.switch_payload => |payload| payload.node,
271+
.function_parameter => |payload| payload.func,
285272
.label => unreachable, // handled separately by labelReferences
286-
.error_token => {},
273+
.error_token => return .empty,
274+
};
275+
276+
var builder: Builder = .{
277+
.allocator = allocator,
278+
.analyser = analyser,
279+
.decl_handle = decl_handle,
280+
.encoding = encoding,
281+
};
282+
errdefer builder.deinit();
283+
284+
if (include_decl) try builder.add(decl_handle.handle, decl_handle.nameToken());
285+
286+
try builder.collectReferences(decl_handle.handle, local_node orelse .root);
287+
288+
const workspace = local_node == null and request != .highlight and decl_handle.isPublic();
289+
if (workspace) {
290+
try gatherReferences(
291+
allocator,
292+
analyser,
293+
decl_handle.handle,
294+
skip_std_references,
295+
include_decl,
296+
&builder,
297+
.get,
298+
);
287299
}
288300

289301
return builder.locations;

0 commit comments

Comments
 (0)