Skip to content

Commit f2ea2db

Browse files
Add completions for enum literal of union tag
1 parent a0a7170 commit f2ea2db

2 files changed

Lines changed: 38 additions & 5 deletions

File tree

src/features/completions.zig

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1500,8 +1500,13 @@ fn collectContainerFields(
15001500
container: Analyser.Type,
15011501
omit_members: std.BufSet,
15021502
) Analyser.Error!void {
1503-
const info = switch (container.data) {
1504-
.container => |info| info,
1503+
const info, const type_maybe = switch (container.data) {
1504+
.container => |info| .{ info, null },
1505+
.union_tag => |union_ty| blk: {
1506+
const info = union_ty.data.container;
1507+
const ty = try container.instanceTypeVal(builder.analyser) orelse container;
1508+
break :blk .{ info, ty };
1509+
},
15051510
else => return,
15061511
};
15071512

@@ -1513,7 +1518,7 @@ fn collectContainerFields(
15131518
const decl = document_scope.declarations.get(@intFromEnum(decl_index));
15141519
if (decl != .ast_node) continue;
15151520
const decl_handle: Analyser.DeclWithHandle = .{ .decl = decl, .handle = scope_handle.handle, .container_type = container };
1516-
const maybe_resolved_ty = try decl_handle.resolveType(builder.analyser);
1521+
const maybe_resolved_ty = type_maybe orelse try decl_handle.resolveType(builder.analyser);
15171522
const tree = &scope_handle.handle.tree;
15181523

15191524
const name = offsets.tokenToSlice(tree, decl.nameToken(tree));
@@ -1526,8 +1531,10 @@ fn collectContainerFields(
15261531
=> {
15271532
const field = tree.fullContainerField(decl.ast_node).?;
15281533

1529-
const kind: types.completion.Item.Kind =
1530-
if (field.ast.tuple_like) .EnumMember else .Field;
1534+
const kind: types.completion.Item.Kind = switch (container.data) {
1535+
.union_tag => .EnumMember,
1536+
else => if (field.ast.tuple_like) .EnumMember else .Field,
1537+
};
15311538

15321539
const insert_text, const insert_text_format: types.InsertTextFormat = insert_text: {
15331540
if (likely != .struct_field and likely != .enum_comparison and likely != .switch_case and kind == .Field) {

tests/lsp_features/completion.zig

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1761,6 +1761,32 @@ test "tagged union" {
17611761
});
17621762
}
17631763

1764+
test "tagged union - tag" {
1765+
try testCompletion(
1766+
\\const std = @import("std");
1767+
\\const Ue = union(enum) {
1768+
\\ alpha,
1769+
\\ beta: []const u8,
1770+
\\};
1771+
\\const foo: std.meta.Tag(Ue) = .<cursor>
1772+
, &.{
1773+
.{ .label = "alpha", .kind = .EnumMember, .detail = "@typeInfo(Ue).@\"union\".tag_type.?" },
1774+
.{ .label = "beta", .kind = .EnumMember, .detail = "@typeInfo(Ue).@\"union\".tag_type.?" },
1775+
});
1776+
try testCompletion(
1777+
\\const std = @import("std");
1778+
\\const Ue = union(enum) {
1779+
\\ alpha,
1780+
\\ beta: []const u8,
1781+
\\};
1782+
\\const S = struct { foo: std.meta.Tag(Ue) };
1783+
\\const s = S{ .foo = .<cursor> };
1784+
, &.{
1785+
.{ .label = "alpha", .kind = .EnumMember, .detail = "@typeInfo(Ue).@\"union\".tag_type.?" },
1786+
.{ .label = "beta", .kind = .EnumMember, .detail = "@typeInfo(Ue).@\"union\".tag_type.?" },
1787+
});
1788+
}
1789+
17641790
test "switch cases" {
17651791
// Because current logic is to list all enums if all else fails,
17661792
// the following tests include an extra enum to ensure that we're not just 'getting lucky'

0 commit comments

Comments
 (0)