Fix symbolReferencesInternal
This commit is contained in:
parent
e82ea30e6f
commit
ada0d13ba9
@ -2261,21 +2261,15 @@ pub fn isContainer(tag: ast.Node.Tag) bool {
|
||||
|
||||
/// Returns the member indices of a given declaration container.
|
||||
/// Asserts given `tag` is a container node
|
||||
fn declMembers(tree: ast.Tree, tag: ast.Node.Tag, node_idx: ast.Node.Index) []const ast.Node.Index {
|
||||
pub fn declMembers(tree: ast.Tree, tag: ast.Node.Tag, node_idx: ast.Node.Index, buffer: *[2]ast.Node.Index) []const ast.Node.Index {
|
||||
std.debug.assert(isContainer(tag));
|
||||
return switch (tag) {
|
||||
.container_decl, .container_decl_trailing => tree.containerDecl(node_idx).ast.members,
|
||||
.container_decl_arg, .container_decl_arg_trailing => tree.containerDeclArg(node_idx).ast.members,
|
||||
.container_decl_two, .container_decl_two_trailing => blk: {
|
||||
var buffer: [2]ast.Node.Index = undefined;
|
||||
break :blk tree.containerDeclTwo(&buffer, node_idx).ast.members;
|
||||
},
|
||||
.container_decl_two, .container_decl_two_trailing => tree.containerDeclTwo(&buffer, node_idx).ast.members,
|
||||
.tagged_union, .tagged_union_trailing => tree.taggedUnion(node_idx).ast.members,
|
||||
.tagged_union_enum_tag, .tagged_union_enum_tag_trailing => tree.taggedUnionEnumTag(node_idx).ast.members,
|
||||
.tagged_union_two, .tagged_union_two_trailing => blk: {
|
||||
var buffer: [2]ast.Node.Index = undefined;
|
||||
break :blk tree.taggedUnionTwo(&buffer, node_idx).ast.members;
|
||||
},
|
||||
.tagged_union_two, .tagged_union_two_trailing => tree.taggedUnionTwo(&buffer, node_idx).ast.members,
|
||||
.root => tree.rootDecls(),
|
||||
// @TODO: Fix error set declarations
|
||||
.error_set_decl => &[_]ast.Node.Index{},
|
||||
@ -2312,6 +2306,7 @@ fn makeScopeInternal(
|
||||
const node = tags[node_idx];
|
||||
|
||||
if (isContainer(node)) {
|
||||
var buf: [2]ast.Node.Index = undefined;
|
||||
const ast_decls = declMembers(tree, node, node_idx);
|
||||
|
||||
(try scopes.addOne(allocator)).* = .{
|
||||
|
@ -77,263 +77,326 @@ fn symbolReferencesInternal(
|
||||
) error{OutOfMemory}!void {
|
||||
const node = node_handle.node;
|
||||
const handle = node_handle.handle;
|
||||
const tree = handle.tree;
|
||||
const node_tags = tree.nodes.items(.tag);
|
||||
const datas = tree.nodes.items(.data);
|
||||
const main_tokens = tree.nodes.items(.main_token);
|
||||
const starts = tree.tokens.items(.start);
|
||||
|
||||
switch (handle.tree.nodes.items(.tag)[node]) {
|
||||
.ContainerDecl, .Root, .Block => {
|
||||
var idx: usize = 0;
|
||||
while (node.iterate(idx)) |child| : (idx += 1) {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = child, .handle = handle }, decl, encoding, context, handler);
|
||||
switch (node_tags[node]) {
|
||||
.block, .block_semicolon, .block_two, .block_two_semicolon => {
|
||||
const statements: []const ast.Node.Index = switch (node_tags[node]) {
|
||||
.block, .block_semicolon => tree.extra_data[datas[node].lhs..datas[node].rhs],
|
||||
.block_two, .block_two_semicolon => blk: {
|
||||
const statements = &[_]ast.Node.Index{ datas[node].lhs, datas[node].rhs };
|
||||
const len: usize = if (datas[node].lhs == 0)
|
||||
@as(usize, 0)
|
||||
else if (datas[node].rhs == 0)
|
||||
@as(usize, 1)
|
||||
else
|
||||
@as(usize, 2);
|
||||
break :blk statements[0..len];
|
||||
},
|
||||
else => unreachable,
|
||||
};
|
||||
for (statements) |stmt|
|
||||
try symbolReferencesInternal(arena, store, .{ .node = stmt, .handle = handle }, decl, encoding, context, handler);
|
||||
},
|
||||
.container_decl,
|
||||
.container_decl_trailing,
|
||||
.container_decl_arg,
|
||||
.container_decl_arg_trailing,
|
||||
.container_decl_two,
|
||||
.container_decl_two_trailing,
|
||||
.tagged_union,
|
||||
.tagged_union_trailing,
|
||||
.tagged_union_two,
|
||||
.tagged_union_two_trailing,
|
||||
.tagged_union_enum_tag,
|
||||
.tagged_union_enum_tag_trailing,
|
||||
.root,
|
||||
.error_set_decl,
|
||||
=> {
|
||||
var buf: [2]ast.Node.Index = undefined;
|
||||
for (analysis.declMembers(tree, node_tags[node], node, &buf)) |member|
|
||||
try symbolReferencesInternal(arena, store, .{ .node = member, .handle = handle }, decl, encoding, context, handler);
|
||||
},
|
||||
.global_var_decl, .local_var_decl, .simple_var_decl, .aligned_var_decl => {
|
||||
const var_decl = analysis.varDecl(tree, node).?;
|
||||
if (var_decl.ast.type_node != 0) {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = var_decl.ast.type_node, .handle = handle }, decl, encoding, context, handler);
|
||||
}
|
||||
if (var_decl.ast.init_node != 0) {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = var_decl.ast.init_node, .handle = handle }, decl, encoding, context, handler);
|
||||
}
|
||||
},
|
||||
.VarDecl => {
|
||||
const var_decl = node.cast(ast.Node.VarDecl).?;
|
||||
if (var_decl.getTypeNode()) |type_node| {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = type_node, .handle = handle }, decl, encoding, context, handler);
|
||||
// @TODO: Usingnamespace
|
||||
// .Use => {
|
||||
// const use = node.cast(ast.Node.Use).?;
|
||||
// try symbolReferencesInternal(arena, store, .{ .node = use.expr, .handle = handle }, decl, encoding, context, handler);
|
||||
// },
|
||||
.container_field, .container_field_align, .container_field_init => {
|
||||
const field = analysis.containerField(node).?;
|
||||
if (field.ast.type_expr != 0) {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = field.ast.type_expr, .handle = handle }, decl, encoding, context, handler);
|
||||
}
|
||||
if (var_decl.getInitNode()) |init_node| {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = init_node, .handle = handle }, decl, encoding, context, handler);
|
||||
if (field.ast.value_expr != 0) {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = field.ast.value_expr, .handle = handle }, decl, encoding, context, handler);
|
||||
}
|
||||
},
|
||||
.Use => {
|
||||
const use = node.cast(ast.Node.Use).?;
|
||||
try symbolReferencesInternal(arena, store, .{ .node = use.expr, .handle = handle }, decl, encoding, context, handler);
|
||||
},
|
||||
.ContainerField => {
|
||||
const field = node.cast(ast.Node.ContainerField).?;
|
||||
if (field.type_expr) |type_node| {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = type_node, .handle = handle }, decl, encoding, context, handler);
|
||||
}
|
||||
if (field.value_expr) |init_node| {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = init_node, .handle = handle }, decl, encoding, context, handler);
|
||||
}
|
||||
},
|
||||
.Identifier => {
|
||||
if (try analysis.lookupSymbolGlobal(store, arena, handle, handle.tree.getNodeSource(node), handle.tree.token_locs[node.firstToken()].start)) |child| {
|
||||
.identifier => {
|
||||
if (try analysis.lookupSymbolGlobal(store, arena, handle, tree.getNodeSource(node), starts[main_tokens[nodes]])) |child| {
|
||||
if (std.meta.eql(decl, child)) {
|
||||
try tokenReference(handle, node.firstToken(), encoding, context, handler);
|
||||
try tokenReference(handle, main_tokens[node], encoding, context, handler);
|
||||
}
|
||||
}
|
||||
},
|
||||
.FnProto => {
|
||||
const fn_proto = node.cast(ast.Node.FnProto).?;
|
||||
for (fn_proto.paramsConst()) |param| {
|
||||
switch (param.param_type) {
|
||||
.type_expr => |type_node| {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = type_node, .handle = handle }, decl, encoding, context, handler);
|
||||
},
|
||||
else => {},
|
||||
.fn_proto, .fn_proto_multi, .fn_proto_one, .fn_proto_simple, .fn_decl => {
|
||||
var buf: [1]ast.Node.Index = undefined;
|
||||
const fn_proto = analysis.fnProto(tree, node, &buf).?;
|
||||
var it = fn_proto.iterate(tree);
|
||||
while (it.next()) |param| {
|
||||
if (param.type_expr != 0)
|
||||
try symbolReferencesInternal(arena, store, .{ .node = param.type_expr, .handle = handle }, decl, encoding, context, handler);
|
||||
}
|
||||
|
||||
if (fn_proto.ast.return_type != 0) {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = fn_proto.ast.return_type, .handle = handle }, decl, encoding, context, handler);
|
||||
}
|
||||
switch (fn_proto.return_type) {
|
||||
.Explicit, .InferErrorSet => |type_node| {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = type_node, .handle = handle }, decl, encoding, context, handler);
|
||||
},
|
||||
else => {},
|
||||
if (fn_proto.ast.align_expr != 0) {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = fn_proto.ast.align_expr, .handle = handle }, decl, encoding, context, handler);
|
||||
}
|
||||
if (fn_proto.getAlignExpr()) |align_expr| {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = align_expr, .handle = handle }, decl, encoding, context, handler);
|
||||
if (fn_proto.ast.section_expr != 0) {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = fn_proto.ast.section_expr, .handle = handle }, decl, encoding, context, handler);
|
||||
}
|
||||
if (fn_proto.getSectionExpr()) |section_expr| {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = section_expr, .handle = handle }, decl, encoding, context, handler);
|
||||
if (fn_proto.ast.callconv_expr != 0) {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = fn_proto.ast.callconv_expr, .handle = handle }, decl, encoding, context, handler);
|
||||
}
|
||||
if (fn_proto.getCallconvExpr()) |callconv_expr| {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = callconv_expr, .handle = handle }, decl, encoding, context, handler);
|
||||
}
|
||||
if (fn_proto.getBodyNode()) |body| {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = body, .handle = handle }, decl, encoding, context, handler);
|
||||
if (node_tags[node] == .fn_decl) {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = datas[node].rhs, .handle = handle }, decl, encoding, context, handler);
|
||||
}
|
||||
},
|
||||
.AnyFrameType => {
|
||||
const anyframe_type = node.cast(ast.Node.AnyFrameType).?;
|
||||
if (anyframe_type.result) |result| {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = result.return_type, .handle = handle }, decl, encoding, context, handler);
|
||||
}
|
||||
.anyframe_type => {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = datas[node].rhs, .handle = handle }, decl, encoding, context, handler);
|
||||
},
|
||||
.Defer => {
|
||||
const defer_node = node.cast(ast.Node.Defer).?;
|
||||
try symbolReferencesInternal(arena, store, .{ .node = defer_node.expr, .handle = handle }, decl, encoding, context, handler);
|
||||
.@"defer" => {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = datas[node].rhs, .handle = handle }, decl, encoding, context, handler);
|
||||
},
|
||||
.Comptime => {
|
||||
const comptime_node = node.cast(ast.Node.Comptime).?;
|
||||
try symbolReferencesInternal(arena, store, .{ .node = comptime_node.expr, .handle = handle }, decl, encoding, context, handler);
|
||||
.@"comptime" => {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = datas[node].lhs, .handle = handle }, decl, encoding, context, handler);
|
||||
},
|
||||
.Nosuspend => {
|
||||
const nosuspend_node = node.cast(ast.Node.Nosuspend).?;
|
||||
try symbolReferencesInternal(arena, store, .{ .node = nosuspend_node.expr, .handle = handle }, decl, encoding, context, handler);
|
||||
.@"nosuspend" => {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = datas[node].lhs, .handle = handle }, decl, encoding, context, handler);
|
||||
},
|
||||
.Switch => {
|
||||
.@"switch", .switch_comma => {
|
||||
// TODO When renaming a union(enum) field, also rename switch items that refer to it.
|
||||
const switch_node = node.cast(ast.Node.Switch).?;
|
||||
try symbolReferencesInternal(arena, store, .{ .node = switch_node.expr, .handle = handle }, decl, encoding, context, handler);
|
||||
for (switch_node.casesConst()) |case| {
|
||||
if (case.*.cast(ast.Node.SwitchCase)) |case_node| {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = case_node.expr, .handle = handle }, decl, encoding, context, handler);
|
||||
}
|
||||
try symbolReferencesInternal(arena, store, .{ .node = datas[node].lhs, .handle = handle }, decl, encoding, context, handler);
|
||||
const extra = tree.extraData(datas[node].rhs, ast.Node.SubRange);
|
||||
const cases = tree.extra_data[extra.start..extra.end];
|
||||
for (cases) |case| {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = case, .handle = handle }, decl, encoding, context, handler);
|
||||
}
|
||||
},
|
||||
.While => {
|
||||
const while_node = node.cast(ast.Node.While).?;
|
||||
try symbolReferencesInternal(arena, store, .{ .node = while_node.condition, .handle = handle }, decl, encoding, context, handler);
|
||||
if (while_node.continue_expr) |cont_expr| {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = cont_expr, .handle = handle }, decl, encoding, context, handler);
|
||||
.switch_case_one => {
|
||||
const case_one = tree.switchCaseOne(node);
|
||||
for (case_one.ast.values) |val|
|
||||
try symbolReferencesInternal(arena, store, .{ .node = val, .handle = handle }, decl, encoding, context, handler);
|
||||
},
|
||||
.switch_case => {
|
||||
const case = tree.switchCase(node);
|
||||
for (case_one.ast.values) |val|
|
||||
try symbolReferencesInternal(arena, store, .{ .node = val, .handle = handle }, decl, encoding, context, handler);
|
||||
},
|
||||
.@"while", .while_simple, .while_con, .for_simple, .@"for" => {
|
||||
const loop: ast.full.While = switch (node_tags[node]) {
|
||||
.@"while" => tree.whileFull(node),
|
||||
.while_simple => tree.whileSimple(node),
|
||||
.while_con => tree.whileCont(node),
|
||||
.for_simple => tree.forSimple(node),
|
||||
.@"for" => tree.forFull(node),
|
||||
else => unreachable,
|
||||
};
|
||||
try symbolReferencesInternal(arena, store, .{ .node = loop.ast.cond_expr, .handle = handle }, decl, encoding, context, handler);
|
||||
if (loop.ast.cont_expr != 0) {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = loop.ast.cont_expr, .handle = handle }, decl, encoding, context, handler);
|
||||
}
|
||||
try symbolReferencesInternal(arena, store, .{ .node = while_node.body, .handle = handle }, decl, encoding, context, handler);
|
||||
if (while_node.@"else") |else_node| {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = else_node.body, .handle = handle }, decl, encoding, context, handler);
|
||||
try symbolReferencesInternal(arena, store, .{ .node = loop.ast.then_expr, .handle = handle }, decl, encoding, context, handler);
|
||||
if (loop.ast.else_expr != 0) {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = loop.ast.else_expr, .handle = handle }, decl, encoding, context, handler);
|
||||
}
|
||||
},
|
||||
.For => {
|
||||
const for_node = node.cast(ast.Node.For).?;
|
||||
try symbolReferencesInternal(arena, store, .{ .node = for_node.array_expr, .handle = handle }, decl, encoding, context, handler);
|
||||
try symbolReferencesInternal(arena, store, .{ .node = for_node.body, .handle = handle }, decl, encoding, context, handler);
|
||||
if (for_node.@"else") |else_node| {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = else_node.body, .handle = handle }, decl, encoding, context, handler);
|
||||
.@"if", .if_simple => {
|
||||
const if_node: ast.full.If = if (node_tags[node] == .@"if") tree.ifFull(node) else tree.ifSimple(node);
|
||||
|
||||
try symbolReferencesInternal(arena, store, .{ .node = if_node.ast.cond_expr, .handle = handle }, decl, encoding, context, handler);
|
||||
try symbolReferencesInternal(arena, store, .{ .node = if_node.ast.then_expr, .handle = handle }, decl, encoding, context, handler);
|
||||
if (if_node.ast.else_expr != 0) {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = if_node.ast.else_expr, .handle = handle }, decl, encoding, context, handler);
|
||||
}
|
||||
},
|
||||
.If => {
|
||||
const if_node = node.cast(ast.Node.If).?;
|
||||
try symbolReferencesInternal(arena, store, .{ .node = if_node.condition, .handle = handle }, decl, encoding, context, handler);
|
||||
try symbolReferencesInternal(arena, store, .{ .node = if_node.body, .handle = handle }, decl, encoding, context, handler);
|
||||
if (if_node.@"else") |else_node| {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = else_node.body, .handle = handle }, decl, encoding, context, handler);
|
||||
.array_type, .array_type_sentinel => {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = datas[node].lhs, .handle = handle }, decl, encoding, context, handler);
|
||||
try symbolReferencesInternal(arena, store, .{ .node = datas[node].rhs, .handle = handle }, decl, encoding, context, handler);
|
||||
},
|
||||
.ptr_type, .ptr_type_aligned, .ptr_type_bit_range, .ptr_type_sentinel => {
|
||||
const ptr_type = analysis.ptrType(tree, node).?;
|
||||
|
||||
if (ptr_type.ast.align_node != 0) {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = ptr_type.ast.align_node, .handle = handle }, decl, encoding, context, handler);
|
||||
if (node_tags[node] == .ptr_type_bit_range) {
|
||||
try symbolReferencesInternal(arena, store, .{
|
||||
.node = ptr_type.ast.bit_range_start,
|
||||
.handle = handle,
|
||||
}, decl, encoding, context, handler);
|
||||
try symbolReferencesInternal(arena, store, .{
|
||||
.node = ptr_type.ast.bit_range_end,
|
||||
.handle = handle,
|
||||
}, decl, encoding, context, handler);
|
||||
}
|
||||
}
|
||||
if (ptr_type.ast.sentinel != 0) {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = ptr_type.ast.sentinel, .handle = handle }, decl, encoding, context, handler);
|
||||
}
|
||||
|
||||
try symbolReferencesInternal(arena, store, .{ .node = ptr_type.ast.child_type, .handle = handle }, decl, encoding, context, handler);
|
||||
},
|
||||
.address_of, .@"await", .bit_not, .bool_not, .optional_type, .negation, .negation_wrap, .@"resume", .@"try" => {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = datas[node].lhs, .handle = handle }, decl, encoding, context, handler);
|
||||
},
|
||||
.array_init,
|
||||
.array_init_comma,
|
||||
.array_init_dot,
|
||||
.array_init_dot_comma,
|
||||
.array_init_one,
|
||||
.array_init_one_comma,
|
||||
.array_init_dot_two,
|
||||
.array_init_dot_two_comma,
|
||||
=> |n| {
|
||||
var buf: [2]ast.Node.Index = undefined;
|
||||
const array_init = switch (n) {
|
||||
.array_init, .array_init_comma => tree.arrayInit(node),
|
||||
.array_init_dot, .array_init_dot_comma => tree.arrayInitDot(node),
|
||||
.array_init_one, .array_init_one_comma => tree.arrayInitOne(&buf[0..1], node),
|
||||
.array_init_dot_two, .array_init_dot_two_comma => tree.arrayInitDotTwo(&buf, node),
|
||||
else => unreachable,
|
||||
};
|
||||
if (array_init.ast.type_expr != 0)
|
||||
try symbolReferencesInternal(arena, store, .{ .node = array_init.ast.type_expr, .handle = handle }, decl, encoding, context, handler);
|
||||
for (array_init.ast.elements) |e|
|
||||
try symbolReferencesInternal(arena, store, .{ .node = e, .handle = handle }, decl, encoding, context, handler);
|
||||
},
|
||||
.struct_init,
|
||||
.struct_init_comma,
|
||||
.struct_init_dot,
|
||||
.struct_init_dot_comma,
|
||||
.struct_init_dot_two,
|
||||
.struct_init_dot_two_comma,
|
||||
.struct_init_one,
|
||||
.struct_init_one_comma,
|
||||
=> |n| {
|
||||
var buf: [2]ast.Node.Index = undefined;
|
||||
const struct_init: ast.full.StructInit = switch (n) {
|
||||
.struct_init, .struct_init_comma => tree.structInit(node),
|
||||
.struct_init_dot, .struct_init_dot_comma => tree.structInitDot(node),
|
||||
.struct_init_one, .struct_init_one_comma => tree.structInitOne(&buf[0..1], node),
|
||||
.struct_init_dot_two, .struct_init_dot_two_comma => tree.structInitDotTwo(&buf, node),
|
||||
else => unreachable,
|
||||
};
|
||||
if (struct_init.ast.type_expr != 0)
|
||||
try symbolReferencesInternal(arena, store, .{ .node = struct_init.ast.type_expr, .handle = handle }, decl, encoding, context, handler);
|
||||
for (struct_init.ast.fields) |field|
|
||||
try symbolReferencesInternal(arena, store, .{ .node = field, .handle = handle }, decl, encoding, context, handler);
|
||||
},
|
||||
.call,
|
||||
.call_comma,
|
||||
.call_one,
|
||||
.call_one_comma,
|
||||
.async_call,
|
||||
.async_call_comma,
|
||||
.async_call_one,
|
||||
.async_call_one_comma,
|
||||
=> |c| {
|
||||
var buf: [1]ast.Node.Index = undefined;
|
||||
const call: ast.full.Call = switch (c) {
|
||||
.call, .call_comma, .async_call, .async_call_comma => tree.callFull(node),
|
||||
.call_one, .call_one_comma, .async_call_one, .async_call_one_comma => tree.callOne(&buf, node),
|
||||
else => unreachable,
|
||||
};
|
||||
if (call.ast.fn_expr != 0)
|
||||
try symbolReferencesInternal(arena, store, .{ .node = call.ast.fn_expr, .handle = handle }, decl, encoding, context, handler);
|
||||
|
||||
for (call.ast.params) |param| {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = param, .handle = handle }, decl, encoding, context, handler);
|
||||
}
|
||||
},
|
||||
.ArrayType => {
|
||||
const info = node.castTag(.ArrayType).?;
|
||||
try symbolReferencesInternal(arena, store, .{ .node = info.len_expr, .handle = handle }, decl, encoding, context, handler);
|
||||
try symbolReferencesInternal(arena, store, .{ .node = info.rhs, .handle = handle }, decl, encoding, context, handler);
|
||||
},
|
||||
.ArrayTypeSentinel => {
|
||||
const info = node.castTag(.ArrayTypeSentinel).?;
|
||||
try symbolReferencesInternal(arena, store, .{ .node = info.len_expr, .handle = handle }, decl, encoding, context, handler);
|
||||
try symbolReferencesInternal(arena, store, .{ .node = info.sentinel, .handle = handle }, decl, encoding, context, handler);
|
||||
try symbolReferencesInternal(arena, store, .{ .node = info.rhs, .handle = handle }, decl, encoding, context, handler);
|
||||
},
|
||||
.PtrType, .SliceType => {
|
||||
const info = switch (node.tag) {
|
||||
.PtrType => node.castTag(.PtrType).?.ptr_info,
|
||||
.SliceType => node.castTag(.SliceType).?.ptr_info,
|
||||
.slice, .slice_sentinel, .slice_open => |s| {
|
||||
const slice: ast.full.Slice = switch (s) {
|
||||
.slice => tree.slice(node),
|
||||
.slice_open => tree.sliceOpen(node),
|
||||
.slice_sentinel => tree.sliceSentinel(node),
|
||||
else => unreachable,
|
||||
};
|
||||
|
||||
if (info.align_info) |align_info| {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = align_info.node, .handle = handle }, decl, encoding, context, handler);
|
||||
if (align_info.bit_range) |range| {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = range.start, .handle = handle }, decl, encoding, context, handler);
|
||||
try symbolReferencesInternal(arena, store, .{ .node = range.end, .handle = handle }, decl, encoding, context, handler);
|
||||
}
|
||||
}
|
||||
if (info.sentinel) |sentinel| {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = sentinel, .handle = handle }, decl, encoding, context, handler);
|
||||
}
|
||||
switch (node.tag) {
|
||||
.PtrType => try symbolReferencesInternal(arena, store, .{ .node = node.castTag(.PtrType).?.rhs, .handle = handle }, decl, encoding, context, handler),
|
||||
.SliceType => try symbolReferencesInternal(arena, store, .{ .node = node.castTag(.SliceType).?.rhs, .handle = handle }, decl, encoding, context, handler),
|
||||
else => unreachable,
|
||||
try symbolReferencesInternal(arena, store, .{ .node = slice.ast.sliced, .handle = handle }, decl, encoding, context, handler);
|
||||
try symbolReferencesInternal(arena, store, .{ .node = slice.ast.start, .handle = handle }, decl, encoding, context, handler);
|
||||
if (slice.ast.end != 0)
|
||||
try symbolReferencesInternal(arena, store, .{ .node = slice.ast.end, .handle = handle }, decl, encoding, context, handler);
|
||||
if (slice.ast.sentinel != 0)
|
||||
try symbolReferencesInternal(arena, store, .{ .node = slice.ast.sentinel, .handle = handle }, decl, encoding, context, handler);
|
||||
},
|
||||
.array_access => {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = datas[node].lhs, .handle = handle }, decl, encoding, context, handler);
|
||||
try symbolReferencesInternal(arena, store, .{ .node = datas[node].rhs, .handle = handle }, decl, encoding, context, handler);
|
||||
},
|
||||
.deref, .unwrap_optional => {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = datas[node].lhs, .handle = handle }, decl, encoding, context, handler);
|
||||
},
|
||||
.grouped_expression => {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = datas[node].lhs, .handle = handle }, decl, encoding, context, handler);
|
||||
},
|
||||
.@"return", .@"break", .@"continue" => {
|
||||
if (datas[node].lhs != 0) {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = datas[node].lhs, .handle = handle }, decl, encoding, context, handler);
|
||||
}
|
||||
},
|
||||
.AddressOf, .Await, .BitNot, .BoolNot, .OptionalType, .Negation, .NegationWrap, .Resume, .Try => {
|
||||
const prefix_op = node.cast(ast.Node.SimplePrefixOp).?;
|
||||
try symbolReferencesInternal(arena, store, .{ .node = prefix_op.rhs, .handle = handle }, decl, encoding, context, handler);
|
||||
},
|
||||
.FieldInitializer => {
|
||||
// TODO Rename field initializer names when needed
|
||||
const field_init = node.cast(ast.Node.FieldInitializer).?;
|
||||
try symbolReferencesInternal(arena, store, .{ .node = field_init.expr, .handle = handle }, decl, encoding, context, handler);
|
||||
},
|
||||
.ArrayInitializer => {
|
||||
const array_init = node.cast(ast.Node.ArrayInitializer).?;
|
||||
try symbolReferencesInternal(arena, store, .{ .node = array_init.lhs, .handle = handle }, decl, encoding, context, handler);
|
||||
for (array_init.listConst()) |child| {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = child, .handle = handle }, decl, encoding, context, handler);
|
||||
.@"suspend" => {
|
||||
if (datas[node].lhs != 0) {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = datas[node].lhs, .handle = handle }, decl, encoding, context, handler);
|
||||
}
|
||||
},
|
||||
.ArrayInitializerDot => {
|
||||
const array_init = node.cast(ast.Node.ArrayInitializerDot).?;
|
||||
for (array_init.listConst()) |child| {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = child, .handle = handle }, decl, encoding, context, handler);
|
||||
}
|
||||
},
|
||||
.StructInitializer => {
|
||||
// TODO Rename field initializer names when needed
|
||||
const struct_init = node.cast(ast.Node.StructInitializer).?;
|
||||
try symbolReferencesInternal(arena, store, .{ .node = struct_init.lhs, .handle = handle }, decl, encoding, context, handler);
|
||||
for (struct_init.listConst()) |child| {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = child, .handle = handle }, decl, encoding, context, handler);
|
||||
}
|
||||
},
|
||||
.StructInitializerDot => {
|
||||
const struct_init = node.cast(ast.Node.StructInitializerDot).?;
|
||||
for (struct_init.listConst()) |child| {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = child, .handle = handle }, decl, encoding, context, handler);
|
||||
}
|
||||
},
|
||||
.Call => {
|
||||
const call = node.cast(ast.Node.Call).?;
|
||||
try symbolReferencesInternal(arena, store, .{ .node = call.lhs, .handle = handle }, decl, encoding, context, handler);
|
||||
for (call.paramsConst()) |param| {
|
||||
.builtin_call,
|
||||
.builtin_call_comma,
|
||||
.builtin_call_two,
|
||||
.builtin_call_two_comma,
|
||||
=> {
|
||||
const builtin_call = analysis.builtinCallParams();
|
||||
for (analysis.builtinCallParams()) |param|
|
||||
try symbolReferencesInternal(arena, store, .{ .node = param, .handle = handle }, decl, encoding, context, handler);
|
||||
}
|
||||
},
|
||||
.Slice => {
|
||||
const slice = node.castTag(.Slice).?;
|
||||
try symbolReferencesInternal(arena, store, .{ .node = slice.lhs, .handle = handle }, decl, encoding, context, handler);
|
||||
try symbolReferencesInternal(arena, store, .{ .node = slice.start, .handle = handle }, decl, encoding, context, handler);
|
||||
if (slice.end) |end| {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = end, .handle = handle }, decl, encoding, context, handler);
|
||||
}
|
||||
if (slice.sentinel) |sentinel| {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = sentinel, .handle = handle }, decl, encoding, context, handler);
|
||||
}
|
||||
},
|
||||
.ArrayAccess => {
|
||||
const arr_acc = node.castTag(.ArrayAccess).?;
|
||||
try symbolReferencesInternal(arena, store, .{ .node = arr_acc.lhs, .handle = handle }, decl, encoding, context, handler);
|
||||
try symbolReferencesInternal(arena, store, .{ .node = arr_acc.index_expr, .handle = handle }, decl, encoding, context, handler);
|
||||
},
|
||||
.Deref, .UnwrapOptional => {
|
||||
const suffix = node.cast(ast.Node.SimpleSuffixOp).?;
|
||||
try symbolReferencesInternal(arena, store, .{ .node = suffix.lhs, .handle = handle }, decl, encoding, context, handler);
|
||||
},
|
||||
.GroupedExpression => {
|
||||
const grouped = node.cast(ast.Node.GroupedExpression).?;
|
||||
try symbolReferencesInternal(arena, store, .{ .node = grouped.expr, .handle = handle }, decl, encoding, context, handler);
|
||||
},
|
||||
.Return, .Break, .Continue => {
|
||||
const cfe = node.cast(ast.Node.ControlFlowExpression).?;
|
||||
if (cfe.getRHS()) |rhs| {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = rhs, .handle = handle }, decl, encoding, context, handler);
|
||||
}
|
||||
},
|
||||
.Suspend => {
|
||||
const suspend_node = node.cast(ast.Node.Suspend).?;
|
||||
if (suspend_node.body) |body| {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = body, .handle = handle }, decl, encoding, context, handler);
|
||||
}
|
||||
},
|
||||
.BuiltinCall => {
|
||||
const builtin_call = node.cast(ast.Node.BuiltinCall).?;
|
||||
for (builtin_call.paramsConst()) |param| {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = param, .handle = handle }, decl, encoding, context, handler);
|
||||
}
|
||||
},
|
||||
// TODO Inline asm expr
|
||||
.TestDecl => {
|
||||
const test_decl = node.cast(ast.Node.TestDecl).?;
|
||||
try symbolReferencesInternal(arena, store, .{ .node = test_decl.body_node, .handle = handle }, decl, encoding, context, handler);
|
||||
},
|
||||
.Period => {
|
||||
const infix_op = node.cast(ast.Node.SimpleInfixOp).?;
|
||||
.@"asm", .asm_simple => |a| {
|
||||
const _asm: ast.full.Asm = if (a == .@"asm") tree.asmFull(node) else tree.asmSimple(node);
|
||||
if (_asm.ast.items.len == 0)
|
||||
try symbolReferencesInternal(arena, store, .{ .node = _asm.ast.template, .handle = handle }, decl, encoding, context, handler);
|
||||
|
||||
try symbolReferencesInternal(arena, store, .{ .node = infix_op.lhs, .handle = handle }, decl, encoding, context, handler);
|
||||
for (_asm.inputs) |input|
|
||||
try symbolReferencesInternal(arena, store, .{ .node = input, .handle = handle }, decl, encoding, context, handler);
|
||||
|
||||
const rhs_str = analysis.nodeToString(handle.tree, infix_op.rhs) orelse return;
|
||||
for (_asm.outputs) |output|
|
||||
try symbolReferencesInternal(arena, store, .{ .node = output, .handle = handle }, decl, encoding, context, handler);
|
||||
},
|
||||
.test_decl => {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = datas[node].rhs, .handle = handle }, decl, encoding, context, handler);
|
||||
},
|
||||
.field_access => {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = datas[node].lhs, .handle = handle }, decl, encoding, context, handler);
|
||||
|
||||
const rhs_str = analysis.nodeToString(handle.tree, datas[node].rhs) orelse return;
|
||||
var bound_type_params = analysis.BoundTypeParams.init(&arena.allocator);
|
||||
const left_type = try analysis.resolveFieldAccessLhsType(
|
||||
store,
|
||||
arena,
|
||||
(try analysis.resolveTypeOfNodeInternal(store, arena, .{
|
||||
.node = infix_op.lhs,
|
||||
.node = datas[node].lhs,
|
||||
.handle = handle,
|
||||
}, &bound_type_params)) orelse return,
|
||||
&bound_type_params,
|
||||
@ -352,15 +415,53 @@ fn symbolReferencesInternal(
|
||||
!left_type.type.is_type_val,
|
||||
)) |child| {
|
||||
if (std.meta.eql(child, decl)) {
|
||||
try tokenReference(handle, infix_op.rhs.firstToken(), encoding, context, handler);
|
||||
try tokenReference(handle, tree.firstToken(datas[node].rhs), encoding, context, handler);
|
||||
}
|
||||
}
|
||||
},
|
||||
.Add, .AddWrap, .ArrayCat, .ArrayMult, .Assign, .AssignBitAnd, .AssignBitOr, .AssignBitShiftLeft, .AssignBitShiftRight, .AssignBitXor, .AssignDiv, .AssignSub, .AssignSubWrap, .AssignMod, .AssignAdd, .AssignAddWrap, .AssignMul, .AssignMulWrap, .BangEqual, .BitAnd, .BitOr, .BitShiftLeft, .BitShiftRight, .BitXor, .BoolOr, .Div, .EqualEqual, .ErrorUnion, .GreaterOrEqual, .GreaterThan, .LessOrEqual, .LessThan, .MergeErrorSets, .Mod, .Mul, .MulWrap, .Range, .Sub, .SubWrap, .OrElse => {
|
||||
const infix_op = node.cast(ast.Node.SimpleInfixOp).?;
|
||||
|
||||
try symbolReferencesInternal(arena, store, .{ .node = infix_op.lhs, .handle = handle }, decl, encoding, context, handler);
|
||||
try symbolReferencesInternal(arena, store, .{ .node = infix_op.rhs, .handle = handle }, decl, encoding, context, handler);
|
||||
.add,
|
||||
.add_wrap,
|
||||
.array_cat,
|
||||
.array_mult,
|
||||
.assign,
|
||||
.assign_bit_and,
|
||||
.assign_bit_or,
|
||||
.assign_bit_shift_left,
|
||||
.assign_bit_shift_right,
|
||||
.assign_bit_xor,
|
||||
.assign_div,
|
||||
.assign_sub,
|
||||
.assign_sub_wrap,
|
||||
.assign_mod,
|
||||
.assign_add,
|
||||
.assign_add_wrap,
|
||||
.assign_mul,
|
||||
.assign_mul_wrap,
|
||||
.bang_equal,
|
||||
.bit_and,
|
||||
.bit_or,
|
||||
.bit_shift_left,
|
||||
.bit_shift_right,
|
||||
.bit_xor,
|
||||
.bool_or,
|
||||
.div,
|
||||
.equal_equal,
|
||||
.error_union,
|
||||
.greater_or_equal,
|
||||
.greater_than,
|
||||
.less_or_equal,
|
||||
.less_than,
|
||||
.merge_error_sets,
|
||||
.mod,
|
||||
.mul,
|
||||
.mul_wrap,
|
||||
.range,
|
||||
.sub,
|
||||
.sub_wrap,
|
||||
.@"orelse",
|
||||
=> {
|
||||
try symbolReferencesInternal(arena, store, .{ .node = datas[node].lhs, .handle = handle }, decl, encoding, context, handler);
|
||||
try symbolReferencesInternal(arena, store, .{ .node = datas[node].rhs, .handle = handle }, decl, encoding, context, handler);
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user