From b7c0867eab958326ed14d8415012401f1b8ba160 Mon Sep 17 00:00:00 2001 From: xdBronch <51252236+xdBronch@users.noreply.github.com> Date: Sat, 7 Jun 2025 18:09:33 -0400 Subject: [PATCH] reference fields in anonymous struct initializers --- src/features/references.zig | 33 +++++++++++++++++++++++++++---- tests/lsp_features/references.zig | 10 ++++++---- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/features/references.zig b/src/features/references.zig index 2f22397931..36da06903b 100644 --- a/src/features/references.zig +++ b/src/features/references.zig @@ -166,16 +166,41 @@ const Builder = struct { const struct_init = tree.fullStructInit(&buffer, node).?; for (struct_init.ast.fields) |value_node| { // the node of `value` in `.name = value` const name_token = tree.firstToken(value_node) - 2; // math our way two token indexes back to get the `name` - const name_loc = offsets.tokenToLoc(tree, name_token); - const name = offsets.locToSlice(tree.source, name_loc); + const name = offsets.identifierTokenToNameSlice(tree, name_token); if (!std.mem.eql(u8, name, decl_name)) continue; - const lookup = try builder.analyser.lookupSymbolFieldInit(handle, name, node, &.{}) orelse continue; + const nodes = switch (tree.nodeTag(node)) { + .struct_init_dot, + .struct_init_dot_comma, + .struct_init_dot_two, + .struct_init_dot_two_comma, + => try ast.nodesOverlappingIndex( + builder.allocator, + tree, + tree.tokenStart(name_token), + ), + // if this isn't an anonymous struct the type can be determined from the `T{}` directly + .struct_init_one, + .struct_init_one_comma, + .struct_init, + .struct_init_comma, + => &.{node}, + else => unreachable, + }; + + const lookup = try builder.analyser.lookupSymbolFieldInit( + handle, + name, + nodes[0], + nodes[1..], + ) orelse return; if (builder.decl_handle.eql(lookup)) { try builder.add(handle, name_token); - return; } + // if we get here then we know that the name of the field matched + // and duplicate fields are invalid so just return early + return; } }, .enum_literal => { diff --git a/tests/lsp_features/references.zig b/tests/lsp_features/references.zig index ba0f38c507..721da1aaa0 100644 --- a/tests/lsp_features/references.zig +++ b/tests/lsp_features/references.zig @@ -145,15 +145,17 @@ test "struct decl access" { test "struct one field init" { try testSymbolReferences( - \\const S = struct {<0>: u32}; - \\const s = S{.<0> = 0 }; + \\const S = struct { <0>: u32 }; + \\const s = S{ .<0> = 0 }; + \\const s2: S = .{ .<0> = 0 }; ); } test "struct multi-field init" { try testSymbolReferences( - \\const S = struct {<0>: u32, a: bool}; - \\const s = S{.<0> = 0, .a = true}; + \\const S = struct { <0>: u32, a: bool }; + \\const s = S{ .<0> = 0, .a = true }; + \\const s2: S = .{ .<0> = 0, .a = true }; ); }