Skip to content

Commit

Permalink
fix document symbols on tuple container field and builtins (#1584)
Browse files Browse the repository at this point in the history
  • Loading branch information
Techatrix authored Nov 5, 2023
1 parent cd520e5 commit bda08cc
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 14 deletions.
17 changes: 10 additions & 7 deletions src/analysis.zig
Original file line number Diff line number Diff line change
Expand Up @@ -419,15 +419,18 @@ pub fn getDeclName(tree: Ast, node: Ast.Node.Index) ?[]const u8 {

pub fn getContainerDeclName(tree: Ast, container: ?Ast.Node.Index, node: Ast.Node.Index) ?[]const u8 {
const name_token = getContainerDeclNameToken(tree, container, node) orelse return null;
return declNameTokenToSlice(tree, name_token);
}

if (tree.nodes.items(.tag)[node] == .test_decl and
tree.tokens.items(.tag)[name_token] == .string_literal)
{
const name = offsets.tokenToSlice(tree, name_token);
return name[1 .. name.len - 1];
pub fn declNameTokenToSlice(tree: Ast, name_token: Ast.TokenIndex) ?[]const u8 {
switch (tree.tokens.items(.tag)[name_token]) {
.string_literal => {
const name = offsets.tokenToSlice(tree, name_token);
return name[1 .. name.len - 1];
},
.identifier => return offsets.identifierTokenToNameSlice(tree, name_token),
else => return null,
}

return offsets.identifierTokenToNameSlice(tree, name_token);
}

/// Resolves variable declarations consisting of chains of imports and field accesses of containers
Expand Down
30 changes: 24 additions & 6 deletions src/features/document_symbol.zig
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const Symbol = struct {
const Context = struct {
arena: std.mem.Allocator,
last_var_decl_name: ?[]const u8,
parent_container: Ast.Node.Index,
parent_node: Ast.Node.Index,
parent_symbols: *std.ArrayListUnmanaged(Symbol),
total_symbol_count: *usize,
Expand All @@ -32,8 +33,8 @@ fn callback(ctx: *Context, tree: Ast, node: Ast.Node.Index) error{OutOfMemory}!v
const main_tokens = tree.nodes.items(.main_token);
const token_tags = tree.tokens.items(.tag);

const decl_name_token = analysis.getDeclNameToken(tree, node);
const decl_name = analysis.getDeclName(tree, node);
const decl_name_token = analysis.getContainerDeclNameToken(tree, ctx.parent_container, node);
const decl_name = if (decl_name_token) |name_token| analysis.declNameTokenToSlice(tree, name_token) else null;

var new_ctx = ctx.*;
const maybe_symbol: ?Symbol = switch (node_tags[node]) {
Expand All @@ -52,7 +53,7 @@ fn callback(ctx: *Context, tree: Ast, node: Ast.Node.Index) error{OutOfMemory}!v
};

break :blk .{
.name = decl_name.?,
.name = decl_name orelse break :blk null,
.detail = null,
.kind = kind,
.loc = offsets.nodeToLoc(tree, node),
Expand Down Expand Up @@ -87,15 +88,15 @@ fn callback(ctx: *Context, tree: Ast, node: Ast.Node.Index) error{OutOfMemory}!v
.container_field_align,
.container_field,
=> blk: {
const kind: types.SymbolKind = switch (node_tags[ctx.parent_node]) {
const kind: types.SymbolKind = switch (node_tags[ctx.parent_container]) {
.root => .Field,
.container_decl,
.container_decl_trailing,
.container_decl_arg,
.container_decl_arg_trailing,
.container_decl_two,
.container_decl_two_trailing,
=> switch (token_tags[main_tokens[ctx.parent_node]]) {
=> switch (token_tags[main_tokens[ctx.parent_container]]) {
.keyword_struct => .Field,
.keyword_union => .Field,
.keyword_enum => .EnumMember,
Expand All @@ -113,14 +114,30 @@ fn callback(ctx: *Context, tree: Ast, node: Ast.Node.Index) error{OutOfMemory}!v
};

break :blk .{
.name = decl_name.?,
.name = decl_name orelse break :blk null,
.detail = ctx.last_var_decl_name,
.kind = kind,
.loc = offsets.nodeToLoc(tree, node),
.selection_loc = offsets.tokenToLoc(tree, decl_name_token.?),
.children = .{},
};
},
.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_enum_tag,
.tagged_union_enum_tag_trailing,
.tagged_union_two,
.tagged_union_two_trailing,
=> blk: {
new_ctx.parent_container = node;
break :blk null;
},
else => null,
};

Expand Down Expand Up @@ -230,6 +247,7 @@ pub fn getDocumentSymbols(
.arena = arena,
.last_var_decl_name = null,
.parent_node = 0, // root-node
.parent_container = 0, // root-node
.parent_symbols = &root_symbols,
.total_symbol_count = &total_symbol_count,
};
Expand Down
24 changes: 23 additions & 1 deletion tests/lsp_features/document_symbol.zig
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ test "documentSymbol - container decl" {
\\ Field alpha
\\ Function f
);
try testDocumentSymbol(
\\const S = struct {
\\ []const u8,
\\ u32,
\\};
,
\\Constant S
);
}

test "documentSymbol - enum" {
Expand All @@ -53,6 +61,20 @@ test "documentSymbol - test decl" {
);
}

// https://github.com/zigtools/zls/issues/1583
test "documentSymbol - builtin" {
try testDocumentSymbol(
\\comptime {
\\ @abs();
\\ @foo();
\\ @foo
\\}
\\
,
\\
);
}

// https://github.com/zigtools/zls/issues/986
test "documentSymbol - nested struct with self" {
try testDocumentSymbol(
Expand Down Expand Up @@ -105,7 +127,7 @@ fn testDocumentSymbol(source: []const u8, want: []const u8) !void {
_ = stack.pop();
}
}
_ = got.pop(); // Final \n
_ = got.popOrNull(); // Final \n

try std.testing.expectEqualStrings(want, got.items);
}

0 comments on commit bda08cc

Please sign in to comment.