Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show doc comments for errors in error sets #1302

Merged
merged 1 commit into from
Jul 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions src/analysis.zig
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,16 @@ pub fn invalidate(self: *Analyser) void {
_ = self.arena.reset(.free_all);
}

pub fn getDocCommentsBeforeToken(allocator: std.mem.Allocator, tree: Ast, base: Ast.TokenIndex) !?[]const u8 {
const tokens = tree.tokens.items(.tag);
const doc_comment_index = getDocCommentTokenIndex(tokens, base) orelse return null;
return try collectDocComments(allocator, tree, doc_comment_index, false);
}

/// Gets a declaration's doc comments. Caller owns returned memory.
pub fn getDocComments(allocator: std.mem.Allocator, tree: Ast, node: Ast.Node.Index) !?[]const u8 {
const base = tree.nodes.items(.main_token)[node];
const base_kind = tree.nodes.items(.tag)[node];
const tokens = tree.tokens.items(.tag);

switch (base_kind) {
// As far as I know, this does not actually happen yet, but it
Expand All @@ -67,10 +72,7 @@ pub fn getDocComments(allocator: std.mem.Allocator, tree: Ast, node: Ast.Node.In
.container_field_init,
.container_field_align,
.container_field,
=> {
if (getDocCommentTokenIndex(tokens, base)) |doc_comment_index|
return try collectDocComments(allocator, tree, doc_comment_index, false);
},
=> return try getDocCommentsBeforeToken(allocator, tree, base),
else => {},
}
return null;
Expand Down Expand Up @@ -2044,7 +2046,7 @@ pub const Declaration = union(enum) {
block: Ast.Node.Index,
},
/// always an identifier
error_token: Ast.Node.Index,
error_token: Ast.TokenIndex,

pub const Index = enum(u32) { _ };

Expand Down
78 changes: 46 additions & 32 deletions src/features/completions.zig
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,32 @@ fn typeToCompletion(
}
}

fn completionDoc(
server: *Server,
either_descriptor: ?[]const u8,
doc_comments: ?[]const u8,
) error{OutOfMemory}!@TypeOf(@as(types.CompletionItem, undefined).documentation) {
var list = std.ArrayList(u8).init(server.arena.allocator());
const writer = list.writer();

if (either_descriptor) |ed|
try writer.print("`Conditionally available: {s}`", .{ed});

if (doc_comments) |dc| {
if (either_descriptor != null)
try writer.writeAll("\n\n");
try writer.writeAll(dc);
}

if (list.items.len == 0)
return null;

return .{ .MarkupContent = types.MarkupContent{
.kind = if (server.client_capabilities.completion_doc_supports_md) .markdown else .plaintext,
.value = list.items,
} };
}

fn nodeToCompletion(
server: *Server,
list: *std.ArrayListUnmanaged(types.CompletionItem),
Expand All @@ -107,27 +133,11 @@ fn nodeToCompletion(
const datas = tree.nodes.items(.data);
const token_tags = tree.tokens.items(.tag);

const doc_kind: types.MarkupKind = if (server.client_capabilities.completion_doc_supports_md)
.markdown
else
.plaintext;

const Documentation = @TypeOf(@as(types.CompletionItem, undefined).documentation);

const doc: Documentation = if (try Analyser.getDocComments(
allocator,
handle.tree,
node,
)) |doc_comments| .{ .MarkupContent = types.MarkupContent{
.kind = doc_kind,
.value = if (either_descriptor) |ed|
try std.fmt.allocPrint(allocator, "`Conditionally available: {s}`\n\n{s}", .{ ed, doc_comments })
else
doc_comments,
} } else (if (either_descriptor) |ed| .{ .MarkupContent = types.MarkupContent{
.kind = doc_kind,
.value = try std.fmt.allocPrint(allocator, "`Conditionally available: {s}`", .{ed}),
} } else null);
const doc = try completionDoc(
server,
either_descriptor,
try Analyser.getDocComments(allocator, handle.tree, node),
);

if (ast.isContainer(handle.tree, node)) {
const context = DeclToCompletionContext{
Expand Down Expand Up @@ -358,17 +368,15 @@ fn declToCompletion(context: DeclToCompletionContext, decl_handle: Analyser.Decl
context.either_descriptor,
),
.param_payload => |pay| {
const Documentation = @TypeOf(@as(types.CompletionItem, undefined).documentation);

const param = pay.param;
const doc_kind: types.MarkupKind = if (context.server.client_capabilities.completion_doc_supports_md) .markdown else .plaintext;
const doc: Documentation = if (param.first_doc_comment) |doc_comments| .{ .MarkupContent = types.MarkupContent{
.kind = doc_kind,
.value = if (context.either_descriptor) |ed|
try std.fmt.allocPrint(allocator, "`Conditionally available: {s}`\n\n{s}", .{ ed, try Analyser.collectDocComments(allocator, tree, doc_comments, false) })
const doc = try completionDoc(
context.server,
context.either_descriptor,
if (param.first_doc_comment) |doc_comments|
try Analyser.collectDocComments(allocator, tree, doc_comments, false)
else
try Analyser.collectDocComments(allocator, tree, doc_comments, false),
} } else null;
null,
);

try context.completions.append(allocator, .{
.label = tree.tokenSlice(param.name_token.?),
Expand All @@ -395,12 +403,18 @@ fn declToCompletion(context: DeclToCompletionContext, decl_handle: Analyser.Decl
.insertTextFormat = .PlainText,
});
},
.error_token => {
const name = tree.tokenSlice(decl_handle.decl.error_token);
.error_token => |token| {
const name = tree.tokenSlice(token);
const doc = try completionDoc(
context.server,
context.either_descriptor,
try Analyser.getDocCommentsBeforeToken(allocator, tree, token),
);

try context.completions.append(allocator, .{
.label = name,
.kind = .Constant,
.documentation = doc,
.detail = try std.fmt.allocPrint(allocator, "error.{s}", .{name}),
.insertText = name,
.insertTextFormat = .PlainText,
Expand Down
5 changes: 4 additions & 1 deletion src/features/hover.zig
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,16 @@ pub fn hoverSymbol(server: *Server, decl_handle: Analyser.DeclWithHandle, markup

break :def ast.paramSlice(tree, param);
},
.error_token => |token| def: {
doc_str = try Analyser.getDocCommentsBeforeToken(server.arena.allocator(), tree, token);
break :def tree.tokenSlice(decl_handle.nameToken());
},
.pointer_payload,
.error_union_payload,
.array_payload,
.array_index,
.switch_payload,
.label_decl,
.error_token,
=> tree.tokenSlice(decl_handle.nameToken()),
};

Expand Down