Skip to content

Commit 7a7576c

Browse files
authored
fix symbol references (#712)
* fix symbol references * skip references for inline assembly
1 parent 51a7ae2 commit 7a7576c

File tree

2 files changed

+66
-63
lines changed

2 files changed

+66
-63
lines changed

src/references.zig

+66-61
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,11 @@ fn symbolReferencesInternal(
8282
builder: *Builder,
8383
node: Ast.Node.Index,
8484
handle: *const DocumentStore.Handle,
85+
is_root: bool,
8586
) error{OutOfMemory}!void {
8687
const tree = handle.tree;
8788

88-
if (node == 0 or node > tree.nodes.len) return;
89+
if (!is_root and node == 0 or node > tree.nodes.len) return;
8990

9091
const node_tags = tree.nodes.items(.tag);
9192
const datas = tree.nodes.items(.data);
@@ -102,7 +103,7 @@ fn symbolReferencesInternal(
102103
const statements = ast.blockStatements(tree, node, &buffer).?;
103104

104105
for (statements) |stmt|
105-
try symbolReferencesInternal(builder, stmt, handle);
106+
try symbolReferencesInternal(builder, stmt, handle, false);
106107
},
107108
.container_decl,
108109
.container_decl_trailing,
@@ -121,24 +122,24 @@ fn symbolReferencesInternal(
121122
=> {
122123
var buf: [2]Ast.Node.Index = undefined;
123124
for (ast.declMembers(tree, node, &buf)) |member|
124-
try symbolReferencesInternal(builder, member, handle);
125+
try symbolReferencesInternal(builder, member, handle, false);
125126
},
126127
.global_var_decl,
127128
.local_var_decl,
128129
.simple_var_decl,
129130
.aligned_var_decl,
130131
=> {
131132
const var_decl = ast.varDecl(tree, node).?;
132-
try symbolReferencesInternal(builder, var_decl.ast.type_node, handle);
133-
try symbolReferencesInternal(builder, var_decl.ast.init_node, handle);
133+
try symbolReferencesInternal(builder, var_decl.ast.type_node, handle, false);
134+
try symbolReferencesInternal(builder, var_decl.ast.init_node, handle, false);
134135
},
135136
.container_field,
136137
.container_field_align,
137138
.container_field_init,
138139
=> {
139140
const field = ast.containerField(tree, node).?;
140-
try symbolReferencesInternal(builder, field.ast.type_expr, handle);
141-
try symbolReferencesInternal(builder, field.ast.value_expr, handle);
141+
try symbolReferencesInternal(builder, field.ast.type_expr, handle, false);
142+
try symbolReferencesInternal(builder, field.ast.value_expr, handle, false);
142143
},
143144
.identifier => {
144145
const child = (try analysis.lookupSymbolGlobal(builder.store, builder.arena, handle, tree.getNodeSource(node), starts[main_tokens[node]])) orelse return;
@@ -154,43 +155,43 @@ fn symbolReferencesInternal(
154155
const fn_proto = ast.fnProto(tree, node, &buf).?;
155156
var it = fn_proto.iterate(&tree);
156157
while (ast.nextFnParam(&it)) |param| {
157-
try symbolReferencesInternal(builder, param.type_expr, handle);
158+
try symbolReferencesInternal(builder, param.type_expr, handle, false);
158159
}
159160

160-
try symbolReferencesInternal(builder, fn_proto.ast.return_type, handle);
161-
try symbolReferencesInternal(builder, fn_proto.ast.align_expr, handle);
162-
try symbolReferencesInternal(builder, fn_proto.ast.section_expr, handle);
163-
try symbolReferencesInternal(builder, fn_proto.ast.callconv_expr, handle);
161+
try symbolReferencesInternal(builder, fn_proto.ast.return_type, handle, false);
162+
try symbolReferencesInternal(builder, fn_proto.ast.align_expr, handle, false);
163+
try symbolReferencesInternal(builder, fn_proto.ast.section_expr, handle, false);
164+
try symbolReferencesInternal(builder, fn_proto.ast.callconv_expr, handle, false);
164165
if (node_tags[node] == .fn_decl) {
165-
try symbolReferencesInternal(builder, datas[node].rhs, handle);
166+
try symbolReferencesInternal(builder, datas[node].rhs, handle, false);
166167
}
167168
},
168169
.@"switch",
169170
.switch_comma,
170171
=> {
171172
// TODO When renaming a union(enum) field, also rename switch items that refer to it.
172-
try symbolReferencesInternal(builder, datas[node].lhs, handle);
173+
try symbolReferencesInternal(builder, datas[node].lhs, handle, false);
173174
const extra = tree.extraData(datas[node].rhs, Ast.Node.SubRange);
174175
const cases = tree.extra_data[extra.start..extra.end];
175176
for (cases) |case| {
176-
try symbolReferencesInternal(builder, case, handle);
177+
try symbolReferencesInternal(builder, case, handle, false);
177178
}
178179
},
179180
.switch_case_one,
180181
.switch_case_inline_one,
181182
=> {
182183
const case_one = tree.switchCaseOne(node);
183-
try symbolReferencesInternal(builder, case_one.ast.target_expr, handle);
184+
try symbolReferencesInternal(builder, case_one.ast.target_expr, handle, false);
184185
for (case_one.ast.values) |val|
185-
try symbolReferencesInternal(builder, val, handle);
186+
try symbolReferencesInternal(builder, val, handle, false);
186187
},
187188
.switch_case,
188189
.switch_case_inline,
189190
=> {
190191
const case = tree.switchCase(node);
191-
try symbolReferencesInternal(builder, case.ast.target_expr, handle);
192+
try symbolReferencesInternal(builder, case.ast.target_expr, handle, false);
192193
for (case.ast.values) |val|
193-
try symbolReferencesInternal(builder, val, handle);
194+
try symbolReferencesInternal(builder, val, handle, false);
194195
},
195196
.@"while",
196197
.while_simple,
@@ -199,17 +200,17 @@ fn symbolReferencesInternal(
199200
.@"for",
200201
=> {
201202
const loop = ast.whileAst(tree, node).?;
202-
try symbolReferencesInternal(builder, loop.ast.cond_expr, handle);
203-
try symbolReferencesInternal(builder, loop.ast.then_expr, handle);
204-
try symbolReferencesInternal(builder, loop.ast.else_expr, handle);
203+
try symbolReferencesInternal(builder, loop.ast.cond_expr, handle, false);
204+
try symbolReferencesInternal(builder, loop.ast.then_expr, handle, false);
205+
try symbolReferencesInternal(builder, loop.ast.else_expr, handle, false);
205206
},
206207
.@"if",
207208
.if_simple,
208209
=> {
209210
const if_node = ast.ifFull(tree, node);
210-
try symbolReferencesInternal(builder, if_node.ast.cond_expr, handle);
211-
try symbolReferencesInternal(builder, if_node.ast.then_expr, handle);
212-
try symbolReferencesInternal(builder, if_node.ast.else_expr, handle);
211+
try symbolReferencesInternal(builder, if_node.ast.cond_expr, handle, false);
212+
try symbolReferencesInternal(builder, if_node.ast.then_expr, handle, false);
213+
try symbolReferencesInternal(builder, if_node.ast.else_expr, handle, false);
213214
},
214215
.ptr_type,
215216
.ptr_type_aligned,
@@ -219,15 +220,15 @@ fn symbolReferencesInternal(
219220
const ptr_type = ast.ptrType(tree, node).?;
220221

221222
if (ptr_type.ast.align_node != 0) {
222-
try symbolReferencesInternal(builder, ptr_type.ast.align_node, handle);
223+
try symbolReferencesInternal(builder, ptr_type.ast.align_node, handle, false);
223224
if (node_tags[node] == .ptr_type_bit_range) {
224-
try symbolReferencesInternal(builder, ptr_type.ast.bit_range_start, handle);
225-
try symbolReferencesInternal(builder, ptr_type.ast.bit_range_end, handle);
225+
try symbolReferencesInternal(builder, ptr_type.ast.bit_range_start, handle, false);
226+
try symbolReferencesInternal(builder, ptr_type.ast.bit_range_end, handle, false);
226227
}
227228
}
228229

229-
try symbolReferencesInternal(builder, ptr_type.ast.sentinel, handle);
230-
try symbolReferencesInternal(builder, ptr_type.ast.child_type, handle);
230+
try symbolReferencesInternal(builder, ptr_type.ast.sentinel, handle, false);
231+
try symbolReferencesInternal(builder, ptr_type.ast.child_type, handle, false);
231232
},
232233
.array_init,
233234
.array_init_comma,
@@ -246,9 +247,9 @@ fn symbolReferencesInternal(
246247
.array_init_dot_two, .array_init_dot_two_comma => tree.arrayInitDotTwo(&buf, node),
247248
else => unreachable,
248249
};
249-
try symbolReferencesInternal(builder, array_init.ast.type_expr, handle);
250+
try symbolReferencesInternal(builder, array_init.ast.type_expr, handle, false);
250251
for (array_init.ast.elements) |e|
251-
try symbolReferencesInternal(builder, e, handle);
252+
try symbolReferencesInternal(builder, e, handle, false);
252253
},
253254
.struct_init,
254255
.struct_init_comma,
@@ -267,9 +268,9 @@ fn symbolReferencesInternal(
267268
.struct_init_dot_two, .struct_init_dot_two_comma => tree.structInitDotTwo(&buf, node),
268269
else => unreachable,
269270
};
270-
try symbolReferencesInternal(builder, struct_init.ast.type_expr, handle);
271+
try symbolReferencesInternal(builder, struct_init.ast.type_expr, handle, false);
271272
for (struct_init.ast.fields) |field|
272-
try symbolReferencesInternal(builder, field, handle);
273+
try symbolReferencesInternal(builder, field, handle, false);
273274
},
274275
.call,
275276
.call_comma,
@@ -283,10 +284,10 @@ fn symbolReferencesInternal(
283284
var buf: [1]Ast.Node.Index = undefined;
284285
const call = ast.callFull(tree, node, &buf).?;
285286

286-
try symbolReferencesInternal(builder, call.ast.fn_expr, handle);
287+
try symbolReferencesInternal(builder, call.ast.fn_expr, handle, false);
287288

288289
for (call.ast.params) |param| {
289-
try symbolReferencesInternal(builder, param, handle);
290+
try symbolReferencesInternal(builder, param, handle, false);
290291
}
291292
},
292293
.slice,
@@ -300,10 +301,10 @@ fn symbolReferencesInternal(
300301
else => unreachable,
301302
};
302303

303-
try symbolReferencesInternal(builder, slice.ast.sliced, handle);
304-
try symbolReferencesInternal(builder, slice.ast.start, handle);
305-
try symbolReferencesInternal(builder, slice.ast.end, handle);
306-
try symbolReferencesInternal(builder, slice.ast.sentinel, handle);
304+
try symbolReferencesInternal(builder, slice.ast.sliced, handle, false);
305+
try symbolReferencesInternal(builder, slice.ast.start, handle, false);
306+
try symbolReferencesInternal(builder, slice.ast.end, handle, false);
307+
try symbolReferencesInternal(builder, slice.ast.sentinel, handle, false);
307308
},
308309
.builtin_call,
309310
.builtin_call_comma,
@@ -314,25 +315,26 @@ fn symbolReferencesInternal(
314315
const params = ast.builtinCallParams(tree, node, &buffer).?;
315316

316317
for (params) |param|
317-
try symbolReferencesInternal(builder, param, handle);
318+
try symbolReferencesInternal(builder, param, handle, false);
318319
},
319320
.@"asm",
320321
.asm_simple,
321322
=> |tag| {
322323
const full_asm: Ast.full.Asm = if (tag == .@"asm") tree.asmFull(node) else tree.asmSimple(node);
323324
if (full_asm.ast.items.len == 0)
324-
try symbolReferencesInternal(builder, full_asm.ast.template, handle);
325+
try symbolReferencesInternal(builder, full_asm.ast.template, handle, false);
325326

326327
for (full_asm.inputs) |input|
327-
try symbolReferencesInternal(builder, input, handle);
328+
try symbolReferencesInternal(builder, input, handle, false);
328329

329330
for (full_asm.outputs) |output|
330-
try symbolReferencesInternal(builder, output, handle);
331+
try symbolReferencesInternal(builder, output, handle, false);
331332
},
332-
.asm_output => unreachable,
333-
.asm_input => unreachable,
333+
// TODO implement references for asm
334+
.asm_output => {},
335+
.asm_input => {},
334336
.field_access => {
335-
try symbolReferencesInternal(builder, datas[node].lhs, handle);
337+
try symbolReferencesInternal(builder, datas[node].lhs, handle, false);
336338

337339
const rhs_str = ast.tokenSlice(tree, datas[node].rhs) catch return;
338340
var bound_type_params = analysis.BoundTypeParams{};
@@ -380,12 +382,12 @@ fn symbolReferencesInternal(
380382
.grouped_expression,
381383
.@"comptime",
382384
.@"nosuspend",
383-
=> try symbolReferencesInternal(builder, datas[node].lhs, handle),
385+
=> try symbolReferencesInternal(builder, datas[node].lhs, handle, false),
384386
.test_decl,
385387
.@"errdefer",
386388
.@"defer",
387389
.anyframe_type,
388-
=> try symbolReferencesInternal(builder, datas[node].rhs, handle),
390+
=> try symbolReferencesInternal(builder, datas[node].rhs, handle, false),
389391
.equal_equal,
390392
.bang_equal,
391393
.less_than,
@@ -440,8 +442,8 @@ fn symbolReferencesInternal(
440442
.switch_range,
441443
.error_union,
442444
=> {
443-
try symbolReferencesInternal(builder, datas[node].lhs, handle);
444-
try symbolReferencesInternal(builder, datas[node].rhs, handle);
445+
try symbolReferencesInternal(builder, datas[node].lhs, handle, false);
446+
try symbolReferencesInternal(builder, datas[node].rhs, handle, false);
445447
},
446448
.anyframe_literal,
447449
.char_literal,
@@ -472,15 +474,9 @@ pub fn symbolReferences(
472474
if (include_decl) try builder.add(curr_handle, decl_handle.nameToken());
473475

474476
switch (decl_handle.decl.*) {
475-
.pointer_payload,
476-
.switch_payload,
477-
.array_payload,
478-
.array_index,
479-
.ast_node,
480-
=> {
481-
try symbolReferencesInternal(&builder, 0, curr_handle);
477+
.ast_node => {
478+
try symbolReferencesInternal(&builder, 0, curr_handle, true);
482479

483-
if (decl_handle.decl.* != .ast_node) return builder.locations;
484480
if (!workspace) return builder.locations;
485481

486482
for (store.handles.values()) |handle| {
@@ -494,10 +490,19 @@ pub fn symbolReferences(
494490

495491
for (dependencies.items) |uri| {
496492
const hdl = store.getHandle(uri) orelse continue;
497-
try symbolReferencesInternal(&builder, 0, hdl);
493+
try symbolReferencesInternal(&builder, 0, hdl, true);
498494
}
499495
}
500496
},
497+
.pointer_payload,
498+
.switch_payload,
499+
.array_payload,
500+
.array_index,
501+
=> {
502+
try symbolReferencesInternal(&builder, 0, curr_handle, true);
503+
504+
return builder.locations;
505+
},
501506
.param_payload => |pay| blk: {
502507
// Rename the param tok.
503508
const param = pay.param;
@@ -514,7 +519,7 @@ pub fn symbolReferences(
514519
if (!std.meta.eql(candidate, param)) continue;
515520

516521
if (curr_handle.tree.nodes.items(.tag)[proto] != .fn_decl) break :blk;
517-
try symbolReferencesInternal(&builder, curr_handle.tree.nodes.items(.data)[proto].rhs, curr_handle);
522+
try symbolReferencesInternal(&builder, curr_handle.tree.nodes.items(.data)[proto].rhs, curr_handle, false);
518523
break :blk;
519524
}
520525
}

tests/lsp_features/references.zig

-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ const allocator: std.mem.Allocator = std.testing.allocator;
1616
const skip_references_tests = true;
1717

1818
test "references" {
19-
if (skip_references_tests) return error.SkipZigTest;
2019
try testReferences(
2120
\\const <0> = 0;
2221
\\const foo = <0>;
@@ -48,7 +47,6 @@ test "references" {
4847
}
4948

5049
test "references - global scope" {
51-
if (skip_references_tests) return error.SkipZigTest;
5250
try testReferences(
5351
\\const foo = <0>;
5452
\\const <0> = 0;

0 commit comments

Comments
 (0)