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 },
.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) {
@ -670,7 +670,7 @@ pub fn resolveTypeOfNodeInternal(store: *DocumentStore, arena: *std.heap.ArenaAl
.identifier => {
if (isTypeIdent(handle.tree, main_tokens[node])) {
return TypeWithHandle{
.type = .{ .data = .primitive, .is_type_val = true },
.type = .{ .data = .{ .primitive = node }, .is_type_val = true },
.handle = handle,
};
}
@ -977,7 +977,8 @@ pub const Type = struct {
slice: Ast.Node.Index,
error_union: 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.
is_type_val: bool,
@ -1941,7 +1942,7 @@ pub const DeclWithHandle = struct {
bound_type_params,
),
.array_index => TypeWithHandle{
.type = .{ .data = .primitive, .is_type_val = false },
.type = .{ .data = .array_index, .is_type_val = false },
.handle = self.handle,
},
.label_decl => return null,

View File

@ -404,7 +404,7 @@ fn typeToCompletion(
null,
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),
};
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;
if (hover_kind == .Markdown) {
hover_text =
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
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 {
hover_text =
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
def_str;
try std.fmt.allocPrint(arena.allocator(), "{s} ({s})", .{ def_str, resolved_type_str });
}
try send(arena, types.Response{