Skip to content

Commit 793b7ee

Browse files
committed
do not resolve aliases when renaming symbol
closes #3184
1 parent b97d5ff commit 793b7ee

2 files changed

Lines changed: 134 additions & 19 deletions

File tree

src/features/references.zig

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ const Builder = struct {
6868
local_only_decl: bool,
6969
/// Whether the `target_symbol` has been added
7070
did_add_target_symbol: bool = false,
71+
resolve_aliases: bool,
7172
analyser: *Analyser,
7273
encoding: offsets.Encoding,
7374

@@ -236,7 +237,9 @@ const Builder = struct {
236237
else => return,
237238
};
238239

239-
candidate = try builder.analyser.resolveVarDeclAlias(candidate) orelse candidate;
240+
if (builder.resolve_aliases) {
241+
candidate = try builder.analyser.resolveVarDeclAlias(candidate) orelse candidate;
242+
}
240243

241244
if (builder.target_symbol.eql(candidate)) {
242245
try builder.add(handle, name_token);
@@ -247,17 +250,24 @@ const Builder = struct {
247250
fn symbolReferences(
248251
analyser: *Analyser,
249252
request: GeneralReferencesRequest,
250-
target_symbol: Analyser.DeclWithHandle,
253+
root_symbol: Analyser.DeclWithHandle,
251254
encoding: offsets.Encoding,
252-
/// add `target_symbol` as a references
255+
/// `types.reference.Context.includeDeclaration`
253256
include_decl: bool,
254257
/// The file on which the request was initiated.
255258
current_handle: *DocumentStore.Handle,
256259
) Analyser.Error!std.ArrayList(types.Location) {
257260
const tracy_zone = tracy.trace(@src());
258261
defer tracy_zone.end();
259262

260-
std.debug.assert(target_symbol.decl != .label); // use `labelReferences` instead
263+
std.debug.assert(root_symbol.decl != .label); // use `labelReferences` instead
264+
265+
const dealiased_symbol = try analyser.resolveVarDeclAlias(root_symbol) orelse root_symbol;
266+
267+
const target_symbol, const resolve_aliases = switch (request) {
268+
.highlight, .rename => .{ root_symbol, dealiased_symbol.eql(root_symbol) },
269+
.references => .{ dealiased_symbol, true },
270+
};
261271

262272
const doc_scope = try target_symbol.handle.getDocumentScope();
263273
const source_index = target_symbol.handle.tree.tokenStart(target_symbol.nameToken());
@@ -295,6 +305,7 @@ fn symbolReferences(
295305
.analyser = analyser,
296306
.target_symbol = target_symbol,
297307
.local_only_decl = local_node != null,
308+
.resolve_aliases = resolve_aliases,
298309
.encoding = encoding,
299310
};
300311

@@ -716,7 +727,7 @@ pub fn referencesHandler(server: *Server, arena: std.mem.Allocator, request: Gen
716727
const name_loc = offsets.identifierLocFromIndex(&handle.tree, source_index) orelse return null;
717728
const name = offsets.locToSlice(handle.tree.source, name_loc);
718729

719-
var target_decl = switch (pos_context) {
730+
const target_decl = switch (pos_context) {
720731
.var_access, .test_doctest_name => try analyser.lookupSymbolGlobal(handle, name, source_index),
721732
.field_access => |loc| z: {
722733
const held_loc = offsets.locMerge(loc, name_loc);
@@ -736,8 +747,6 @@ pub fn referencesHandler(server: *Server, arena: std.mem.Allocator, request: Gen
736747
else => null,
737748
} orelse return null;
738749

739-
target_decl = try analyser.resolveVarDeclAlias(target_decl) orelse target_decl;
740-
741750
break :locs switch (target_decl.decl) {
742751
.label => |payload| try labelReferences(
743752
arena,

tests/lsp_features/references.zig

Lines changed: 118 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -301,21 +301,113 @@ test "switch case capture - union tag" {
301301
);
302302
}
303303

304+
test "alias with same name - cursor on declaration" {
305+
try testReferences(&.{
306+
\\const S = struct {
307+
\\ fn <loc>foo<cursor></loc>() void {}
308+
\\};
309+
\\comptime {
310+
\\ const <loc>foo</loc> = S.<loc>foo</loc>;
311+
\\ <loc>foo</loc>();
312+
\\}
313+
}, .{ .format = .asymmetric, .request_kind = .references });
314+
try testReferences(&.{
315+
\\const S = struct {
316+
\\ fn <loc>foo<cursor></loc>() void {}
317+
\\};
318+
\\comptime {
319+
\\ const <loc>foo</loc> = S.<loc>foo</loc>;
320+
\\ <loc>foo</loc>();
321+
\\}
322+
}, .{ .format = .asymmetric, .request_kind = .rename });
323+
}
324+
325+
test "alias with same name - cursor on alias" {
326+
try testReferences(&.{
327+
\\const S = struct {
328+
\\ fn <loc>foo</loc>() void {}
329+
\\};
330+
\\comptime {
331+
\\ const <loc>foo</loc> = S.<loc>foo</loc>;
332+
\\ <loc>foo<cursor></loc>();
333+
\\}
334+
\\comptime {
335+
\\ const <loc>foo</loc> = S.<loc>foo</loc>;
336+
\\ <loc>foo</loc>();
337+
\\}
338+
}, .{ .format = .asymmetric, .request_kind = .references });
339+
try testReferences(&.{
340+
\\const S = struct {
341+
\\ fn foo() void {}
342+
\\};
343+
\\comptime {
344+
\\ const <loc>foo</loc> = S.foo;
345+
\\ <loc>foo<cursor></loc>();
346+
\\}
347+
\\comptime {
348+
\\ const foo = S.foo;
349+
\\ foo();
350+
\\}
351+
}, .{ .format = .asymmetric, .request_kind = .rename });
352+
}
353+
354+
test "alias with different name - cursor on declaration" {
355+
// No references on renamed symbols is mainly an optimization rather than intended behaviour.
356+
try testReferences(&.{
357+
\\const S = struct {
358+
\\ fn <loc>foo<cursor></loc>() void {}
359+
\\};
360+
\\comptime {
361+
\\ const bar = S.<loc>foo</loc>;
362+
\\ bar();
363+
\\}
364+
}, .{ .format = .asymmetric, .request_kind = .references });
365+
try testReferences(&.{
366+
\\const S = struct {
367+
\\ fn <loc>foo<cursor></loc>() void {}
368+
\\};
369+
\\comptime {
370+
\\ const bar = S.<loc>foo</loc>;
371+
\\ bar();
372+
\\}
373+
}, .{ .format = .asymmetric, .request_kind = .rename });
374+
}
375+
376+
test "alias with different name - cursor on alias" {
377+
// No references on renamed symbols is mainly an optimization rather than intended behaviour.
378+
try testReferences(&.{
379+
\\const S = struct {
380+
\\ fn <loc>foo</loc>() void {}
381+
\\};
382+
\\comptime {
383+
\\ const bar = S.<loc>foo</loc>;
384+
\\ bar<cursor>();
385+
\\}
386+
}, .{ .format = .asymmetric, .request_kind = .references });
387+
try testReferences(&.{
388+
\\const S = struct {
389+
\\ fn foo() void {}
390+
\\};
391+
\\comptime {
392+
\\ const <loc>bar</loc> = S.foo;
393+
\\ <loc>bar<cursor></loc>();
394+
\\}
395+
}, .{ .format = .asymmetric, .request_kind = .rename });
396+
}
397+
304398
test "cross-file reference" {
305399
try testReferences(&.{
306400
// Untitled-0.zig
307-
\\pub const <0> = struct {};
401+
\\pub const <loc>Foo<cursor></loc> = struct {};
308402
,
309403
// Untitled-1.zig
310404
\\const file = @import("Untitled-0.zig");
311-
\\const <0> = file.<0>;
312-
\\const renamed = file.<0>;
405+
\\const <loc>Foo</loc> = file.<loc>Foo</loc>;
313406
\\comptime {
314-
\\ _ = <0>;
315-
\\ _ = renamed;
407+
\\ _ = <loc>Foo</loc>;
316408
\\}
317409
,
318-
}, .{ .format = .symmetric });
410+
}, .{ .format = .asymmetric });
319411
}
320412

321413
test "cross-file - transitive import" {
@@ -336,18 +428,32 @@ test "cross-file - transitive import" {
336428
test "cross-file - alias" {
337429
try testReferences(&.{
338430
// Untitled-0.zig
339-
\\pub const <0> = struct {
340-
\\ fn foo(_: <0>) void {}
341-
\\ var bar: <0> = undefined;
431+
\\pub const <loc>Foo<cursor></loc> = struct {
432+
\\ fn foo(_: <loc>Foo</loc>) void {}
433+
\\ var bar: <loc>Foo</loc> = undefined;
342434
\\};
343435
,
344436
// Untitled-1.zig
345-
\\const <0> = @import("Untitled-0.zig").<0>;
437+
\\const <loc>Foo</loc> = @import("Untitled-0.zig").<loc>Foo</loc>;
346438
\\comptime {
347-
\\ _ = <0>;
439+
\\ _ = <loc>Foo</loc>;
348440
\\}
349441
,
350-
}, .{ .format = .symmetric });
442+
}, .{ .format = .asymmetric });
443+
try testReferences(&.{
444+
// Untitled-0.zig
445+
\\pub const <loc>Foo<cursor></loc> = struct {};
446+
,
447+
// Untitled-1.zig
448+
\\const file = @import("Untitled-0.zig");
449+
\\const <loc>Foo</loc> = file.<loc>Foo</loc>;
450+
\\const renamed = file.<loc>Foo</loc>;
451+
\\comptime {
452+
\\ _ = <loc>Foo</loc>;
453+
\\ _ = renamed;
454+
\\}
455+
,
456+
}, .{ .format = .asymmetric });
351457
}
352458

353459
test "matching control flow - unlabeled loop" {

0 commit comments

Comments
 (0)