Basic variable type resolution on hover

This commit is contained in:
Auguste Rame 2022-07-08 20:29:53 +02:00 committed by Auguste Rame
parent 0f3eb1df36
commit 0c0cb261b7
2 changed files with 41 additions and 9 deletions

View File

@ -494,7 +494,7 @@ fn resolveUnwrapErrorType(store: *DocumentStore, arena: *std.heap.ArenaAllocator
.type = .{ .data = .{ .other = n }, .is_type_val = rhs.type.is_type_val }, .type = .{ .data = .{ .other = n }, .is_type_val = rhs.type.is_type_val },
.handle = rhs.handle, .handle = rhs.handle,
}, },
.primitive, .slice, .pointer => return null, .primitive, .slice, .pointer, .array_index => return null,
}; };
if (rhs.handle.tree.nodes.items(.tag)[rhs_node] == .error_union) { if (rhs.handle.tree.nodes.items(.tag)[rhs_node] == .error_union) {
@ -670,7 +670,7 @@ pub fn resolveTypeOfNodeInternal(store: *DocumentStore, arena: *std.heap.ArenaAl
.identifier => { .identifier => {
if (isTypeIdent(handle.tree, main_tokens[node])) { if (isTypeIdent(handle.tree, main_tokens[node])) {
return TypeWithHandle{ return TypeWithHandle{
.type = .{ .data = .primitive, .is_type_val = true }, .type = .{ .data = .{ .primitive = node }, .is_type_val = true },
.handle = handle, .handle = handle,
}; };
} }
@ -977,7 +977,8 @@ pub const Type = struct {
slice: Ast.Node.Index, slice: Ast.Node.Index,
error_union: Ast.Node.Index, error_union: Ast.Node.Index,
other: Ast.Node.Index, other: Ast.Node.Index,
primitive, primitive: Ast.Node.Index,
array_index,
}, },
/// If true, the type `type`, the attached data is the value of the type value. /// If true, the type `type`, the attached data is the value of the type value.
is_type_val: bool, is_type_val: bool,
@ -1941,7 +1942,7 @@ pub const DeclWithHandle = struct {
bound_type_params, bound_type_params,
), ),
.array_index => TypeWithHandle{ .array_index => TypeWithHandle{
.type = .{ .data = .primitive, .is_type_val = false }, .type = .{ .data = .array_index, .is_type_val = false },
.handle = self.handle, .handle = self.handle,
}, },
.label_decl => return null, .label_decl => return null,

View File

@ -404,7 +404,7 @@ fn typeToCompletion(
null, null,
config, config,
), ),
.primitive => {}, .primitive, .array_index => {},
} }
} }
@ -736,19 +736,50 @@ fn hoverSymbol(id: types.RequestId, arena: *std.heap.ArenaAllocator, decl_handle
.label_decl => |label_decl| tree.tokenSlice(label_decl), .label_decl => |label_decl| tree.tokenSlice(label_decl),
}; };
var bound_type_params = analysis.BoundTypeParams.init(arena.allocator());
const resolved_type = try decl_handle.resolveType(&document_store, arena, &bound_type_params);
const resolved_type_str = if (resolved_type) |rt|
if (rt.type.is_type_val) "type" else switch (rt.type.data) {
.pointer,
.slice,
.error_union,
.primitive,
=> |p| tree.getNodeSource(p),
.other => |p| switch (tree.nodes.items(.tag)[p]) {
.container_decl,
.container_decl_arg,
.container_decl_arg_trailing,
.container_decl_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,
=> tree.tokenSlice(tree.nodes.items(.main_token)[p] - 2), // NOTE: This is a hacky nightmare but it works :P
else => tree.getNodeSource(p),
},
else => "unknown",
}
else
"unknown";
var hover_text: []const u8 = undefined; var hover_text: []const u8 = undefined;
if (hover_kind == .Markdown) { if (hover_kind == .Markdown) {
hover_text = hover_text =
if (doc_str) |doc| if (doc_str) |doc|
try std.fmt.allocPrint(arena.allocator(), "```zig\n{s}\n```\n{s}", .{ def_str, doc }) try std.fmt.allocPrint(arena.allocator(), "```zig\n{s}\n```\n```zig\n({s})\n```\n{s}", .{ def_str, resolved_type_str, doc })
else else
try std.fmt.allocPrint(arena.allocator(), "```zig\n{s}\n```", .{def_str}); try std.fmt.allocPrint(arena.allocator(), "```zig\n{s}\n```\n```zig\n({s})\n```", .{ def_str, resolved_type_str });
} else { } else {
hover_text = hover_text =
if (doc_str) |doc| if (doc_str) |doc|
try std.fmt.allocPrint(arena.allocator(), "{s}\n{s}", .{ def_str, doc }) try std.fmt.allocPrint(arena.allocator(), "{s} ({s})\n{s}", .{ def_str, resolved_type_str, doc })
else else
def_str; try std.fmt.allocPrint(arena.allocator(), "{s} ({s})", .{ def_str, resolved_type_str });
} }
try send(arena, types.Response{ try send(arena, types.Response{