fix symbol references (#712)
* fix symbol references * skip references for inline assembly
This commit is contained in:
parent
51a7ae2274
commit
7a7576c06d
@ -82,10 +82,11 @@ fn symbolReferencesInternal(
|
|||||||
builder: *Builder,
|
builder: *Builder,
|
||||||
node: Ast.Node.Index,
|
node: Ast.Node.Index,
|
||||||
handle: *const DocumentStore.Handle,
|
handle: *const DocumentStore.Handle,
|
||||||
|
is_root: bool,
|
||||||
) error{OutOfMemory}!void {
|
) error{OutOfMemory}!void {
|
||||||
const tree = handle.tree;
|
const tree = handle.tree;
|
||||||
|
|
||||||
if (node == 0 or node > tree.nodes.len) return;
|
if (!is_root and node == 0 or node > tree.nodes.len) return;
|
||||||
|
|
||||||
const node_tags = tree.nodes.items(.tag);
|
const node_tags = tree.nodes.items(.tag);
|
||||||
const datas = tree.nodes.items(.data);
|
const datas = tree.nodes.items(.data);
|
||||||
@ -102,7 +103,7 @@ fn symbolReferencesInternal(
|
|||||||
const statements = ast.blockStatements(tree, node, &buffer).?;
|
const statements = ast.blockStatements(tree, node, &buffer).?;
|
||||||
|
|
||||||
for (statements) |stmt|
|
for (statements) |stmt|
|
||||||
try symbolReferencesInternal(builder, stmt, handle);
|
try symbolReferencesInternal(builder, stmt, handle, false);
|
||||||
},
|
},
|
||||||
.container_decl,
|
.container_decl,
|
||||||
.container_decl_trailing,
|
.container_decl_trailing,
|
||||||
@ -121,7 +122,7 @@ fn symbolReferencesInternal(
|
|||||||
=> {
|
=> {
|
||||||
var buf: [2]Ast.Node.Index = undefined;
|
var buf: [2]Ast.Node.Index = undefined;
|
||||||
for (ast.declMembers(tree, node, &buf)) |member|
|
for (ast.declMembers(tree, node, &buf)) |member|
|
||||||
try symbolReferencesInternal(builder, member, handle);
|
try symbolReferencesInternal(builder, member, handle, false);
|
||||||
},
|
},
|
||||||
.global_var_decl,
|
.global_var_decl,
|
||||||
.local_var_decl,
|
.local_var_decl,
|
||||||
@ -129,16 +130,16 @@ fn symbolReferencesInternal(
|
|||||||
.aligned_var_decl,
|
.aligned_var_decl,
|
||||||
=> {
|
=> {
|
||||||
const var_decl = ast.varDecl(tree, node).?;
|
const var_decl = ast.varDecl(tree, node).?;
|
||||||
try symbolReferencesInternal(builder, var_decl.ast.type_node, handle);
|
try symbolReferencesInternal(builder, var_decl.ast.type_node, handle, false);
|
||||||
try symbolReferencesInternal(builder, var_decl.ast.init_node, handle);
|
try symbolReferencesInternal(builder, var_decl.ast.init_node, handle, false);
|
||||||
},
|
},
|
||||||
.container_field,
|
.container_field,
|
||||||
.container_field_align,
|
.container_field_align,
|
||||||
.container_field_init,
|
.container_field_init,
|
||||||
=> {
|
=> {
|
||||||
const field = ast.containerField(tree, node).?;
|
const field = ast.containerField(tree, node).?;
|
||||||
try symbolReferencesInternal(builder, field.ast.type_expr, handle);
|
try symbolReferencesInternal(builder, field.ast.type_expr, handle, false);
|
||||||
try symbolReferencesInternal(builder, field.ast.value_expr, handle);
|
try symbolReferencesInternal(builder, field.ast.value_expr, handle, false);
|
||||||
},
|
},
|
||||||
.identifier => {
|
.identifier => {
|
||||||
const child = (try analysis.lookupSymbolGlobal(builder.store, builder.arena, handle, tree.getNodeSource(node), starts[main_tokens[node]])) orelse return;
|
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(
|
|||||||
const fn_proto = ast.fnProto(tree, node, &buf).?;
|
const fn_proto = ast.fnProto(tree, node, &buf).?;
|
||||||
var it = fn_proto.iterate(&tree);
|
var it = fn_proto.iterate(&tree);
|
||||||
while (ast.nextFnParam(&it)) |param| {
|
while (ast.nextFnParam(&it)) |param| {
|
||||||
try symbolReferencesInternal(builder, param.type_expr, handle);
|
try symbolReferencesInternal(builder, param.type_expr, handle, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
try symbolReferencesInternal(builder, fn_proto.ast.return_type, handle);
|
try symbolReferencesInternal(builder, fn_proto.ast.return_type, handle, false);
|
||||||
try symbolReferencesInternal(builder, fn_proto.ast.align_expr, handle);
|
try symbolReferencesInternal(builder, fn_proto.ast.align_expr, handle, false);
|
||||||
try symbolReferencesInternal(builder, fn_proto.ast.section_expr, handle);
|
try symbolReferencesInternal(builder, fn_proto.ast.section_expr, handle, false);
|
||||||
try symbolReferencesInternal(builder, fn_proto.ast.callconv_expr, handle);
|
try symbolReferencesInternal(builder, fn_proto.ast.callconv_expr, handle, false);
|
||||||
if (node_tags[node] == .fn_decl) {
|
if (node_tags[node] == .fn_decl) {
|
||||||
try symbolReferencesInternal(builder, datas[node].rhs, handle);
|
try symbolReferencesInternal(builder, datas[node].rhs, handle, false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.@"switch",
|
.@"switch",
|
||||||
.switch_comma,
|
.switch_comma,
|
||||||
=> {
|
=> {
|
||||||
// TODO When renaming a union(enum) field, also rename switch items that refer to it.
|
// TODO When renaming a union(enum) field, also rename switch items that refer to it.
|
||||||
try symbolReferencesInternal(builder, datas[node].lhs, handle);
|
try symbolReferencesInternal(builder, datas[node].lhs, handle, false);
|
||||||
const extra = tree.extraData(datas[node].rhs, Ast.Node.SubRange);
|
const extra = tree.extraData(datas[node].rhs, Ast.Node.SubRange);
|
||||||
const cases = tree.extra_data[extra.start..extra.end];
|
const cases = tree.extra_data[extra.start..extra.end];
|
||||||
for (cases) |case| {
|
for (cases) |case| {
|
||||||
try symbolReferencesInternal(builder, case, handle);
|
try symbolReferencesInternal(builder, case, handle, false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.switch_case_one,
|
.switch_case_one,
|
||||||
.switch_case_inline_one,
|
.switch_case_inline_one,
|
||||||
=> {
|
=> {
|
||||||
const case_one = tree.switchCaseOne(node);
|
const case_one = tree.switchCaseOne(node);
|
||||||
try symbolReferencesInternal(builder, case_one.ast.target_expr, handle);
|
try symbolReferencesInternal(builder, case_one.ast.target_expr, handle, false);
|
||||||
for (case_one.ast.values) |val|
|
for (case_one.ast.values) |val|
|
||||||
try symbolReferencesInternal(builder, val, handle);
|
try symbolReferencesInternal(builder, val, handle, false);
|
||||||
},
|
},
|
||||||
.switch_case,
|
.switch_case,
|
||||||
.switch_case_inline,
|
.switch_case_inline,
|
||||||
=> {
|
=> {
|
||||||
const case = tree.switchCase(node);
|
const case = tree.switchCase(node);
|
||||||
try symbolReferencesInternal(builder, case.ast.target_expr, handle);
|
try symbolReferencesInternal(builder, case.ast.target_expr, handle, false);
|
||||||
for (case.ast.values) |val|
|
for (case.ast.values) |val|
|
||||||
try symbolReferencesInternal(builder, val, handle);
|
try symbolReferencesInternal(builder, val, handle, false);
|
||||||
},
|
},
|
||||||
.@"while",
|
.@"while",
|
||||||
.while_simple,
|
.while_simple,
|
||||||
@ -199,17 +200,17 @@ fn symbolReferencesInternal(
|
|||||||
.@"for",
|
.@"for",
|
||||||
=> {
|
=> {
|
||||||
const loop = ast.whileAst(tree, node).?;
|
const loop = ast.whileAst(tree, node).?;
|
||||||
try symbolReferencesInternal(builder, loop.ast.cond_expr, handle);
|
try symbolReferencesInternal(builder, loop.ast.cond_expr, handle, false);
|
||||||
try symbolReferencesInternal(builder, loop.ast.then_expr, handle);
|
try symbolReferencesInternal(builder, loop.ast.then_expr, handle, false);
|
||||||
try symbolReferencesInternal(builder, loop.ast.else_expr, handle);
|
try symbolReferencesInternal(builder, loop.ast.else_expr, handle, false);
|
||||||
},
|
},
|
||||||
.@"if",
|
.@"if",
|
||||||
.if_simple,
|
.if_simple,
|
||||||
=> {
|
=> {
|
||||||
const if_node = ast.ifFull(tree, node);
|
const if_node = ast.ifFull(tree, node);
|
||||||
try symbolReferencesInternal(builder, if_node.ast.cond_expr, handle);
|
try symbolReferencesInternal(builder, if_node.ast.cond_expr, handle, false);
|
||||||
try symbolReferencesInternal(builder, if_node.ast.then_expr, handle);
|
try symbolReferencesInternal(builder, if_node.ast.then_expr, handle, false);
|
||||||
try symbolReferencesInternal(builder, if_node.ast.else_expr, handle);
|
try symbolReferencesInternal(builder, if_node.ast.else_expr, handle, false);
|
||||||
},
|
},
|
||||||
.ptr_type,
|
.ptr_type,
|
||||||
.ptr_type_aligned,
|
.ptr_type_aligned,
|
||||||
@ -219,15 +220,15 @@ fn symbolReferencesInternal(
|
|||||||
const ptr_type = ast.ptrType(tree, node).?;
|
const ptr_type = ast.ptrType(tree, node).?;
|
||||||
|
|
||||||
if (ptr_type.ast.align_node != 0) {
|
if (ptr_type.ast.align_node != 0) {
|
||||||
try symbolReferencesInternal(builder, ptr_type.ast.align_node, handle);
|
try symbolReferencesInternal(builder, ptr_type.ast.align_node, handle, false);
|
||||||
if (node_tags[node] == .ptr_type_bit_range) {
|
if (node_tags[node] == .ptr_type_bit_range) {
|
||||||
try symbolReferencesInternal(builder, ptr_type.ast.bit_range_start, handle);
|
try symbolReferencesInternal(builder, ptr_type.ast.bit_range_start, handle, false);
|
||||||
try symbolReferencesInternal(builder, ptr_type.ast.bit_range_end, handle);
|
try symbolReferencesInternal(builder, ptr_type.ast.bit_range_end, handle, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try symbolReferencesInternal(builder, ptr_type.ast.sentinel, handle);
|
try symbolReferencesInternal(builder, ptr_type.ast.sentinel, handle, false);
|
||||||
try symbolReferencesInternal(builder, ptr_type.ast.child_type, handle);
|
try symbolReferencesInternal(builder, ptr_type.ast.child_type, handle, false);
|
||||||
},
|
},
|
||||||
.array_init,
|
.array_init,
|
||||||
.array_init_comma,
|
.array_init_comma,
|
||||||
@ -246,9 +247,9 @@ fn symbolReferencesInternal(
|
|||||||
.array_init_dot_two, .array_init_dot_two_comma => tree.arrayInitDotTwo(&buf, node),
|
.array_init_dot_two, .array_init_dot_two_comma => tree.arrayInitDotTwo(&buf, node),
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
};
|
};
|
||||||
try symbolReferencesInternal(builder, array_init.ast.type_expr, handle);
|
try symbolReferencesInternal(builder, array_init.ast.type_expr, handle, false);
|
||||||
for (array_init.ast.elements) |e|
|
for (array_init.ast.elements) |e|
|
||||||
try symbolReferencesInternal(builder, e, handle);
|
try symbolReferencesInternal(builder, e, handle, false);
|
||||||
},
|
},
|
||||||
.struct_init,
|
.struct_init,
|
||||||
.struct_init_comma,
|
.struct_init_comma,
|
||||||
@ -267,9 +268,9 @@ fn symbolReferencesInternal(
|
|||||||
.struct_init_dot_two, .struct_init_dot_two_comma => tree.structInitDotTwo(&buf, node),
|
.struct_init_dot_two, .struct_init_dot_two_comma => tree.structInitDotTwo(&buf, node),
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
};
|
};
|
||||||
try symbolReferencesInternal(builder, struct_init.ast.type_expr, handle);
|
try symbolReferencesInternal(builder, struct_init.ast.type_expr, handle, false);
|
||||||
for (struct_init.ast.fields) |field|
|
for (struct_init.ast.fields) |field|
|
||||||
try symbolReferencesInternal(builder, field, handle);
|
try symbolReferencesInternal(builder, field, handle, false);
|
||||||
},
|
},
|
||||||
.call,
|
.call,
|
||||||
.call_comma,
|
.call_comma,
|
||||||
@ -283,10 +284,10 @@ fn symbolReferencesInternal(
|
|||||||
var buf: [1]Ast.Node.Index = undefined;
|
var buf: [1]Ast.Node.Index = undefined;
|
||||||
const call = ast.callFull(tree, node, &buf).?;
|
const call = ast.callFull(tree, node, &buf).?;
|
||||||
|
|
||||||
try symbolReferencesInternal(builder, call.ast.fn_expr, handle);
|
try symbolReferencesInternal(builder, call.ast.fn_expr, handle, false);
|
||||||
|
|
||||||
for (call.ast.params) |param| {
|
for (call.ast.params) |param| {
|
||||||
try symbolReferencesInternal(builder, param, handle);
|
try symbolReferencesInternal(builder, param, handle, false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.slice,
|
.slice,
|
||||||
@ -300,10 +301,10 @@ fn symbolReferencesInternal(
|
|||||||
else => unreachable,
|
else => unreachable,
|
||||||
};
|
};
|
||||||
|
|
||||||
try symbolReferencesInternal(builder, slice.ast.sliced, handle);
|
try symbolReferencesInternal(builder, slice.ast.sliced, handle, false);
|
||||||
try symbolReferencesInternal(builder, slice.ast.start, handle);
|
try symbolReferencesInternal(builder, slice.ast.start, handle, false);
|
||||||
try symbolReferencesInternal(builder, slice.ast.end, handle);
|
try symbolReferencesInternal(builder, slice.ast.end, handle, false);
|
||||||
try symbolReferencesInternal(builder, slice.ast.sentinel, handle);
|
try symbolReferencesInternal(builder, slice.ast.sentinel, handle, false);
|
||||||
},
|
},
|
||||||
.builtin_call,
|
.builtin_call,
|
||||||
.builtin_call_comma,
|
.builtin_call_comma,
|
||||||
@ -314,25 +315,26 @@ fn symbolReferencesInternal(
|
|||||||
const params = ast.builtinCallParams(tree, node, &buffer).?;
|
const params = ast.builtinCallParams(tree, node, &buffer).?;
|
||||||
|
|
||||||
for (params) |param|
|
for (params) |param|
|
||||||
try symbolReferencesInternal(builder, param, handle);
|
try symbolReferencesInternal(builder, param, handle, false);
|
||||||
},
|
},
|
||||||
.@"asm",
|
.@"asm",
|
||||||
.asm_simple,
|
.asm_simple,
|
||||||
=> |tag| {
|
=> |tag| {
|
||||||
const full_asm: Ast.full.Asm = if (tag == .@"asm") tree.asmFull(node) else tree.asmSimple(node);
|
const full_asm: Ast.full.Asm = if (tag == .@"asm") tree.asmFull(node) else tree.asmSimple(node);
|
||||||
if (full_asm.ast.items.len == 0)
|
if (full_asm.ast.items.len == 0)
|
||||||
try symbolReferencesInternal(builder, full_asm.ast.template, handle);
|
try symbolReferencesInternal(builder, full_asm.ast.template, handle, false);
|
||||||
|
|
||||||
for (full_asm.inputs) |input|
|
for (full_asm.inputs) |input|
|
||||||
try symbolReferencesInternal(builder, input, handle);
|
try symbolReferencesInternal(builder, input, handle, false);
|
||||||
|
|
||||||
for (full_asm.outputs) |output|
|
for (full_asm.outputs) |output|
|
||||||
try symbolReferencesInternal(builder, output, handle);
|
try symbolReferencesInternal(builder, output, handle, false);
|
||||||
},
|
},
|
||||||
.asm_output => unreachable,
|
// TODO implement references for asm
|
||||||
.asm_input => unreachable,
|
.asm_output => {},
|
||||||
|
.asm_input => {},
|
||||||
.field_access => {
|
.field_access => {
|
||||||
try symbolReferencesInternal(builder, datas[node].lhs, handle);
|
try symbolReferencesInternal(builder, datas[node].lhs, handle, false);
|
||||||
|
|
||||||
const rhs_str = ast.tokenSlice(tree, datas[node].rhs) catch return;
|
const rhs_str = ast.tokenSlice(tree, datas[node].rhs) catch return;
|
||||||
var bound_type_params = analysis.BoundTypeParams{};
|
var bound_type_params = analysis.BoundTypeParams{};
|
||||||
@ -380,12 +382,12 @@ fn symbolReferencesInternal(
|
|||||||
.grouped_expression,
|
.grouped_expression,
|
||||||
.@"comptime",
|
.@"comptime",
|
||||||
.@"nosuspend",
|
.@"nosuspend",
|
||||||
=> try symbolReferencesInternal(builder, datas[node].lhs, handle),
|
=> try symbolReferencesInternal(builder, datas[node].lhs, handle, false),
|
||||||
.test_decl,
|
.test_decl,
|
||||||
.@"errdefer",
|
.@"errdefer",
|
||||||
.@"defer",
|
.@"defer",
|
||||||
.anyframe_type,
|
.anyframe_type,
|
||||||
=> try symbolReferencesInternal(builder, datas[node].rhs, handle),
|
=> try symbolReferencesInternal(builder, datas[node].rhs, handle, false),
|
||||||
.equal_equal,
|
.equal_equal,
|
||||||
.bang_equal,
|
.bang_equal,
|
||||||
.less_than,
|
.less_than,
|
||||||
@ -440,8 +442,8 @@ fn symbolReferencesInternal(
|
|||||||
.switch_range,
|
.switch_range,
|
||||||
.error_union,
|
.error_union,
|
||||||
=> {
|
=> {
|
||||||
try symbolReferencesInternal(builder, datas[node].lhs, handle);
|
try symbolReferencesInternal(builder, datas[node].lhs, handle, false);
|
||||||
try symbolReferencesInternal(builder, datas[node].rhs, handle);
|
try symbolReferencesInternal(builder, datas[node].rhs, handle, false);
|
||||||
},
|
},
|
||||||
.anyframe_literal,
|
.anyframe_literal,
|
||||||
.char_literal,
|
.char_literal,
|
||||||
@ -472,15 +474,9 @@ pub fn symbolReferences(
|
|||||||
if (include_decl) try builder.add(curr_handle, decl_handle.nameToken());
|
if (include_decl) try builder.add(curr_handle, decl_handle.nameToken());
|
||||||
|
|
||||||
switch (decl_handle.decl.*) {
|
switch (decl_handle.decl.*) {
|
||||||
.pointer_payload,
|
.ast_node => {
|
||||||
.switch_payload,
|
try symbolReferencesInternal(&builder, 0, curr_handle, true);
|
||||||
.array_payload,
|
|
||||||
.array_index,
|
|
||||||
.ast_node,
|
|
||||||
=> {
|
|
||||||
try symbolReferencesInternal(&builder, 0, curr_handle);
|
|
||||||
|
|
||||||
if (decl_handle.decl.* != .ast_node) return builder.locations;
|
|
||||||
if (!workspace) return builder.locations;
|
if (!workspace) return builder.locations;
|
||||||
|
|
||||||
for (store.handles.values()) |handle| {
|
for (store.handles.values()) |handle| {
|
||||||
@ -494,10 +490,19 @@ pub fn symbolReferences(
|
|||||||
|
|
||||||
for (dependencies.items) |uri| {
|
for (dependencies.items) |uri| {
|
||||||
const hdl = store.getHandle(uri) orelse continue;
|
const hdl = store.getHandle(uri) orelse continue;
|
||||||
try symbolReferencesInternal(&builder, 0, hdl);
|
try symbolReferencesInternal(&builder, 0, hdl, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
.pointer_payload,
|
||||||
|
.switch_payload,
|
||||||
|
.array_payload,
|
||||||
|
.array_index,
|
||||||
|
=> {
|
||||||
|
try symbolReferencesInternal(&builder, 0, curr_handle, true);
|
||||||
|
|
||||||
|
return builder.locations;
|
||||||
|
},
|
||||||
.param_payload => |pay| blk: {
|
.param_payload => |pay| blk: {
|
||||||
// Rename the param tok.
|
// Rename the param tok.
|
||||||
const param = pay.param;
|
const param = pay.param;
|
||||||
@ -514,7 +519,7 @@ pub fn symbolReferences(
|
|||||||
if (!std.meta.eql(candidate, param)) continue;
|
if (!std.meta.eql(candidate, param)) continue;
|
||||||
|
|
||||||
if (curr_handle.tree.nodes.items(.tag)[proto] != .fn_decl) break :blk;
|
if (curr_handle.tree.nodes.items(.tag)[proto] != .fn_decl) break :blk;
|
||||||
try symbolReferencesInternal(&builder, curr_handle.tree.nodes.items(.data)[proto].rhs, curr_handle);
|
try symbolReferencesInternal(&builder, curr_handle.tree.nodes.items(.data)[proto].rhs, curr_handle, false);
|
||||||
break :blk;
|
break :blk;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,6 @@ const allocator: std.mem.Allocator = std.testing.allocator;
|
|||||||
const skip_references_tests = true;
|
const skip_references_tests = true;
|
||||||
|
|
||||||
test "references" {
|
test "references" {
|
||||||
if (skip_references_tests) return error.SkipZigTest;
|
|
||||||
try testReferences(
|
try testReferences(
|
||||||
\\const <0> = 0;
|
\\const <0> = 0;
|
||||||
\\const foo = <0>;
|
\\const foo = <0>;
|
||||||
@ -48,7 +47,6 @@ test "references" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "references - global scope" {
|
test "references - global scope" {
|
||||||
if (skip_references_tests) return error.SkipZigTest;
|
|
||||||
try testReferences(
|
try testReferences(
|
||||||
\\const foo = <0>;
|
\\const foo = <0>;
|
||||||
\\const <0> = 0;
|
\\const <0> = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user